lhci-ai-assistant 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +228 -0
  3. package/dist/ai/copilot.d.ts +40 -0
  4. package/dist/ai/copilot.d.ts.map +1 -0
  5. package/dist/ai/copilot.js +176 -0
  6. package/dist/ai/copilot.js.map +1 -0
  7. package/dist/ai/local.d.ts +11 -0
  8. package/dist/ai/local.d.ts.map +1 -0
  9. package/dist/ai/local.js +199 -0
  10. package/dist/ai/local.js.map +1 -0
  11. package/dist/ai/openai.d.ts +39 -0
  12. package/dist/ai/openai.d.ts.map +1 -0
  13. package/dist/ai/openai.js +113 -0
  14. package/dist/ai/openai.js.map +1 -0
  15. package/dist/ai/prompt.d.ts +36 -0
  16. package/dist/ai/prompt.d.ts.map +1 -0
  17. package/dist/ai/prompt.js +190 -0
  18. package/dist/ai/prompt.js.map +1 -0
  19. package/dist/analyzer.d.ts +19 -0
  20. package/dist/analyzer.d.ts.map +1 -0
  21. package/dist/analyzer.js +264 -0
  22. package/dist/analyzer.js.map +1 -0
  23. package/dist/autofix/generator.d.ts +27 -0
  24. package/dist/autofix/generator.d.ts.map +1 -0
  25. package/dist/autofix/generator.js +153 -0
  26. package/dist/autofix/generator.js.map +1 -0
  27. package/dist/autofix/patterns.d.ts +34 -0
  28. package/dist/autofix/patterns.d.ts.map +1 -0
  29. package/dist/autofix/patterns.js +247 -0
  30. package/dist/autofix/patterns.js.map +1 -0
  31. package/dist/cli.d.ts +3 -0
  32. package/dist/cli.d.ts.map +1 -0
  33. package/dist/cli.js +159 -0
  34. package/dist/cli.js.map +1 -0
  35. package/dist/config.d.ts +19 -0
  36. package/dist/config.d.ts.map +1 -0
  37. package/dist/config.js +109 -0
  38. package/dist/config.js.map +1 -0
  39. package/dist/github/diff-fetcher.d.ts +43 -0
  40. package/dist/github/diff-fetcher.d.ts.map +1 -0
  41. package/dist/github/diff-fetcher.js +183 -0
  42. package/dist/github/diff-fetcher.js.map +1 -0
  43. package/dist/github/pr-commenter.d.ts +18 -0
  44. package/dist/github/pr-commenter.d.ts.map +1 -0
  45. package/dist/github/pr-commenter.js +229 -0
  46. package/dist/github/pr-commenter.js.map +1 -0
  47. package/dist/index.d.ts +23 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +85 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/metrics/comparator.d.ts +10 -0
  52. package/dist/metrics/comparator.d.ts.map +1 -0
  53. package/dist/metrics/comparator.js +228 -0
  54. package/dist/metrics/comparator.js.map +1 -0
  55. package/dist/metrics/extractor.d.ts +26 -0
  56. package/dist/metrics/extractor.d.ts.map +1 -0
  57. package/dist/metrics/extractor.js +174 -0
  58. package/dist/metrics/extractor.js.map +1 -0
  59. package/dist/metrics/loader.d.ts +35 -0
  60. package/dist/metrics/loader.d.ts.map +1 -0
  61. package/dist/metrics/loader.js +94 -0
  62. package/dist/metrics/loader.js.map +1 -0
  63. package/dist/output/json.d.ts +23 -0
  64. package/dist/output/json.d.ts.map +1 -0
  65. package/dist/output/json.js +144 -0
  66. package/dist/output/json.js.map +1 -0
  67. package/dist/output/markdown.d.ts +10 -0
  68. package/dist/output/markdown.d.ts.map +1 -0
  69. package/dist/output/markdown.js +226 -0
  70. package/dist/output/markdown.js.map +1 -0
  71. package/dist/output/terminal.d.ts +22 -0
  72. package/dist/output/terminal.d.ts.map +1 -0
  73. package/dist/output/terminal.js +238 -0
  74. package/dist/output/terminal.js.map +1 -0
  75. package/dist/types.d.ts +156 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +6 -0
  78. package/dist/types.js.map +1 -0
  79. package/package.json +80 -0
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compareMetrics = compareMetrics;
4
+ exports.getComparisonSummary = getComparisonSummary;
5
+ /**
6
+ * Compare current metrics against baseline metrics
7
+ */
8
+ function compareMetrics(current, baseline) {
9
+ const comparisons = [];
10
+ // Compare scores
11
+ comparisons.push(...compareScores(current.scores, baseline.scores));
12
+ // Compare Core Web Vitals
13
+ comparisons.push(...compareCoreWebVitals(current.coreWebVitals, baseline.coreWebVitals));
14
+ // Categorize results
15
+ const regressions = comparisons.filter((c) => c.isRegression);
16
+ const improvements = comparisons.filter((c) => c.isImprovement);
17
+ const unchanged = comparisons.filter((c) => !c.isRegression && !c.isImprovement);
18
+ // Calculate overall score change
19
+ const overallScore = {
20
+ base: baseline.scores.performance ?? 0,
21
+ current: current.scores.performance ?? 0,
22
+ diff: (current.scores.performance ?? 0) - (baseline.scores.performance ?? 0),
23
+ };
24
+ return {
25
+ regressions: sortBySeverity(regressions),
26
+ improvements: sortBySeverity(improvements),
27
+ unchanged,
28
+ overallScore,
29
+ };
30
+ }
31
+ /**
32
+ * Compare category scores
33
+ */
34
+ function compareScores(current, baseline) {
35
+ const comparisons = [];
36
+ const scoreKeys = ['performance', 'accessibility', 'bestPractices', 'seo'];
37
+ for (const key of scoreKeys) {
38
+ const baseValue = baseline[key];
39
+ const currentValue = current[key];
40
+ if (baseValue !== undefined && currentValue !== undefined) {
41
+ comparisons.push(createScoreComparison(formatScoreKey(key), currentValue, baseValue));
42
+ }
43
+ }
44
+ return comparisons;
45
+ }
46
+ /**
47
+ * Compare Core Web Vitals
48
+ */
49
+ function compareCoreWebVitals(current, baseline) {
50
+ const comparisons = [];
51
+ const metricKeys = ['fcp', 'lcp', 'tbt', 'cls', 'speedIndex', 'tti'];
52
+ for (const key of metricKeys) {
53
+ const baseValue = baseline[key];
54
+ const currentValue = current[key];
55
+ if (baseValue !== undefined && currentValue !== undefined) {
56
+ comparisons.push(createMetricComparison(formatMetricKey(key), currentValue, baseValue));
57
+ }
58
+ }
59
+ return comparisons;
60
+ }
61
+ /**
62
+ * Create a comparison for score metrics (higher is better)
63
+ */
64
+ function createScoreComparison(metric, current, base) {
65
+ const diff = current - base;
66
+ const diffPercent = base !== 0 ? (diff / base) * 100 : 0;
67
+ // For scores, higher is better
68
+ const isRegression = diff < -0.01; // 1% threshold
69
+ const isImprovement = diff > 0.01;
70
+ return {
71
+ metric,
72
+ base,
73
+ current,
74
+ diff,
75
+ diffPercent,
76
+ isRegression,
77
+ isImprovement,
78
+ severity: getScoreSeverity(diff),
79
+ };
80
+ }
81
+ /**
82
+ * Create a comparison for timing metrics (lower is better)
83
+ */
84
+ function createMetricComparison(metric, current, base) {
85
+ const diff = current - base;
86
+ const diffPercent = base !== 0 ? (diff / base) * 100 : 0;
87
+ // For timing metrics, lower is better (except CLS which also lower is better)
88
+ const isRegression = diff > getMetricThreshold(metric);
89
+ const isImprovement = diff < -getMetricThreshold(metric);
90
+ return {
91
+ metric,
92
+ base,
93
+ current,
94
+ diff,
95
+ diffPercent,
96
+ isRegression,
97
+ isImprovement,
98
+ severity: getMetricSeverity(metric, diff),
99
+ };
100
+ }
101
+ /**
102
+ * Get the threshold for considering a change significant
103
+ */
104
+ function getMetricThreshold(metric) {
105
+ const thresholds = {
106
+ FCP: 100, // 100ms
107
+ LCP: 100,
108
+ TBT: 50, // 50ms
109
+ CLS: 0.01,
110
+ 'Speed Index': 200,
111
+ TTI: 200,
112
+ };
113
+ return thresholds[metric] ?? 100;
114
+ }
115
+ /**
116
+ * Get severity for score changes
117
+ */
118
+ function getScoreSeverity(diff) {
119
+ const absDiff = Math.abs(diff);
120
+ if (absDiff >= 0.2)
121
+ return 'critical';
122
+ if (absDiff >= 0.1)
123
+ return 'high';
124
+ if (absDiff >= 0.05)
125
+ return 'medium';
126
+ return 'low';
127
+ }
128
+ /**
129
+ * Get severity for metric changes
130
+ */
131
+ function getMetricSeverity(metric, diff) {
132
+ const absDiff = Math.abs(diff);
133
+ // Different thresholds for different metrics
134
+ if (metric === 'CLS') {
135
+ if (absDiff >= 0.1)
136
+ return 'critical';
137
+ if (absDiff >= 0.05)
138
+ return 'high';
139
+ if (absDiff >= 0.02)
140
+ return 'medium';
141
+ return 'low';
142
+ }
143
+ // For timing metrics (ms)
144
+ if (absDiff >= 1000)
145
+ return 'critical';
146
+ if (absDiff >= 500)
147
+ return 'high';
148
+ if (absDiff >= 200)
149
+ return 'medium';
150
+ return 'low';
151
+ }
152
+ /**
153
+ * Format score key for display
154
+ */
155
+ function formatScoreKey(key) {
156
+ const mapping = {
157
+ performance: 'Performance Score',
158
+ accessibility: 'Accessibility Score',
159
+ bestPractices: 'Best Practices Score',
160
+ seo: 'SEO Score',
161
+ };
162
+ return mapping[key] ?? key;
163
+ }
164
+ /**
165
+ * Format metric key for display
166
+ */
167
+ function formatMetricKey(key) {
168
+ const mapping = {
169
+ fcp: 'FCP',
170
+ lcp: 'LCP',
171
+ tbt: 'TBT',
172
+ cls: 'CLS',
173
+ speedIndex: 'Speed Index',
174
+ tti: 'TTI',
175
+ };
176
+ return mapping[key] ?? key;
177
+ }
178
+ /**
179
+ * Sort comparisons by severity (most severe first)
180
+ */
181
+ function sortBySeverity(comparisons) {
182
+ const severityOrder = {
183
+ critical: 0,
184
+ high: 1,
185
+ medium: 2,
186
+ low: 3,
187
+ };
188
+ return [...comparisons].sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
189
+ }
190
+ /**
191
+ * Get a summary of the comparison result
192
+ */
193
+ function getComparisonSummary(result) {
194
+ const lines = [];
195
+ if (result.regressions.length > 0) {
196
+ lines.push(`Regressions: ${result.regressions.length}`);
197
+ for (const r of result.regressions.slice(0, 3)) {
198
+ lines.push(` - ${r.metric}: ${formatChange(r)}`);
199
+ }
200
+ }
201
+ if (result.improvements.length > 0) {
202
+ lines.push(`Improvements: ${result.improvements.length}`);
203
+ for (const i of result.improvements.slice(0, 3)) {
204
+ lines.push(` - ${i.metric}: ${formatChange(i)}`);
205
+ }
206
+ }
207
+ const scoreDiff = result.overallScore.diff * 100;
208
+ lines.push(`\nOverall Performance: ${scoreDiff >= 0 ? '+' : ''}${scoreDiff.toFixed(1)}%`);
209
+ return lines.join('\n');
210
+ }
211
+ /**
212
+ * Format a metric change for display
213
+ */
214
+ function formatChange(comparison) {
215
+ const sign = comparison.diff >= 0 ? '+' : '';
216
+ if (comparison.metric.includes('Score')) {
217
+ const basePct = (comparison.base * 100).toFixed(0);
218
+ const currentPct = (comparison.current * 100).toFixed(0);
219
+ const diffPct = (comparison.diff * 100).toFixed(1);
220
+ return `${basePct}% → ${currentPct}% (${sign}${diffPct}%)`;
221
+ }
222
+ if (comparison.metric === 'CLS') {
223
+ return `${comparison.base.toFixed(3)} → ${comparison.current.toFixed(3)} (${sign}${comparison.diff.toFixed(3)})`;
224
+ }
225
+ // Timing metrics
226
+ return `${comparison.base.toFixed(0)}ms → ${comparison.current.toFixed(0)}ms (${sign}${comparison.diff.toFixed(0)}ms)`;
227
+ }
228
+ //# sourceMappingURL=comparator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparator.js","sourceRoot":"","sources":["../../src/metrics/comparator.ts"],"names":[],"mappings":";;AAKA,wCAkCC;AA6MD,oDAuBC;AAzQD;;GAEG;AACH,SAAgB,cAAc,CAC5B,OAAgB,EAChB,QAAiB;IAEjB,MAAM,WAAW,GAAuB,EAAE,CAAC;IAE3C,iBAAiB;IACjB,WAAW,CAAC,IAAI,CACd,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAClD,CAAC;IAEF,0BAA0B;IAC1B,WAAW,CAAC,IAAI,CACd,GAAG,oBAAoB,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,aAAa,CAAC,CACvE,CAAC;IAEF,qBAAqB;IACrB,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9D,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAEjF,iCAAiC;IACjC,MAAM,YAAY,GAAG;QACnB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC;QACtC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC;QACxC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;KAC7E,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,cAAc,CAAC,WAAW,CAAC;QACxC,YAAY,EAAE,cAAc,CAAC,YAAY,CAAC;QAC1C,SAAS;QACT,YAAY;KACb,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,OAA0B,EAC1B,QAA2B;IAE3B,MAAM,WAAW,GAAuB,EAAE,CAAC;IAE3C,MAAM,SAAS,GAAG,CAAC,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,KAAK,CAAU,CAAC;IAEpF,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC1D,WAAW,CAAC,IAAI,CACd,qBAAqB,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,OAAiC,EACjC,QAAkC;IAElC,MAAM,WAAW,GAAuB,EAAE,CAAC;IAE3C,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,CAAU,CAAC;IAE9E,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,SAAS,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC1D,WAAW,CAAC,IAAI,CACd,sBAAsB,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CACtE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC5B,MAAc,EACd,OAAe,EACf,IAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzD,+BAA+B;IAC/B,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,eAAe;IAClD,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;IAElC,OAAO;QACL,MAAM;QACN,IAAI;QACJ,OAAO;QACP,IAAI;QACJ,WAAW;QACX,YAAY;QACZ,aAAa;QACb,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAC7B,MAAc,EACd,OAAe,EACf,IAAY;IAEZ,MAAM,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzD,8EAA8E;IAC9E,MAAM,YAAY,GAAG,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAEzD,OAAO;QACL,MAAM;QACN,IAAI;QACJ,OAAO;QACP,IAAI;QACJ,WAAW;QACX,YAAY;QACZ,aAAa;QACb,QAAQ,EAAE,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CAAC,MAAc;IACxC,MAAM,UAAU,GAA2B;QACzC,GAAG,EAAE,GAAG,EAAE,QAAQ;QAClB,GAAG,EAAE,GAAG;QACR,GAAG,EAAE,EAAE,EAAE,OAAO;QAChB,GAAG,EAAE,IAAI;QACT,aAAa,EAAE,GAAG;QAClB,GAAG,EAAE,GAAG;KACT,CAAC;IAEF,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/B,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,UAAU,CAAC;IACtC,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IACrC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,MAAc,EACd,IAAY;IAEZ,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/B,6CAA6C;IAC7C,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,IAAI,OAAO,IAAI,GAAG;YAAE,OAAO,UAAU,CAAC;QACtC,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,MAAM,CAAC;QACnC,IAAI,OAAO,IAAI,IAAI;YAAE,OAAO,QAAQ,CAAC;QACrC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0BAA0B;IAC1B,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,UAAU,CAAC;IACvC,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,QAAQ,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,OAAO,GAA2B;QACtC,WAAW,EAAE,mBAAmB;QAChC,aAAa,EAAE,qBAAqB;QACpC,aAAa,EAAE,sBAAsB;QACrC,GAAG,EAAE,WAAW;KACjB,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,OAAO,GAA2B;QACtC,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;QACV,UAAU,EAAE,aAAa;QACzB,GAAG,EAAE,KAAK;KACX,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,WAA+B;IACrD,MAAM,aAAa,GAA2B;QAC5C,QAAQ,EAAE,CAAC;QACX,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;KACP,CAAC;IAEF,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,CAC1B,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAChE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,MAAwB;IAC3D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;QACxD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,GAAG,GAAG,CAAC;IACjD,KAAK,CAAC,IAAI,CACR,0BAA0B,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAC9E,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,UAA4B;IAChD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7C,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO,GAAG,OAAO,OAAO,UAAU,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC;IAC7D,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAChC,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACnH,CAAC;IAED,iBAAiB;IACjB,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACzH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { LHReport, Metrics } from '../types';
2
+ /**
3
+ * Extract key metrics from a Lighthouse report
4
+ */
5
+ export declare function extractMetrics(lhr: LHReport): Metrics;
6
+ /**
7
+ * Get a human-readable summary of metrics
8
+ */
9
+ export declare function getMetricsSummary(metrics: Metrics): string;
10
+ /**
11
+ * Format a score as a percentage
12
+ */
13
+ export declare function formatScore(score: number): string;
14
+ /**
15
+ * Format milliseconds in a human-readable way
16
+ */
17
+ export declare function formatMs(ms: number): string;
18
+ /**
19
+ * Format bytes in a human-readable way
20
+ */
21
+ export declare function formatBytes(bytes: number): string;
22
+ /**
23
+ * Get the rating for a metric value
24
+ */
25
+ export declare function getMetricRating(metric: string, value: number): 'good' | 'needs-improvement' | 'poor';
26
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/metrics/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAe,MAAM,UAAU,CAAC;AAE1D;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAMrD;AAuED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CA2C1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,mBAAmB,GAAG,MAAM,CAsBvC"}
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractMetrics = extractMetrics;
4
+ exports.getMetricsSummary = getMetricsSummary;
5
+ exports.formatScore = formatScore;
6
+ exports.formatMs = formatMs;
7
+ exports.formatBytes = formatBytes;
8
+ exports.getMetricRating = getMetricRating;
9
+ /**
10
+ * Extract key metrics from a Lighthouse report
11
+ */
12
+ function extractMetrics(lhr) {
13
+ return {
14
+ scores: extractScores(lhr),
15
+ coreWebVitals: extractCoreWebVitals(lhr),
16
+ opportunities: extractOpportunities(lhr),
17
+ };
18
+ }
19
+ /**
20
+ * Extract category scores
21
+ */
22
+ function extractScores(lhr) {
23
+ return {
24
+ performance: lhr.categories.performance?.score ?? undefined,
25
+ accessibility: lhr.categories.accessibility?.score ?? undefined,
26
+ bestPractices: lhr.categories['best-practices']?.score ?? undefined,
27
+ seo: lhr.categories.seo?.score ?? undefined,
28
+ };
29
+ }
30
+ /**
31
+ * Extract Core Web Vitals metrics
32
+ */
33
+ function extractCoreWebVitals(lhr) {
34
+ return {
35
+ fcp: getNumericValue(lhr, 'first-contentful-paint'),
36
+ lcp: getNumericValue(lhr, 'largest-contentful-paint'),
37
+ tbt: getNumericValue(lhr, 'total-blocking-time'),
38
+ cls: getNumericValue(lhr, 'cumulative-layout-shift'),
39
+ speedIndex: getNumericValue(lhr, 'speed-index'),
40
+ tti: getNumericValue(lhr, 'interactive'),
41
+ };
42
+ }
43
+ /**
44
+ * Get numeric value from an audit
45
+ */
46
+ function getNumericValue(lhr, auditId) {
47
+ const audit = lhr.audits[auditId];
48
+ if (!audit || audit.numericValue === undefined) {
49
+ return undefined;
50
+ }
51
+ return audit.numericValue;
52
+ }
53
+ /**
54
+ * Extract performance opportunities
55
+ */
56
+ function extractOpportunities(lhr) {
57
+ const opportunities = [];
58
+ for (const [id, audit] of Object.entries(lhr.audits)) {
59
+ // Only include opportunities that have room for improvement
60
+ if (audit.details?.type === 'opportunity' &&
61
+ audit.score !== null &&
62
+ audit.score !== 1) {
63
+ opportunities.push({
64
+ id,
65
+ title: audit.title,
66
+ description: audit.description,
67
+ savingsMs: audit.details.overallSavingsMs,
68
+ savingsBytes: audit.details.overallSavingsBytes,
69
+ score: audit.score,
70
+ });
71
+ }
72
+ }
73
+ // Sort by potential savings (highest first)
74
+ return opportunities.sort((a, b) => {
75
+ const savingsA = a.savingsMs || 0;
76
+ const savingsB = b.savingsMs || 0;
77
+ return savingsB - savingsA;
78
+ });
79
+ }
80
+ /**
81
+ * Get a human-readable summary of metrics
82
+ */
83
+ function getMetricsSummary(metrics) {
84
+ const lines = [];
85
+ // Scores
86
+ lines.push('Category Scores:');
87
+ if (metrics.scores.performance !== undefined) {
88
+ lines.push(` Performance: ${formatScore(metrics.scores.performance)}`);
89
+ }
90
+ if (metrics.scores.accessibility !== undefined) {
91
+ lines.push(` Accessibility: ${formatScore(metrics.scores.accessibility)}`);
92
+ }
93
+ if (metrics.scores.bestPractices !== undefined) {
94
+ lines.push(` Best Practices: ${formatScore(metrics.scores.bestPractices)}`);
95
+ }
96
+ if (metrics.scores.seo !== undefined) {
97
+ lines.push(` SEO: ${formatScore(metrics.scores.seo)}`);
98
+ }
99
+ // Core Web Vitals
100
+ lines.push('\nCore Web Vitals:');
101
+ if (metrics.coreWebVitals.fcp !== undefined) {
102
+ lines.push(` FCP: ${formatMs(metrics.coreWebVitals.fcp)}`);
103
+ }
104
+ if (metrics.coreWebVitals.lcp !== undefined) {
105
+ lines.push(` LCP: ${formatMs(metrics.coreWebVitals.lcp)}`);
106
+ }
107
+ if (metrics.coreWebVitals.tbt !== undefined) {
108
+ lines.push(` TBT: ${formatMs(metrics.coreWebVitals.tbt)}`);
109
+ }
110
+ if (metrics.coreWebVitals.cls !== undefined) {
111
+ lines.push(` CLS: ${metrics.coreWebVitals.cls.toFixed(3)}`);
112
+ }
113
+ // Top opportunities
114
+ if (metrics.opportunities.length > 0) {
115
+ lines.push('\nTop Opportunities:');
116
+ for (const opp of metrics.opportunities.slice(0, 5)) {
117
+ const savings = opp.savingsMs ? ` (${formatMs(opp.savingsMs)} savings)` : '';
118
+ lines.push(` - ${opp.title}${savings}`);
119
+ }
120
+ }
121
+ return lines.join('\n');
122
+ }
123
+ /**
124
+ * Format a score as a percentage
125
+ */
126
+ function formatScore(score) {
127
+ return `${Math.round(score * 100)}%`;
128
+ }
129
+ /**
130
+ * Format milliseconds in a human-readable way
131
+ */
132
+ function formatMs(ms) {
133
+ if (ms >= 1000) {
134
+ return `${(ms / 1000).toFixed(2)}s`;
135
+ }
136
+ return `${Math.round(ms)}ms`;
137
+ }
138
+ /**
139
+ * Format bytes in a human-readable way
140
+ */
141
+ function formatBytes(bytes) {
142
+ if (bytes >= 1024 * 1024) {
143
+ return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
144
+ }
145
+ if (bytes >= 1024) {
146
+ return `${(bytes / 1024).toFixed(2)} KB`;
147
+ }
148
+ return `${bytes} B`;
149
+ }
150
+ /**
151
+ * Get the rating for a metric value
152
+ */
153
+ function getMetricRating(metric, value) {
154
+ const thresholds = {
155
+ fcp: { good: 1800, poor: 3000 },
156
+ lcp: { good: 2500, poor: 4000 },
157
+ tbt: { good: 200, poor: 600 },
158
+ cls: { good: 0.1, poor: 0.25 },
159
+ speedIndex: { good: 3400, poor: 5800 },
160
+ tti: { good: 3800, poor: 7300 },
161
+ };
162
+ const threshold = thresholds[metric.toLowerCase()];
163
+ if (!threshold) {
164
+ return 'needs-improvement';
165
+ }
166
+ if (value <= threshold.good) {
167
+ return 'good';
168
+ }
169
+ if (value >= threshold.poor) {
170
+ return 'poor';
171
+ }
172
+ return 'needs-improvement';
173
+ }
174
+ //# sourceMappingURL=extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/metrics/extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { LHReport } from '../types';
2
+ /**
3
+ * Load Lighthouse reports from the .lighthouseci directory
4
+ */
5
+ export declare function loadLighthouseReports(basePath?: string): Promise<LHReport[]>;
6
+ /**
7
+ * Load a specific Lighthouse report by filename
8
+ */
9
+ export declare function loadReportByName(filename: string, basePath?: string): Promise<LHReport>;
10
+ /**
11
+ * Load the manifest file from .lighthouseci
12
+ */
13
+ export declare function loadManifest(basePath?: string): Promise<ManifestEntry[]>;
14
+ export interface ManifestEntry {
15
+ url: string;
16
+ isRepresentativeRun: boolean;
17
+ jsonPath: string;
18
+ htmlPath: string;
19
+ summary: {
20
+ performance: number;
21
+ accessibility: number;
22
+ 'best-practices': number;
23
+ seo: number;
24
+ pwa?: number;
25
+ };
26
+ }
27
+ /**
28
+ * Get the representative run for each URL
29
+ */
30
+ export declare function getRepresentativeRuns(basePath?: string): Promise<Map<string, LHReport>>;
31
+ /**
32
+ * List available Lighthouse reports
33
+ */
34
+ export declare function listReports(basePath?: string): string[];
35
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/metrics/loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIpC;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAmClF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAU7F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAU9E;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAmB7F;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CASvD"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadLighthouseReports = loadLighthouseReports;
4
+ exports.loadReportByName = loadReportByName;
5
+ exports.loadManifest = loadManifest;
6
+ exports.getRepresentativeRuns = getRepresentativeRuns;
7
+ exports.listReports = listReports;
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ const LHCI_DIR = '.lighthouseci';
11
+ /**
12
+ * Load Lighthouse reports from the .lighthouseci directory
13
+ */
14
+ async function loadLighthouseReports(basePath) {
15
+ const lhciDir = (0, path_1.join)(basePath || process.cwd(), LHCI_DIR);
16
+ if (!(0, fs_1.existsSync)(lhciDir)) {
17
+ throw new Error(`No ${LHCI_DIR} directory found. Run \`lhci collect\` first to generate Lighthouse reports.`);
18
+ }
19
+ const files = (0, fs_1.readdirSync)(lhciDir);
20
+ const jsonFiles = files.filter((file) => file.startsWith('lhr-') && file.endsWith('.json'));
21
+ if (jsonFiles.length === 0) {
22
+ throw new Error(`No Lighthouse reports found in ${LHCI_DIR}. Run \`lhci collect\` first.`);
23
+ }
24
+ const reports = [];
25
+ for (const file of jsonFiles) {
26
+ try {
27
+ const content = (0, fs_1.readFileSync)((0, path_1.join)(lhciDir, file), 'utf-8');
28
+ const report = JSON.parse(content);
29
+ reports.push(report);
30
+ }
31
+ catch (error) {
32
+ console.warn(`Warning: Failed to parse ${file}:`, error);
33
+ }
34
+ }
35
+ if (reports.length === 0) {
36
+ throw new Error('Failed to load any valid Lighthouse reports.');
37
+ }
38
+ return reports;
39
+ }
40
+ /**
41
+ * Load a specific Lighthouse report by filename
42
+ */
43
+ async function loadReportByName(filename, basePath) {
44
+ const lhciDir = (0, path_1.join)(basePath || process.cwd(), LHCI_DIR);
45
+ const filePath = (0, path_1.join)(lhciDir, filename);
46
+ if (!(0, fs_1.existsSync)(filePath)) {
47
+ throw new Error(`Report not found: ${filename}`);
48
+ }
49
+ const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
50
+ return JSON.parse(content);
51
+ }
52
+ /**
53
+ * Load the manifest file from .lighthouseci
54
+ */
55
+ async function loadManifest(basePath) {
56
+ const lhciDir = (0, path_1.join)(basePath || process.cwd(), LHCI_DIR);
57
+ const manifestPath = (0, path_1.join)(lhciDir, 'manifest.json');
58
+ if (!(0, fs_1.existsSync)(manifestPath)) {
59
+ return [];
60
+ }
61
+ const content = (0, fs_1.readFileSync)(manifestPath, 'utf-8');
62
+ return JSON.parse(content);
63
+ }
64
+ /**
65
+ * Get the representative run for each URL
66
+ */
67
+ async function getRepresentativeRuns(basePath) {
68
+ const manifest = await loadManifest(basePath);
69
+ const runs = new Map();
70
+ for (const entry of manifest) {
71
+ if (entry.isRepresentativeRun) {
72
+ try {
73
+ const report = await loadReportByName(entry.jsonPath.replace('.lighthouseci/', ''), basePath);
74
+ runs.set(entry.url, report);
75
+ }
76
+ catch (error) {
77
+ console.warn(`Warning: Failed to load representative run for ${entry.url}`);
78
+ }
79
+ }
80
+ }
81
+ return runs;
82
+ }
83
+ /**
84
+ * List available Lighthouse reports
85
+ */
86
+ function listReports(basePath) {
87
+ const lhciDir = (0, path_1.join)(basePath || process.cwd(), LHCI_DIR);
88
+ if (!(0, fs_1.existsSync)(lhciDir)) {
89
+ return [];
90
+ }
91
+ const files = (0, fs_1.readdirSync)(lhciDir);
92
+ return files.filter((file) => file.startsWith('lhr-') && file.endsWith('.json'));
93
+ }
94
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/metrics/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { AnalysisResult } from '../types';
2
+ /**
3
+ * Format analysis result as JSON
4
+ */
5
+ export declare function formatAsJSON(result: AnalysisResult, pretty?: boolean): string;
6
+ /**
7
+ * Output analysis result as JSON to stdout
8
+ */
9
+ export declare function outputAsJSON(result: AnalysisResult, pretty?: boolean): void;
10
+ /**
11
+ * Parse analysis result from JSON
12
+ */
13
+ export declare function parseFromJSON(json: string): AnalysisResult;
14
+ /**
15
+ * Create a minimal JSON report
16
+ */
17
+ export declare function formatMinimalJSON(result: AnalysisResult): string;
18
+ /**
19
+ * Format as SARIF (Static Analysis Results Interchange Format)
20
+ * Useful for GitHub Advanced Security integration
21
+ */
22
+ export declare function formatAsSARIF(result: AnalysisResult): string;
23
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/output/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,GAAE,OAAc,GAAG,MAAM,CA4CnF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,GAAE,OAAc,GAAG,IAAI,CAEjF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAW1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAWhE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAsC5D"}