@ui-entropy/scanner-core 0.1.2 → 0.2.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.
package/README.md CHANGED
@@ -28,7 +28,13 @@ npm install @ui-entropy/scanner-core
28
28
 
29
29
  **For CLI usage**, install the main package instead:
30
30
  ```bash
31
- npm install -g ui-entropy
31
+ npm install -g @ui-entropy/cli
32
+ ```
33
+
34
+ The CLI includes smart project initialization:
35
+ ```bash
36
+ npx @ui-entropy/cli init # Auto-detects your framework
37
+ npx @ui-entropy/cli scan # Scan with generated config
32
38
  ```
33
39
 
34
40
  ## 🔧 Quick Start
@@ -97,15 +103,7 @@ Find all class/ID usage across source files.
97
103
 
98
104
  Calculate waste metrics and identify unused selectors.
99
105
 
100
- ## 📈 Real-World Results
101
-
102
- | Project | CSS Size | Waste % | Unused Selectors |
103
- |---------|----------|---------|------------------|
104
- | build-and-bloom | 45 KB | 72% | 129 selectors |
105
- | Portfolio Site | 180 KB | 91% | 1,024 selectors |
106
- | React Dashboard | 89 KB | 38% | 412 selectors |
107
-
108
- ## 🔗 Related Packages
106
+ ## Related Packages
109
107
 
