create-claude-cabinet 0.29.13 → 0.29.14
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/package.json +1 -1
- package/templates/site-audit-runtime/package.json +1 -1
- package/templates/site-audit-runtime/src/checks/axe-core.mjs +13 -6
- package/templates/site-audit-runtime/src/checks/lighthouse.mjs +15 -1
- package/templates/site-audit-runtime/src/checks/pa11y.mjs +2 -2
- package/templates/site-audit-runtime/src/report.mjs +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-cabinet/site-audit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Comprehensive deployed-site quality audit engine for Claude Cabinet. Runs checks across performance, accessibility, security, SEO, content, DNS, and privacy against a deployed URL; single-site and comparison modes; standalone HTML report.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,12 +33,19 @@ export function normalize(raw, durationMs) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const violations = Array.isArray(data) ? data.flatMap(p => p.violations || []) : (data.violations || []);
|
|
36
|
-
const findings = violations.map(v =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
const findings = violations.map(v => {
|
|
37
|
+
const targets = (v.nodes || []).slice(0, 3).map(n =>
|
|
38
|
+
(n.target || []).flat().join(' > ')
|
|
39
|
+
).filter(Boolean);
|
|
40
|
+
return {
|
|
41
|
+
severity: IMPACT_TO_SEVERITY[v.impact] || 'info',
|
|
42
|
+
message: v.description || v.id,
|
|
43
|
+
url: v.helpUrl || undefined,
|
|
44
|
+
context: targets.length
|
|
45
|
+
? `Elements: ${targets.join(', ')}${v.nodes?.length > 3 ? ` (+${v.nodes.length - 3} more)` : ''}`
|
|
46
|
+
: (v.nodes?.[0]?.html?.slice(0, 200) || undefined),
|
|
47
|
+
};
|
|
48
|
+
});
|
|
42
49
|
|
|
43
50
|
const worstSev = findings.length ? findings.reduce((w, f) => {
|
|
44
51
|
const o = { critical: 0, serious: 1, moderate: 2, info: 3 };
|
|
@@ -59,7 +59,21 @@ export function normalize(raw, durationMs) {
|
|
|
59
59
|
return (order[f.severity] ?? 3) < (order[w] ?? 3) ? f.severity : w;
|
|
60
60
|
}, 'info') : null;
|
|
61
61
|
|
|
62
|
-
const
|
|
62
|
+
const cwvKeys = {
|
|
63
|
+
'largest-contentful-paint': 'LCP',
|
|
64
|
+
'cumulative-layout-shift': 'CLS',
|
|
65
|
+
'first-contentful-paint': 'FCP',
|
|
66
|
+
'total-blocking-time': 'TBT',
|
|
67
|
+
'speed-index': 'Speed Index',
|
|
68
|
+
'interactive': 'TTI',
|
|
69
|
+
};
|
|
70
|
+
const metrics = {};
|
|
71
|
+
for (const [auditId, label] of Object.entries(cwvKeys)) {
|
|
72
|
+
const a = audits[auditId];
|
|
73
|
+
if (a?.displayValue) metrics[label] = a.displayValue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const details = { categories: scores, ...(Object.keys(metrics).length && { metrics }) };
|
|
63
77
|
const passSummary = Object.entries(scores)
|
|
64
78
|
.map(([k, v]) => `${k.replace(/-/g, ' ')}: ${v}`)
|
|
65
79
|
.join(', ');
|
|
@@ -28,8 +28,8 @@ export function normalize(raw, durationMs) {
|
|
|
28
28
|
const findings = issues.map(i => ({
|
|
29
29
|
severity: TYPE_TO_SEVERITY[i.type] || 'info',
|
|
30
30
|
message: i.message || i.code || 'unknown',
|
|
31
|
-
context: i.
|
|
32
|
-
url: i.
|
|
31
|
+
context: [i.code, i.selector ? `Element: ${i.selector}` : null].filter(Boolean).join(' — ') || undefined,
|
|
32
|
+
url: i.context?.slice(0, 150) || undefined,
|
|
33
33
|
}));
|
|
34
34
|
|
|
35
35
|
const errors = findings.filter(f => f.severity === 'serious' || f.severity === 'critical').length;
|
|
@@ -132,6 +132,13 @@ function renderDetails(result) {
|
|
|
132
132
|
});
|
|
133
133
|
html += `<div style="margin-bottom:.75rem;font-size:.9rem">${items.join('')}</div>`;
|
|
134
134
|
}
|
|
135
|
+
const metrics = result.details.metrics;
|
|
136
|
+
if (metrics && typeof metrics === 'object') {
|
|
137
|
+
const items = Object.entries(metrics).map(([label, value]) =>
|
|
138
|
+
`<span style="display:inline-block;margin-right:1.2rem"><strong>${esc(label)}</strong> ${esc(String(value))}</span>`
|
|
139
|
+
);
|
|
140
|
+
html += `<div style="margin-bottom:.75rem;font-size:.85rem;color:#555">Core Web Vitals: ${items.join('')}</div>`;
|
|
141
|
+
}
|
|
135
142
|
const types = result.details.types;
|
|
136
143
|
if (Array.isArray(types) && types.length) {
|
|
137
144
|
html += `<div style="margin-bottom:.75rem;font-size:.85rem;color:#555">Schema types: ${types.map(t => `<strong>${esc(String(t))}</strong>`).join(', ')}</div>`;
|