110
108
  - **[ui-entropy](https://npmjs.com/package/ui-entropy)** - CLI tool for terminal usage
111
109
  - **UI Entropy Dashboard** _(coming soon)_ - Team analytics and historical tracking
@@ -0,0 +1,36 @@
1
+ /**
2
+ * CSS Waste Analyzer
3
+ *
4
+ * Analyzes unused CSS selectors and calculates waste percentage.
5
+ * This is the primary analyzer for v0.1-v0.2 of UI Entropy.
6
+ */
7
+ import type { Analyzer, AnalyzerContext, AnalyzerResult } from './types.js';
8
+ export interface CSSWasteMetrics {
9
+ totalClasses: number;
10
+ totalIds: number;
11
+ usedClasses: number;
12
+ usedIds: number;
13
+ unusedClasses: string[];
14
+ unusedIds: string[];
15
+ wastePercentage: number;
16
+ totalCssBytes: number;
17
+ wastedBytes: number;
18
+ totalRules: number;
19
+ }
20
+ /**
21
+ * CSS Waste Analyzer
22
+ *
23
+ * Calculates entropy based on unused CSS selectors.
24
+ * Score = wastePercentage (0-100)
25
+ */
26
+ export declare class CSSWasteAnalyzer implements Analyzer {
27
+ name: string;
28
+ weight: number;
29
+ analyze(context: AnalyzerContext): AnalyzerResult;
30
+ private generateRecommendations;
31
+ }
32
+ /**
33
+ * Factory function for creating CSS Waste analyzer
34
+ */
35
+ export declare function cssWasteAnalyzer(): CSSWasteAnalyzer;
36
+ //# sourceMappingURL=css-waste.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-waste.d.ts","sourceRoot":"","sources":["../../src/analyzers/css-waste.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,IAAI,SAAe;IACnB,MAAM,SAAO;IAEb,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc;IAiEjD,OAAO,CAAC,uBAAuB;CAgChC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,CAEnD"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * CSS Waste Analyzer
3
+ *
4
+ * Analyzes unused CSS selectors and calculates waste percentage.
5
+ * This is the primary analyzer for v0.1-v0.2 of UI Entropy.
6
+ */
7
+ /**
8
+ * CSS Waste Analyzer
9
+ *
10
+ * Calculates entropy based on unused CSS selectors.
11
+ * Score = wastePercentage (0-100)
12
+ */
13
+ export class CSSWasteAnalyzer {
14
+ name = 'CSS Waste';
15
+ weight = 0.6; // 60% of overall entropy score
16
+ analyze(context) {
17
+ const { selectors, usage } = context;
18
+ // Find unused selectors
19
+ const unusedClasses = [];
20
+ const unusedIds = [];
21
+ let usedClassCount = 0;
22
+ let usedIdCount = 0;
23
+ // Check which classes are unused
24
+ for (const className of selectors.classes) {
25
+ if (usage.classes.has(className)) {
26
+ usedClassCount++;
27
+ }
28
+ else {
29
+ unusedClasses.push(className);
30
+ }
31
+ }
32
+ // Check which IDs are unused
33
+ for (const idName of selectors.ids) {
34
+ if (usage.ids.has(idName)) {
35
+ usedIdCount++;
36
+ }
37
+ else {
38
+ unusedIds.push(idName);
39
+ }
40
+ }
41
+ // Calculate waste percentage
42
+ const totalSelectors = selectors.classes.size + selectors.ids.size;
43
+ const usedSelectors = usedClassCount + usedIdCount;
44
+ const unusedSelectors = totalSelectors - usedSelectors;
45
+ const wastePercentage = totalSelectors > 0
46
+ ? Math.round((unusedSelectors / totalSelectors) * 100)
47
+ : 0;
48
+ // Estimate wasted bytes (proportional to unused selectors)
49
+ const wastedBytes = Math.round((selectors.totalBytes * wastePercentage) / 100);
50
+ // Build metrics
51
+ const metrics = {
52
+ totalClasses: selectors.classes.size,
53
+ totalIds: selectors.ids.size,
54
+ usedClasses: usedClassCount,
55
+ usedIds: usedIdCount,
56
+ unusedClasses,
57
+ unusedIds,
58
+ wastePercentage,
59
+ totalCssBytes: selectors.totalBytes,
60
+ wastedBytes,
61
+ totalRules: selectors.totalRules,
62
+ };
63
+ // Generate recommendations
64
+ const recommendations = this.generateRecommendations(wastePercentage);
65
+ return {
66
+ name: this.name,
67
+ score: wastePercentage, // Waste % maps directly to entropy score
68
+ weight: this.weight,
69
+ metrics,
70
+ recommendations,
71
+ };
72
+ }
73
+ generateRecommendations(wastePercentage) {
74
+ if (wastePercentage < 10) {
75
+ return [
76
+ 'Excellent! Your CSS is highly optimized.',
77
+ 'Continue monitoring to maintain low waste.',
78
+ ];
79
+ }
80
+ else if (wastePercentage < 30) {
81
+ return [
82
+ 'Good CSS hygiene. Minor cleanup opportunities exist.',
83
+ 'Review unused classes for removal.',
84
+ ];
85
+ }
86
+ else if (wastePercentage < 50) {
87
+ return [
88
+ 'Moderate waste detected.',
89
+ 'Consider removing unused framework imports.',
90
+ 'Review component-specific stylesheets.',
91
+ ];
92
+ }
93
+ else if (wastePercentage < 75) {
94
+ return [
95
+ 'High waste detected.',
96
+ 'Use PurgeCSS or Tailwind JIT to eliminate unused styles.',
97
+ 'Avoid importing full CSS frameworks.',
98
+ ];
99
+ }
100
+ else {
101
+ return [
102
+ 'Critical waste: Significant cleanup needed.',
103
+ 'Enable Tailwind JIT or PurgeCSS immediately.',
104
+ 'Remove unused CSS framework files.',
105
+ 'Consider switching to a utility-first approach.',
106
+ ];
107
+ }
108
+ }
109
+ }
110
+ /**
111
+ * Factory function for creating CSS Waste analyzer
112
+ */
113
+ export function cssWasteAnalyzer() {
114
+ return new CSSWasteAnalyzer();
115
+ }
116
+ //# sourceMappingURL=css-waste.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Duplication Analyzer (Placeholder for v0.3+)
3
+ *
4
+ * Analyzes CSS selector duplication and similar styles.
5
+ * Currently returns score of 0 (no duplication detected).
6
+ */
7
+ import type { Analyzer, AnalyzerContext, AnalyzerResult } from './types.js';
8
+ export interface DuplicationMetrics {
9
+ duplicateSelectors: number;
10
+ similarRules: number;
11
+ duplicationPercentage: number;
12
+ potentialSavings: number;
13
+ }
14
+ /**
15
+ * Duplication Analyzer (v0.3+ feature)
16
+ *
17
+ * Detects duplicate selectors and similar CSS rules.
18
+ * Currently a placeholder that returns 0.
19
+ */
20
+ export declare class DuplicationAnalyzer implements Analyzer {
21
+ name: string;
22
+ weight: number;
23
+ analyze(_context: AnalyzerContext): AnalyzerResult;
24
+ }
25
+ /**
26
+ * Factory function for creating Duplication analyzer
27
+ */
28
+ export declare function duplicationAnalyzer(): DuplicationAnalyzer;
29
+ //# sourceMappingURL=duplication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplication.d.ts","sourceRoot":"","sources":["../../src/analyzers/duplication.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5E,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,QAAQ;IAClD,IAAI,SAAiB;IACrB,MAAM,SAAO;IAEb,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,cAAc;CAuBnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,mBAAmB,CAEzD"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Duplication Analyzer (Placeholder for v0.3+)
3
+ *
4
+ * Analyzes CSS selector duplication and similar styles.
5
+ * Currently returns score of 0 (no duplication detected).
6
+ */
7
+ /**
8
+ * Duplication Analyzer (v0.3+ feature)
9
+ *
10
+ * Detects duplicate selectors and similar CSS rules.
11
+ * Currently a placeholder that returns 0.
12
+ */
13
+ export class DuplicationAnalyzer {
14
+ name = 'Duplication';
15
+ weight = 0.4; // 40% of overall entropy score
16
+ analyze(_context) {
17
+ // TODO: Implement duplication detection in v0.3+
18
+ // - Find duplicate selectors
19
+ // - Detect similar CSS rules (same properties, different selectors)
20
+ // - Calculate consolidation opportunities
21
+ const metrics = {
22
+ duplicateSelectors: 0,
23
+ similarRules: 0,
24
+ duplicationPercentage: 0,
25
+ potentialSavings: 0,
26
+ };
27
+ return {
28
+ name: this.name,
29
+ score: 0, // Placeholder: no duplication detected
30
+ weight: this.weight,
31
+ metrics,
32
+ recommendations: [
33
+ 'Duplication analysis coming in v0.3',
34
+ ],
35
+ };
36
+ }
37
+ }
38
+ /**
39
+ * Factory function for creating Duplication analyzer
40
+ */
41
+ export function duplicationAnalyzer() {
42
+ return new DuplicationAnalyzer();
43
+ }
44
+ //# sourceMappingURL=duplication.js.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Entropy Score Engine
3
+ *
4
+ * Combines multiple analyzers to calculate overall UI Entropy score.
5
+ */
6
+ import type { Analyzer, AnalyzerContext, EntropyScore } from './types.js';
7
+ /**
8
+ * Calculate overall entropy score from multiple analyzers
9
+ *
10
+ * Formula:
11
+ * UI Entropy Score = Σ(analyzer.score × analyzer.weight)
12
+ *
13
+ * Example (v0.1):
14
+ * = (CSS Waste Score × 0.6) + (Duplication Score × 0.4)
15
+ * = (75 × 0.6) + (0 × 0.4)
16
+ * = 45
17
+ */
18
+ export declare function calculateEntropyScore(context: AnalyzerContext, analyzers: Analyzer[]): EntropyScore;
19
+ //# sourceMappingURL=entropy-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entropy-engine.d.ts","sourceRoot":"","sources":["../../src/analyzers/entropy-engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAkB,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1F;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,QAAQ,EAAE,GACpB,YAAY,CA2Bd"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Entropy Score Engine
3
+ *
4
+ * Combines multiple analyzers to calculate overall UI Entropy score.
5
+ */
6
+ /**
7
+ * Calculate overall entropy score from multiple analyzers
8
+ *
9
+ * Formula:
10
+ * UI Entropy Score = Σ(analyzer.score × analyzer.weight)
11
+ *
12
+ * Example (v0.1):
13
+ * = (CSS Waste Score × 0.6) + (Duplication Score × 0.4)
14
+ * = (75 × 0.6) + (0 × 0.4)
15
+ * = 45
16
+ */
17
+ export function calculateEntropyScore(context, analyzers) {
18
+ // Run all analyzers
19
+ const results = analyzers.map(analyzer => analyzer.analyze(context));
20
+ // Normalize weights to sum to 1.0
21
+ const totalWeight = results.reduce((sum, r) => sum + r.weight, 0);
22
+ const normalizedResults = results.map(r => ({
23
+ ...r,
24
+ weight: r.weight / totalWeight,
25
+ }));
26
+ // Calculate weighted average
27
+ const overallScore = normalizedResults.reduce((sum, result) => sum + (result.score * result.weight), 0);
28
+ // Determine severity
29
+ const severity = getSeverityLevel(overallScore);
30
+ return {
31
+ overallScore: Math.round(overallScore),
32
+ analyzers: normalizedResults,
33
+ severity,
34
+ };
35
+ }
36
+ /**
37
+ * Map entropy score to severity level
38
+ */
39
+ function getSeverityLevel(score) {
40
+ if (score < 20)
41
+ return 'low';
42
+ if (score < 50)
43
+ return 'medium';
44
+ if (score < 75)
45
+ return 'high';
46
+ return 'critical';
47
+ }
48
+ //# sourceMappingURL=entropy-engine.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Analyzer System Exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './css-waste.js';
6
+ export * from './duplication.js';
7
+ export * from './entropy-engine.js';
8
+ import type { Analyzer } from './types.js';
9
+ /**
10
+ * Default analyzer configuration for v0.1
11
+ *
12
+ * Weights:
13
+ * - CSS Waste: 60%
14
+ * - Duplication: 40% (placeholder, returns 0)
15
+ */
16
+ export declare function getDefaultAnalyzers(): Analyzer[];
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAKpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,EAAE,CAKhD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Analyzer System Exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './css-waste.js';
6
+ export * from './duplication.js';
7
+ export * from './entropy-engine.js';
8
+ // Default analyzer set for v0.1
9
+ import { cssWasteAnalyzer } from './css-waste.js';
10
+ import { duplicationAnalyzer } from './duplication.js';
11
+ /**
12
+ * Default analyzer configuration for v0.1
13
+ *
14
+ * Weights:
15
+ * - CSS Waste: 60%
16
+ * - Duplication: 40% (placeholder, returns 0)
17
+ */
18
+ export function getDefaultAnalyzers() {
19
+ return [
20
+ cssWasteAnalyzer(),
21
+ duplicationAnalyzer(),
22
+ ];
23
+ }
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Analyzer Plugin System
3
+ *
4
+ * Supports pluggable analyzers for different entropy metrics:
5
+ * - CSS Waste Analyzer (current)
6
+ * - Duplication Analyzer (future)
7
+ * - Framework Analyzer (future)
8
+ * - Accessibility Analyzer (future)
9
+ */
10
+ import type { ExtractedSelectors } from '../parse-css.js';
11
+ import type { UsageExtractionResult } from '../extract-usage.js';
12
+ import type { CrawlResult } from '../crawl.js';
13
+ /**
14
+ * Input data available to all analyzers
15
+ */
16
+ export interface AnalyzerContext {
17
+ /** Extracted CSS selectors */
18
+ selectors: ExtractedSelectors;
19
+ /** Usage data from source files */
20
+ usage: UsageExtractionResult;
21
+ /** File crawl results */
22
+ crawl: CrawlResult;
23
+ }
24
+ /**
25
+ * Base analyzer result - all analyzers return a score 0-100
26
+ * where 0 = perfect, 100 = maximum entropy/waste
27
+ */
28
+ export interface AnalyzerResult {
29
+ /** Analyzer name */
30
+ name: string;
31
+ /** Entropy score (0-100): 0 = perfect, 100 = maximum entropy */
32
+ score: number;
33
+ /** Weight in overall entropy calculation (0-1) */
34
+ weight: number;
35
+ /** Human-readable metrics */
36
+ metrics: Record<string, any>;
37
+ /** Recommendations based on score */
38
+ recommendations: string[];
39
+ }
40
+ /**
41
+ * Analyzer plugin interface
42
+ */
43
+ export interface Analyzer {
44
+ /** Analyzer name */
45
+ name: string;
46
+ /** Weight in overall entropy score (0-1) */
47
+ weight: number;
48
+ /** Run the analyzer */
49
+ analyze(context: AnalyzerContext): AnalyzerResult;
50
+ }
51
+ /**
52
+ * Combined entropy score result
53
+ */
54
+ export interface EntropyScore {
55
+ /** Overall UI Entropy score (0-100) */
56
+ overallScore: number;
57
+ /** Individual analyzer results */
58
+ analyzers: AnalyzerResult[];
59
+ /** Severity level */
60
+ severity: 'low' | 'medium' | 'high' | 'critical';
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,SAAS,EAAE,kBAAkB,CAAC;IAC9B,mCAAmC;IACnC,KAAK,EAAE,qBAAqB,CAAC;IAC7B,yBAAyB;IACzB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,qCAAqC;IACrC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,qBAAqB;IACrB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;CAClD"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Analyzer Plugin System
3
+ *
4
+ * Supports pluggable analyzers for different entropy metrics:
5
+ * - CSS Waste Analyzer (current)
6
+ * - Duplication Analyzer (future)
7
+ * - Framework Analyzer (future)
8
+ * - Accessibility Analyzer (future)
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { extractSelectors, extractSelectorsFromMultiple, type ExtractedSelectors, type ParseWarning, } from './parse-css.js';
2
2
  export { extractUsage, extractUsedClasses, extractUsedIds, extractUsageFromMultiple, type UsageExtractionResult, } from './extract-usage.js';
3
+ export { type Analyzer, type AnalyzerContext, type AnalyzerResult, type EntropyScore, cssWasteAnalyzer, duplicationAnalyzer, CSSWasteAnalyzer, DuplicationAnalyzer, calculateEntropyScore, getDefaultAnalyzers, } from './analyzers/index.js';
3
4
  export { analyzeWaste, estimateWastedBytes, type AnalysisResult, } from './analyze.js';
4
5
  export { generateReport, generateJsonReport, generateTextReport, generateSummaryReport, type ReportFormat, type JsonReport, } from './report.js';
5
6
  export { crawl, crawlSync, type CrawlOptions, type CrawlResult, } from './crawl.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,EACL,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,IAAI,EACJ,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EAGjB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EAGnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,KAAK,EACL,SAAS,EACT,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,KAAK,MAAM,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,IAAI,EACJ,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,13 @@
2
2
  export { extractSelectors, extractSelectorsFromMultiple, } from './parse-css.js';
3
3
  // Usage Extraction
4
4
  export { extractUsage, extractUsedClasses, extractUsedIds, extractUsageFromMultiple, } from './extract-usage.js';
5
- // Analysis
5
+ // Analyzer System (NEW v0.3+)
6
+ export {
7
+ // Built-in analyzers
8
+ cssWasteAnalyzer, duplicationAnalyzer, CSSWasteAnalyzer, DuplicationAnalyzer,
9
+ // Entropy engine
10
+ calculateEntropyScore, getDefaultAnalyzers, } from './analyzers/index.js';
11
+ // Analysis (Legacy)
6
12
  export { analyzeWaste, estimateWastedBytes, } from './analyze.js';
7
13
  // Reporting
8
14
  export { generateReport, generateJsonReport, generateTextReport, generateSummaryReport, } from './report.js';
package/dist/scan.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { type ParseWarning } from './parse-css.js';
2
2
  import { type AnalysisResult } from './analyze.js';
3
3
  import { type ReportFormat } from './report.js';
4
+ import { type Analyzer, type EntropyScore } from './analyzers/index.js';
4
5
  export interface ScanOptions {
5
6
  /**
6
7
  * Directory to scan
@@ -18,9 +19,16 @@ export interface ScanOptions {
18
19
  cssPatterns?: string[];
19
20
  sourcePatterns?: string[];
20
21
  ignorePatterns?: string[];
22
+ /**
23
+ * Custom analyzers (v0.3+)
24
+ * @default getDefaultAnalyzers()
25
+ */
26
+ analyzers?: Analyzer[];
21
27
  }
22
28
  export interface ScanResult {
23
29
  analysis: AnalysisResult;
30
+ /** NEW: Entropy score from analyzer system */
31
+ entropyScore: EntropyScore;
24
32
  report: string;
25
33
  files: {
26
34
  cssFiles: number;
@@ -1 +1 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CA+D1D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,MAAsB,GAAG,MAAM,CAGjE"}
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,8CAA8C;IAC9C,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CA2E1D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,MAAsB,GAAG,MAAM,CAGjE"}
package/dist/scan.js CHANGED
@@ -4,6 +4,7 @@ import { extractSelectorsFromMultiple } from './parse-css.js';
4
4
  import { extractUsageFromMultiple } from './extract-usage.js';
5
5
  import { analyzeWaste } from './analyze.js';
6
6
  import { generateReport } from './report.js';
7
+ import { getDefaultAnalyzers, calculateEntropyScore, } from './analyzers/index.js';
7
8
  /**
8
9
  * Scan a project directory for CSS waste
9
10
  *
@@ -16,7 +17,8 @@ import { generateReport } from './report.js';
16
17
  * 6. Generate report
17
18
  */
18
19
  export function scan(options = {}) {
19
- const { baseDir = process.cwd(), format = 'text', cssPatterns, sourcePatterns, ignorePatterns, } = options;
20
+ const { baseDir = process.cwd(), format = 'text', cssPatterns, sourcePatterns, ignorePatterns, analyzers = getDefaultAnalyzers(), // NEW: Default analyzer set
21
+ } = options;
20
22
  // 1. Load configuration
21
23
  const config = getConfig(baseDir);
22
24
  // Override with CLI options if provided
@@ -46,13 +48,20 @@ export function scan(options = {}) {
46
48
  // 4. Extract usage from source files
47
49
  const sourceContents = crawlResult.sourceFiles.map(f => f.content);
48
50
  const usage = extractUsageFromMultiple(sourceContents);
49
- // 5. Analyze waste
51
+ // 5. Analyze waste (legacy)
50
52
  const analysis = analyzeWaste(selectors, usage);
53
+ // 5b. NEW: Run analyzer system and calculate entropy score
54
+ const entropyScore = calculateEntropyScore({
55
+ selectors,
56
+ usage,
57
+ crawl: crawlResult,
58
+ }, analyzers);
51
59
  // 6. Generate report
52
60
  const reportFormat = config.output?.format ?? format;
53
61
  const report = generateReport(analysis, reportFormat, selectors.warnings);
54
62
  return {
55
63
  analysis,
64
+ entropyScore, // NEW: Entropy score included
56
65
  report,
57
66
  files: {
58
67
  cssFiles: crawlResult.stats.totalCssFiles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui-entropy/scanner-core",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "CSS waste detection engine - finds unused classes and IDs in your codebase",
6
6
  "main": "./dist/index.js",