@hale-bopp/valentino-engine 2.2.0 → 2.3.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 +61 -0
- package/dist/bin/commands/cockpit.d.ts +16 -0
- package/dist/bin/commands/cockpit.d.ts.map +1 -0
- package/dist/bin/commands/cockpit.js +205 -0
- package/dist/bin/commands/cockpit.js.map +1 -0
- package/dist/bin/commands/theme-audit.d.ts +7 -0
- package/dist/bin/commands/theme-audit.d.ts.map +1 -0
- package/dist/bin/commands/theme-audit.js +70 -0
- package/dist/bin/commands/theme-audit.js.map +1 -0
- package/dist/bin/commands/validate.d.ts.map +1 -1
- package/dist/bin/commands/validate.js +94 -1
- package/dist/bin/commands/validate.js.map +1 -1
- package/dist/bin/valentino.js +14 -0
- package/dist/bin/valentino.js.map +1 -1
- package/dist/cockpit-server.d.ts +17 -0
- package/dist/cockpit-server.d.ts.map +1 -0
- package/dist/cockpit-server.js +505 -0
- package/dist/cockpit-server.js.map +1 -0
- package/dist/cockpit-web/index.html +979 -0
- package/dist/core/cockpit-api.d.ts +99 -0
- package/dist/core/cockpit-api.d.ts.map +1 -0
- package/dist/core/cockpit-api.js +269 -0
- package/dist/core/cockpit-api.js.map +1 -0
- package/dist/core/cockpit-repl.d.ts +51 -0
- package/dist/core/cockpit-repl.d.ts.map +1 -0
- package/dist/core/cockpit-repl.js +217 -0
- package/dist/core/cockpit-repl.js.map +1 -0
- package/dist/core/contrast-usage-probe.d.ts +84 -0
- package/dist/core/contrast-usage-probe.d.ts.map +1 -0
- package/dist/core/contrast-usage-probe.js +244 -0
- package/dist/core/contrast-usage-probe.js.map +1 -0
- package/dist/core/contrast-usage-probe.test.d.ts +2 -0
- package/dist/core/contrast-usage-probe.test.d.ts.map +1 -0
- package/dist/core/contrast-usage-probe.test.js +186 -0
- package/dist/core/contrast-usage-probe.test.js.map +1 -0
- package/dist/core/intent-parser.d.ts +67 -0
- package/dist/core/intent-parser.d.ts.map +1 -0
- package/dist/core/intent-parser.js +485 -0
- package/dist/core/intent-parser.js.map +1 -0
- package/dist/core/openrouter-client.d.ts +38 -0
- package/dist/core/openrouter-client.d.ts.map +1 -0
- package/dist/core/openrouter-client.js +123 -0
- package/dist/core/openrouter-client.js.map +1 -0
- package/dist/core/page-status.d.ts +15 -1
- package/dist/core/page-status.d.ts.map +1 -1
- package/dist/core/page-status.js +21 -0
- package/dist/core/page-status.js.map +1 -1
- package/dist/core/project-adapter.d.ts +73 -0
- package/dist/core/project-adapter.d.ts.map +1 -0
- package/dist/core/project-adapter.js +364 -0
- package/dist/core/project-adapter.js.map +1 -0
- package/dist/core/schema-export.d.ts +32 -0
- package/dist/core/schema-export.d.ts.map +1 -0
- package/dist/core/schema-export.js +493 -0
- package/dist/core/schema-export.js.map +1 -0
- package/dist/core/theme-audit.d.ts +104 -0
- package/dist/core/theme-audit.d.ts.map +1 -0
- package/dist/core/theme-audit.js +127 -0
- package/dist/core/theme-audit.js.map +1 -0
- package/dist/core/theme-audit.test.d.ts +2 -0
- package/dist/core/theme-audit.test.d.ts.map +1 -0
- package/dist/core/theme-audit.test.js +198 -0
- package/dist/core/theme-audit.test.js.map +1 -0
- package/dist/core/url-import.d.ts +41 -0
- package/dist/core/url-import.d.ts.map +1 -0
- package/dist/core/url-import.js +207 -0
- package/dist/core/url-import.js.map +1 -0
- package/dist/core/video-import.d.ts +46 -0
- package/dist/core/video-import.d.ts.map +1 -0
- package/dist/core/video-import.js +192 -0
- package/dist/core/video-import.js.map +1 -0
- package/dist/core/visual-import.d.ts +42 -0
- package/dist/core/visual-import.d.ts.map +1 -0
- package/dist/core/visual-import.js +227 -0
- package/dist/core/visual-import.js.map +1 -0
- package/dist/index.d.ts +25 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +32 -0
- package/dist/mcp/index.js.map +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cockpit-repl.js","sourceRoot":"","sources":["../../src/core/cockpit-repl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contrast Usage Probe — static CSS analysis for unremediated text variables.
|
|
3
|
+
*
|
|
4
|
+
* Scans CSS to find text/accent CSS variables used in selectors that could
|
|
5
|
+
* render on light surfaces WITHOUT being remapped by a surface-aware override.
|
|
6
|
+
*
|
|
7
|
+
* Catches: `.card-desc { color: var(--text-secondary) }` used inside
|
|
8
|
+
* `.valentino-section-shell[data-surface='default']` where --text-secondary
|
|
9
|
+
* is NOT remapped to a surface-safe value.
|
|
10
|
+
*
|
|
11
|
+
* Pure function, zero DOM.
|
|
12
|
+
*/
|
|
13
|
+
export type ContrastUsageWarning = {
|
|
14
|
+
/** CSS variable used as foreground color */
|
|
15
|
+
token: string;
|
|
16
|
+
/** The CSS selector where it's used */
|
|
17
|
+
selector: string;
|
|
18
|
+
/** Line number in the CSS file */
|
|
19
|
+
line: number;
|
|
20
|
+
/** Surfaces where the token is NOT remapped */
|
|
21
|
+
unremappedSurfaces: string[];
|
|
22
|
+
/** Severity: error if used on light surfaces without remap */
|
|
23
|
+
severity: 'warning' | 'error';
|
|
24
|
+
message: string;
|
|
25
|
+
};
|
|
26
|
+
export type ContrastUsageProbeResult = {
|
|
27
|
+
warnings: ContrastUsageWarning[];
|
|
28
|
+
/** Tokens that ARE properly remapped per surface */
|
|
29
|
+
remappedTokens: Map<string, string[]>;
|
|
30
|
+
valid: boolean;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Parse which tokens are remapped in each surface block.
|
|
34
|
+
* Returns: Map<tokenName, surfaceName[]>
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseRemappedTokens(css: string): Map<string, string[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Find all text/accent CSS variable usages outside of surface remap blocks.
|
|
39
|
+
* Returns: Array of {token, selector, line}
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseTextTokenUsages(css: string): Array<{
|
|
42
|
+
token: string;
|
|
43
|
+
selector: string;
|
|
44
|
+
line: number;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Probe CSS for text/accent variables that are used on elements which could
|
|
48
|
+
* appear inside light surfaces, but are NOT remapped in those surface blocks.
|
|
49
|
+
*
|
|
50
|
+
* @param css - Full CSS content (e.g., framework.css)
|
|
51
|
+
* @param options.textTokens - Specific tokens to check. If omitted, discovers all var(--text-*) usages.
|
|
52
|
+
*/
|
|
53
|
+
export declare function probeContrastUsage(css: string): ContrastUsageProbeResult;
|
|
54
|
+
/**
|
|
55
|
+
* Extract CSS from Shadow DOM Web Component source files.
|
|
56
|
+
* Looks for tagged template literals containing <style> blocks,
|
|
57
|
+
* which is the standard pattern for Lit/vanilla Shadow DOM components.
|
|
58
|
+
*
|
|
59
|
+
* Returns array of { componentName, css } for each component found.
|
|
60
|
+
*/
|
|
61
|
+
export declare function extractShadowDomStyles(source: string, fileName?: string): Array<{
|
|
62
|
+
componentName: string;
|
|
63
|
+
css: string;
|
|
64
|
+
}>;
|
|
65
|
+
export type ContrastUsageMultiResult = {
|
|
66
|
+
/** Combined warnings from all sources */
|
|
67
|
+
warnings: ContrastUsageWarning[];
|
|
68
|
+
/** Per-source results for reporting */
|
|
69
|
+
sources: Array<{
|
|
70
|
+
source: string;
|
|
71
|
+
warningCount: number;
|
|
72
|
+
}>;
|
|
73
|
+
valid: boolean;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Probe multiple CSS sources at once (framework.css + Shadow DOM components).
|
|
77
|
+
* Surface remaps are read from the primary CSS (framework.css).
|
|
78
|
+
* Token usages are collected from ALL sources (framework + components).
|
|
79
|
+
*/
|
|
80
|
+
export declare function probeContrastUsageMulti(primaryCss: string, additionalSources?: Array<{
|
|
81
|
+
name: string;
|
|
82
|
+
css: string;
|
|
83
|
+
}>): ContrastUsageMultiResult;
|
|
84
|
+
//# sourceMappingURL=contrast-usage-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contrast-usage-probe.d.ts","sourceRoot":"","sources":["../../src/core/contrast-usage-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,MAAM,oBAAoB,GAAG;IAC/B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACnC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,oDAAoD;IACpD,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,KAAK,EAAE,OAAO,CAAC;CAClB,CAAC;AA6CF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAoBtE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA0D1G;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,wBAAwB,CAuCxE;AAID;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAClB,KAAK,CAAC;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAc/C;AAID,MAAM,MAAM,wBAAwB,GAAG;IACnC,yCAAyC;IACzC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,uCAAuC;IACvC,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,KAAK,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,GACzD,wBAAwB,CAiD1B"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contrast Usage Probe — static CSS analysis for unremediated text variables.
|
|
3
|
+
*
|
|
4
|
+
* Scans CSS to find text/accent CSS variables used in selectors that could
|
|
5
|
+
* render on light surfaces WITHOUT being remapped by a surface-aware override.
|
|
6
|
+
*
|
|
7
|
+
* Catches: `.card-desc { color: var(--text-secondary) }` used inside
|
|
8
|
+
* `.valentino-section-shell[data-surface='default']` where --text-secondary
|
|
9
|
+
* is NOT remapped to a surface-safe value.
|
|
10
|
+
*
|
|
11
|
+
* Pure function, zero DOM.
|
|
12
|
+
*/
|
|
13
|
+
import { inferTokenRole } from './theme-audit.js';
|
|
14
|
+
// ── Surface detection ────────────────────────────────────────────────────────
|
|
15
|
+
const LIGHT_SURFACES = ['default', 'muted', 'accent', 'reading-light', 'ops-light'];
|
|
16
|
+
const DARK_SURFACES = ['dark', 'shell-dark'];
|
|
17
|
+
/** Pattern to find surface-scoped blocks that remap a variable */
|
|
18
|
+
const SURFACE_REMAP_RE = /\.valentino-section-shell\[data-surface=['"]([^'"]+)['"]\]\s*\{([^}]+)\}/g;
|
|
19
|
+
/** Pattern to find var(--token) usage in CSS property values */
|
|
20
|
+
const VAR_USAGE_RE = /:\s*var\((--[a-z][a-z0-9-]*)\)/g;
|
|
21
|
+
/** Pattern to find rgba(var(--rgb-*), alpha) usage — common for glow/shadow on interactive states */
|
|
22
|
+
const RGBA_VAR_USAGE_RE = /rgba\(\s*var\((--rgb-[a-z][a-z0-9-]*)\)/g;
|
|
23
|
+
/**
|
|
24
|
+
* Tokens that contain "text" or "font" in their name but are NOT colors.
|
|
25
|
+
* These are size/typography tokens and should be excluded from contrast checks.
|
|
26
|
+
*/
|
|
27
|
+
function isNonColorToken(token) {
|
|
28
|
+
const lower = token.toLowerCase();
|
|
29
|
+
// Font family, size steps, line heights, letter spacing
|
|
30
|
+
if (lower.includes('font-family') || lower.includes('font-size') || lower.includes('font-weight'))
|
|
31
|
+
return true;
|
|
32
|
+
if (/--text-step-\d/.test(lower))
|
|
33
|
+
return true;
|
|
34
|
+
if (lower.includes('leading') || lower.includes('tracking') || lower.includes('measure'))
|
|
35
|
+
return true;
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Tokens scoped to a specific surface kind in their name (e.g., --action-widget-dark-*)
|
|
40
|
+
* should not be checked against the opposite surface kind.
|
|
41
|
+
*/
|
|
42
|
+
function isSurfaceScopedToken(token) {
|
|
43
|
+
const lower = token.toLowerCase();
|
|
44
|
+
if (lower.includes('-dark-'))
|
|
45
|
+
return 'dark';
|
|
46
|
+
if (lower.includes('-light-'))
|
|
47
|
+
return 'light';
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
/** Pattern to find variable definitions (--token: value) */
|
|
51
|
+
const VAR_DEFINE_RE = /(--[a-z][a-z0-9-]*):\s*var\((--[a-z][a-z0-9-]*)\)|(-[a-z][a-z0-9-]*):\s*([^;]+)/g;
|
|
52
|
+
// ── Core probe ───────────────────────────────────────────────────────────────
|
|
53
|
+
/**
|
|
54
|
+
* Parse which tokens are remapped in each surface block.
|
|
55
|
+
* Returns: Map<tokenName, surfaceName[]>
|
|
56
|
+
*/
|
|
57
|
+
export function parseRemappedTokens(css) {
|
|
58
|
+
const remaps = new Map();
|
|
59
|
+
let match;
|
|
60
|
+
SURFACE_REMAP_RE.lastIndex = 0;
|
|
61
|
+
while ((match = SURFACE_REMAP_RE.exec(css)) !== null) {
|
|
62
|
+
const surfaceName = match[1];
|
|
63
|
+
const blockContent = match[2];
|
|
64
|
+
// Find all variable definitions in this surface block
|
|
65
|
+
const defRe = /(--[a-z][a-z0-9-]*):/g;
|
|
66
|
+
let defMatch;
|
|
67
|
+
while ((defMatch = defRe.exec(blockContent)) !== null) {
|
|
68
|
+
const token = defMatch[1];
|
|
69
|
+
if (!remaps.has(token))
|
|
70
|
+
remaps.set(token, []);
|
|
71
|
+
remaps.get(token).push(surfaceName);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return remaps;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Find all text/accent CSS variable usages outside of surface remap blocks.
|
|
78
|
+
* Returns: Array of {token, selector, line}
|
|
79
|
+
*/
|
|
80
|
+
export function parseTextTokenUsages(css) {
|
|
81
|
+
const usages = [];
|
|
82
|
+
const lines = css.split('\n');
|
|
83
|
+
// Track which line ranges are inside surface remap blocks (skip those)
|
|
84
|
+
const surfaceBlockRanges = [];
|
|
85
|
+
SURFACE_REMAP_RE.lastIndex = 0;
|
|
86
|
+
let blockMatch;
|
|
87
|
+
while ((blockMatch = SURFACE_REMAP_RE.exec(css)) !== null) {
|
|
88
|
+
const startOffset = blockMatch.index;
|
|
89
|
+
const endOffset = startOffset + blockMatch[0].length;
|
|
90
|
+
const startLine = css.substring(0, startOffset).split('\n').length;
|
|
91
|
+
const endLine = css.substring(0, endOffset).split('\n').length;
|
|
92
|
+
surfaceBlockRanges.push({ start: startLine, end: endLine });
|
|
93
|
+
}
|
|
94
|
+
function isInsideSurfaceBlock(lineNum) {
|
|
95
|
+
return surfaceBlockRanges.some(r => lineNum >= r.start && lineNum <= r.end);
|
|
96
|
+
}
|
|
97
|
+
// Simple CSS selector tracker
|
|
98
|
+
let currentSelector = '';
|
|
99
|
+
for (let i = 0; i < lines.length; i++) {
|
|
100
|
+
const lineNum = i + 1;
|
|
101
|
+
const line = lines[i].trim();
|
|
102
|
+
// Skip lines inside surface remap blocks
|
|
103
|
+
if (isInsideSurfaceBlock(lineNum))
|
|
104
|
+
continue;
|
|
105
|
+
// Track selectors (crude but effective for this purpose)
|
|
106
|
+
if (line.includes('{') && !line.startsWith('/*')) {
|
|
107
|
+
currentSelector = line.replace(/\s*\{.*/, '').trim();
|
|
108
|
+
}
|
|
109
|
+
// Find var(--token) usages
|
|
110
|
+
VAR_USAGE_RE.lastIndex = 0;
|
|
111
|
+
let varMatch;
|
|
112
|
+
while ((varMatch = VAR_USAGE_RE.exec(line)) !== null) {
|
|
113
|
+
const token = varMatch[1];
|
|
114
|
+
if (isNonColorToken(token))
|
|
115
|
+
continue;
|
|
116
|
+
const role = inferTokenRole(token);
|
|
117
|
+
if (role === 'text' || role === 'accent') {
|
|
118
|
+
usages.push({ token, selector: currentSelector, line: lineNum });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Also catch rgba(var(--rgb-*)) pattern — map --rgb-X to its parent --X token
|
|
122
|
+
RGBA_VAR_USAGE_RE.lastIndex = 0;
|
|
123
|
+
let rgbaMatch;
|
|
124
|
+
while ((rgbaMatch = RGBA_VAR_USAGE_RE.exec(line)) !== null) {
|
|
125
|
+
const rgbToken = rgbaMatch[1]; // e.g. --rgb-neural-cyan
|
|
126
|
+
// Infer the parent token: --rgb-neural-cyan → --accent-neural-cyan
|
|
127
|
+
// These are used in color/background contexts so they're accent-like
|
|
128
|
+
usages.push({ token: rgbToken, selector: currentSelector, line: lineNum });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return usages;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Probe CSS for text/accent variables that are used on elements which could
|
|
135
|
+
* appear inside light surfaces, but are NOT remapped in those surface blocks.
|
|
136
|
+
*
|
|
137
|
+
* @param css - Full CSS content (e.g., framework.css)
|
|
138
|
+
* @param options.textTokens - Specific tokens to check. If omitted, discovers all var(--text-*) usages.
|
|
139
|
+
*/
|
|
140
|
+
export function probeContrastUsage(css) {
|
|
141
|
+
const remappedTokens = parseRemappedTokens(css);
|
|
142
|
+
const usages = parseTextTokenUsages(css);
|
|
143
|
+
const warnings = [];
|
|
144
|
+
// For each text token usage, check if it's remapped in all light surfaces
|
|
145
|
+
const checkedTokens = new Set();
|
|
146
|
+
for (const usage of usages) {
|
|
147
|
+
// Only warn once per token (not per usage)
|
|
148
|
+
if (checkedTokens.has(usage.token))
|
|
149
|
+
continue;
|
|
150
|
+
checkedTokens.add(usage.token);
|
|
151
|
+
const remappedIn = remappedTokens.get(usage.token) ?? [];
|
|
152
|
+
// Skip tokens scoped to a specific surface kind (e.g., --action-widget-dark-text)
|
|
153
|
+
const scopedKind = isSurfaceScopedToken(usage.token);
|
|
154
|
+
if (scopedKind === 'dark')
|
|
155
|
+
continue; // Dark-scoped tokens don't need light remaps
|
|
156
|
+
const surfacesToCheck = scopedKind === 'light' ? LIGHT_SURFACES : LIGHT_SURFACES;
|
|
157
|
+
const missingLightSurfaces = surfacesToCheck.filter(s => !remappedIn.includes(s));
|
|
158
|
+
if (missingLightSurfaces.length > 0) {
|
|
159
|
+
warnings.push({
|
|
160
|
+
token: usage.token,
|
|
161
|
+
selector: usage.selector,
|
|
162
|
+
line: usage.line,
|
|
163
|
+
unremappedSurfaces: missingLightSurfaces,
|
|
164
|
+
severity: 'error',
|
|
165
|
+
message: `"${usage.token}" used in "${usage.selector}" (line ${usage.line}) is not remapped in light surfaces: ${missingLightSurfaces.join(', ')}. Text may be invisible on white backgrounds.`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
warnings,
|
|
171
|
+
remappedTokens,
|
|
172
|
+
valid: warnings.length === 0,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// ── Shadow DOM extraction ────────────────────────────────────────────────────
|
|
176
|
+
/**
|
|
177
|
+
* Extract CSS from Shadow DOM Web Component source files.
|
|
178
|
+
* Looks for tagged template literals containing <style> blocks,
|
|
179
|
+
* which is the standard pattern for Lit/vanilla Shadow DOM components.
|
|
180
|
+
*
|
|
181
|
+
* Returns array of { componentName, css } for each component found.
|
|
182
|
+
*/
|
|
183
|
+
export function extractShadowDomStyles(source, fileName) {
|
|
184
|
+
const results = [];
|
|
185
|
+
// Match <style>...</style> inside template literals
|
|
186
|
+
const styleRe = /<style>([\s\S]*?)<\/style>/g;
|
|
187
|
+
let match;
|
|
188
|
+
while ((match = styleRe.exec(source)) !== null) {
|
|
189
|
+
results.push({
|
|
190
|
+
componentName: fileName ?? 'unknown-component',
|
|
191
|
+
css: match[1],
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
return results;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Probe multiple CSS sources at once (framework.css + Shadow DOM components).
|
|
198
|
+
* Surface remaps are read from the primary CSS (framework.css).
|
|
199
|
+
* Token usages are collected from ALL sources (framework + components).
|
|
200
|
+
*/
|
|
201
|
+
export function probeContrastUsageMulti(primaryCss, additionalSources) {
|
|
202
|
+
// Remaps only come from the primary CSS (framework.css has the surface blocks)
|
|
203
|
+
const remappedTokens = parseRemappedTokens(primaryCss);
|
|
204
|
+
// Collect usages from all sources
|
|
205
|
+
const allSources = [
|
|
206
|
+
{ name: 'framework.css', css: primaryCss },
|
|
207
|
+
...(additionalSources ?? []),
|
|
208
|
+
];
|
|
209
|
+
const warnings = [];
|
|
210
|
+
const checkedTokens = new Set();
|
|
211
|
+
const sourceSummary = [];
|
|
212
|
+
for (const { name, css } of allSources) {
|
|
213
|
+
const usages = parseTextTokenUsages(css);
|
|
214
|
+
let sourceWarnings = 0;
|
|
215
|
+
for (const usage of usages) {
|
|
216
|
+
if (checkedTokens.has(usage.token))
|
|
217
|
+
continue;
|
|
218
|
+
checkedTokens.add(usage.token);
|
|
219
|
+
const remappedIn = remappedTokens.get(usage.token) ?? [];
|
|
220
|
+
const scopedKind = isSurfaceScopedToken(usage.token);
|
|
221
|
+
if (scopedKind === 'dark')
|
|
222
|
+
continue;
|
|
223
|
+
const missingLightSurfaces = LIGHT_SURFACES.filter(s => !remappedIn.includes(s));
|
|
224
|
+
if (missingLightSurfaces.length > 0) {
|
|
225
|
+
sourceWarnings++;
|
|
226
|
+
warnings.push({
|
|
227
|
+
token: usage.token,
|
|
228
|
+
selector: usage.selector,
|
|
229
|
+
line: usage.line,
|
|
230
|
+
unremappedSurfaces: missingLightSurfaces,
|
|
231
|
+
severity: 'error',
|
|
232
|
+
message: `[${name}] "${usage.token}" used in "${usage.selector}" (line ${usage.line}) is not remapped in light surfaces: ${missingLightSurfaces.join(', ')}`,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
sourceSummary.push({ source: name, warningCount: sourceWarnings });
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
warnings,
|
|
240
|
+
sources: sourceSummary,
|
|
241
|
+
valid: warnings.length === 0,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=contrast-usage-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contrast-usage-probe.js","sourceRoot":"","sources":["../../src/core/contrast-usage-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAyBlD,gFAAgF;AAEhF,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC;AACpF,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAE7C,kEAAkE;AAClE,MAAM,gBAAgB,GAAG,2EAA2E,CAAC;AAErG,gEAAgE;AAChE,MAAM,YAAY,GAAG,iCAAiC,CAAC;AAEvD,qGAAqG;AACrG,MAAM,iBAAiB,GAAG,0CAA0C,CAAC;AAErE;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,wDAAwD;IACxD,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/G,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACtG,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,KAAa;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5C,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,OAAO,CAAC;IAC9C,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,4DAA4D;AAC5D,MAAM,aAAa,GAAG,kFAAkF,CAAC;AAEzG,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE3C,IAAI,KAAK,CAAC;IACV,gBAAgB,CAAC,SAAS,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAE9B,sDAAsD;QACtD,MAAM,KAAK,GAAG,uBAAuB,CAAC;QACtC,IAAI,QAAQ,CAAC;QACb,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC5C,MAAM,MAAM,GAA6D,EAAE,CAAC;IAC5E,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE9B,uEAAuE;IACvE,MAAM,kBAAkB,GAA0C,EAAE,CAAC;IACrE,gBAAgB,CAAC,SAAS,GAAG,CAAC,CAAC;IAC/B,IAAI,UAAU,CAAC;IACf,OAAO,CAAC,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACxD,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC;QACrC,MAAM,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACrD,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QACnE,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC/D,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,SAAS,oBAAoB,CAAC,OAAe;QACzC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAChF,CAAC;IAED,8BAA8B;IAC9B,IAAI,eAAe,GAAG,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE7B,yCAAyC;QACzC,IAAI,oBAAoB,CAAC,OAAO,CAAC;YAAE,SAAS;QAE5C,yDAAyD;QACzD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzD,CAAC;QAED,2BAA2B;QAC3B,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC;QAC3B,IAAI,QAAQ,CAAC;QACb,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,eAAe,CAAC,KAAK,CAAC;gBAAE,SAAS;YACrC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC;QACL,CAAC;QAED,8EAA8E;QAC9E,iBAAiB,CAAC,SAAS,GAAG,CAAC,CAAC;QAChC,IAAI,SAAS,CAAC;QACd,OAAO,CAAC,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACzD,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,yBAAyB;YACxD,mEAAmE;YACnE,qEAAqE;YACrE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC1C,MAAM,cAAc,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAE5C,0EAA0E;IAC1E,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACzB,2CAA2C;QAC3C,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,SAAS;QAC7C,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE/B,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAEzD,kFAAkF;QAClF,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,UAAU,KAAK,MAAM;YAAE,SAAS,CAAC,6CAA6C;QAClF,MAAM,eAAe,GAAG,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC;QAEjF,MAAM,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAElF,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC;gBACV,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,kBAAkB,EAAE,oBAAoB;gBACxC,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,IAAI,KAAK,CAAC,KAAK,cAAc,KAAK,CAAC,QAAQ,WAAW,KAAK,CAAC,IAAI,wCAAwC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,+CAA+C;aAClM,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO;QACH,QAAQ;QACR,cAAc;QACd,KAAK,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;KAC/B,CAAC;AACN,CAAC;AAED,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAClC,MAAc,EACd,QAAiB;IAEjB,MAAM,OAAO,GAAkD,EAAE,CAAC;IAElE,oDAAoD;IACpD,MAAM,OAAO,GAAG,6BAA6B,CAAC;IAC9C,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC;YACT,aAAa,EAAE,QAAQ,IAAI,mBAAmB;YAC9C,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;SAChB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAYD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACnC,UAAkB,EAClB,iBAAwD;IAExD,+EAA+E;IAC/E,MAAM,cAAc,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAEvD,kCAAkC;IAClC,MAAM,UAAU,GAAG;QACf,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,EAAE;QAC1C,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;KAC/B,CAAC;IAEF,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,MAAM,aAAa,GAAoD,EAAE,CAAC;IAE1E,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,UAAU,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC7C,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAE/B,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrD,IAAI,UAAU,KAAK,MAAM;gBAAE,SAAS;YAEpC,MAAM,oBAAoB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAEjF,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,cAAc,EAAE,CAAC;gBACjB,QAAQ,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,kBAAkB,EAAE,oBAAoB;oBACxC,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,IAAI,IAAI,MAAM,KAAK,CAAC,KAAK,cAAc,KAAK,CAAC,QAAQ,WAAW,KAAK,CAAC,IAAI,wCAAwC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC/J,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACH,QAAQ;QACR,OAAO,EAAE,aAAa;QACtB,KAAK,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;KAC/B,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contrast-usage-probe.test.d.ts","sourceRoot":"","sources":["../../src/core/contrast-usage-probe.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { probeContrastUsage, probeContrastUsageMulti, parseRemappedTokens, parseTextTokenUsages, extractShadowDomStyles, } from './contrast-usage-probe.js';
|
|
3
|
+
// ── parseRemappedTokens ──────────────────────────────────────────────────────
|
|
4
|
+
describe('parseRemappedTokens', () => {
|
|
5
|
+
it('detects tokens remapped in surface blocks', () => {
|
|
6
|
+
const css = `
|
|
7
|
+
.valentino-section-shell[data-surface='default'] {
|
|
8
|
+
--valentino-surface-bg: #ffffff;
|
|
9
|
+
--text-secondary: var(--valentino-surface-default-text-muted);
|
|
10
|
+
}
|
|
11
|
+
.valentino-section-shell[data-surface='muted'] {
|
|
12
|
+
--text-secondary: var(--valentino-surface-muted-text-muted);
|
|
13
|
+
}`;
|
|
14
|
+
const result = parseRemappedTokens(css);
|
|
15
|
+
expect(result.get('--text-secondary')).toContain('default');
|
|
16
|
+
expect(result.get('--text-secondary')).toContain('muted');
|
|
17
|
+
});
|
|
18
|
+
it('returns empty map for CSS without surface blocks', () => {
|
|
19
|
+
const css = `.nav-links a { color: var(--text-secondary); }`;
|
|
20
|
+
const result = parseRemappedTokens(css);
|
|
21
|
+
expect(result.size).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
// ── parseTextTokenUsages ─────────────────────────────────────────────────────
|
|
25
|
+
describe('parseTextTokenUsages', () => {
|
|
26
|
+
it('finds text token usages outside surface blocks', () => {
|
|
27
|
+
const css = `.nav-links a { color: var(--text-secondary); }`;
|
|
28
|
+
const usages = parseTextTokenUsages(css);
|
|
29
|
+
expect(usages).toHaveLength(1);
|
|
30
|
+
expect(usages[0].token).toBe('--text-secondary');
|
|
31
|
+
});
|
|
32
|
+
it('skips usages inside surface remap blocks', () => {
|
|
33
|
+
const css = `
|
|
34
|
+
.valentino-section-shell[data-surface='default'] {
|
|
35
|
+
--text-secondary: var(--valentino-surface-default-text-muted);
|
|
36
|
+
}
|
|
37
|
+
.card-desc { color: var(--text-secondary); }`;
|
|
38
|
+
const usages = parseTextTokenUsages(css);
|
|
39
|
+
// Only the .card-desc usage, not the remap inside the surface block
|
|
40
|
+
expect(usages).toHaveLength(1);
|
|
41
|
+
expect(usages[0].selector).toContain('card-desc');
|
|
42
|
+
});
|
|
43
|
+
it('ignores background tokens', () => {
|
|
44
|
+
const css = `.hero { background: var(--bg-deep-void); }`;
|
|
45
|
+
const usages = parseTextTokenUsages(css);
|
|
46
|
+
expect(usages).toHaveLength(0);
|
|
47
|
+
});
|
|
48
|
+
it('finds accent tokens', () => {
|
|
49
|
+
const css = `.link:hover { color: var(--accent-neural-cyan); }`;
|
|
50
|
+
const usages = parseTextTokenUsages(css);
|
|
51
|
+
expect(usages).toHaveLength(1);
|
|
52
|
+
expect(usages[0].token).toBe('--accent-neural-cyan');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
// ── probeContrastUsage ───────────────────────────────────────────────────────
|
|
56
|
+
describe('probeContrastUsage', () => {
|
|
57
|
+
it('warns when --text-secondary is used but not remapped in light surfaces', () => {
|
|
58
|
+
const css = `
|
|
59
|
+
.valentino-section-shell[data-surface='default'] {
|
|
60
|
+
--valentino-surface-bg: #ffffff;
|
|
61
|
+
--valentino-surface-text: #0f172a;
|
|
62
|
+
}
|
|
63
|
+
.nav-links a { color: var(--text-secondary); }`;
|
|
64
|
+
const result = probeContrastUsage(css);
|
|
65
|
+
expect(result.valid).toBe(false);
|
|
66
|
+
expect(result.warnings).toHaveLength(1);
|
|
67
|
+
expect(result.warnings[0].token).toBe('--text-secondary');
|
|
68
|
+
expect(result.warnings[0].unremappedSurfaces).toContain('default');
|
|
69
|
+
});
|
|
70
|
+
it('passes when --text-secondary is remapped in all light surfaces', () => {
|
|
71
|
+
const css = `
|
|
72
|
+
.valentino-section-shell[data-surface='default'] { --text-secondary: #475569; }
|
|
73
|
+
.valentino-section-shell[data-surface='muted'] { --text-secondary: #475569; }
|
|
74
|
+
.valentino-section-shell[data-surface='accent'] { --text-secondary: #4b5563; }
|
|
75
|
+
.valentino-section-shell[data-surface='reading-light'] { --text-secondary: #334155; }
|
|
76
|
+
.valentino-section-shell[data-surface='ops-light'] { --text-secondary: #475569; }
|
|
77
|
+
.nav-links a { color: var(--text-secondary); }`;
|
|
78
|
+
const result = probeContrastUsage(css);
|
|
79
|
+
expect(result.valid).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
it('warns for multiple tokens independently', () => {
|
|
82
|
+
const css = `
|
|
83
|
+
.hero h1 { color: var(--text-primary); }
|
|
84
|
+
.card-desc { color: var(--text-secondary); }`;
|
|
85
|
+
const result = probeContrastUsage(css);
|
|
86
|
+
expect(result.warnings).toHaveLength(2);
|
|
87
|
+
const tokens = result.warnings.map(w => w.token);
|
|
88
|
+
expect(tokens).toContain('--text-primary');
|
|
89
|
+
expect(tokens).toContain('--text-secondary');
|
|
90
|
+
});
|
|
91
|
+
it('only warns once per token even if used multiple times', () => {
|
|
92
|
+
const css = `
|
|
93
|
+
.nav-links a { color: var(--text-secondary); }
|
|
94
|
+
.card-desc { color: var(--text-secondary); }
|
|
95
|
+
.hero p.tagline { color: var(--text-secondary); }`;
|
|
96
|
+
const result = probeContrastUsage(css);
|
|
97
|
+
expect(result.warnings).toHaveLength(1);
|
|
98
|
+
});
|
|
99
|
+
it('no warnings for CSS with no text token usage', () => {
|
|
100
|
+
const css = `.hero { background: var(--bg-deep-void); padding: 2rem; }`;
|
|
101
|
+
const result = probeContrastUsage(css);
|
|
102
|
+
expect(result.valid).toBe(true);
|
|
103
|
+
expect(result.warnings).toHaveLength(0);
|
|
104
|
+
});
|
|
105
|
+
it('catches rgba(var(--rgb-*)) pattern used in hover states', () => {
|
|
106
|
+
const css = `.btn:hover { box-shadow: 0 0 10px rgba(var(--rgb-neural-cyan), 0.4); }`;
|
|
107
|
+
const result = probeContrastUsage(css);
|
|
108
|
+
const rgbWarnings = result.warnings.filter(w => w.token === '--rgb-neural-cyan');
|
|
109
|
+
expect(rgbWarnings.length).toBeGreaterThan(0);
|
|
110
|
+
});
|
|
111
|
+
it('skips dark-scoped tokens even with rgba pattern', () => {
|
|
112
|
+
const css = `.widget { color: var(--action-widget-dark-text); }`;
|
|
113
|
+
const result = probeContrastUsage(css);
|
|
114
|
+
const darkWarnings = result.warnings.filter(w => w.token === '--action-widget-dark-text');
|
|
115
|
+
expect(darkWarnings).toHaveLength(0);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
// ── extractShadowDomStyles ───────────────────────────────────────────────────
|
|
119
|
+
describe('extractShadowDomStyles', () => {
|
|
120
|
+
it('extracts CSS from <style> blocks in template literals', () => {
|
|
121
|
+
const source = `
|
|
122
|
+
class MyComponent extends HTMLElement {
|
|
123
|
+
connectedCallback() {
|
|
124
|
+
this.attachShadow({ mode: 'open' });
|
|
125
|
+
this.shadowRoot.innerHTML = \`
|
|
126
|
+
<style>
|
|
127
|
+
.footer-col a { color: var(--text-secondary); }
|
|
128
|
+
.footer-col a:hover { color: var(--accent-neural-cyan); }
|
|
129
|
+
</style>
|
|
130
|
+
<div class="footer-col"><a href="/">Home</a></div>
|
|
131
|
+
\`;
|
|
132
|
+
}
|
|
133
|
+
}`;
|
|
134
|
+
const styles = extractShadowDomStyles(source, 'my-component.ts');
|
|
135
|
+
expect(styles).toHaveLength(1);
|
|
136
|
+
expect(styles[0].componentName).toBe('my-component.ts');
|
|
137
|
+
expect(styles[0].css).toContain('--text-secondary');
|
|
138
|
+
expect(styles[0].css).toContain('--accent-neural-cyan');
|
|
139
|
+
});
|
|
140
|
+
it('extracts multiple <style> blocks', () => {
|
|
141
|
+
const source = `
|
|
142
|
+
<style>.a { color: var(--text-primary); }</style>
|
|
143
|
+
<style>.b { color: var(--text-secondary); }</style>
|
|
144
|
+
`;
|
|
145
|
+
const styles = extractShadowDomStyles(source, 'multi.ts');
|
|
146
|
+
expect(styles).toHaveLength(2);
|
|
147
|
+
});
|
|
148
|
+
it('returns empty for files without <style> blocks', () => {
|
|
149
|
+
const source = `export function helper() { return 42; }`;
|
|
150
|
+
expect(extractShadowDomStyles(source)).toEqual([]);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
// ── probeContrastUsageMulti ──────────────────────────────────────────────────
|
|
154
|
+
describe('probeContrastUsageMulti', () => {
|
|
155
|
+
const primaryCss = `
|
|
156
|
+
.valentino-section-shell[data-surface='default'] {
|
|
157
|
+
--valentino-surface-bg: #ffffff;
|
|
158
|
+
}
|
|
159
|
+
.nav-links a { color: var(--text-secondary); }`;
|
|
160
|
+
it('finds warnings from primary CSS', () => {
|
|
161
|
+
const result = probeContrastUsageMulti(primaryCss);
|
|
162
|
+
expect(result.warnings.length).toBeGreaterThan(0);
|
|
163
|
+
expect(result.sources).toHaveLength(1);
|
|
164
|
+
});
|
|
165
|
+
it('finds warnings from additional Shadow DOM sources', () => {
|
|
166
|
+
const componentCss = `.footer-col a { color: var(--text-muted); }`;
|
|
167
|
+
const result = probeContrastUsageMulti(primaryCss, [
|
|
168
|
+
{ name: 'sovereign-footer.ts', css: componentCss },
|
|
169
|
+
]);
|
|
170
|
+
// --text-secondary from primary + --text-muted from component
|
|
171
|
+
const tokens = result.warnings.map(w => w.token);
|
|
172
|
+
expect(tokens).toContain('--text-secondary');
|
|
173
|
+
expect(tokens).toContain('--text-muted');
|
|
174
|
+
expect(result.sources).toHaveLength(2);
|
|
175
|
+
});
|
|
176
|
+
it('deduplicates tokens across sources', () => {
|
|
177
|
+
const componentCss = `.link { color: var(--text-secondary); }`;
|
|
178
|
+
const result = probeContrastUsageMulti(primaryCss, [
|
|
179
|
+
{ name: 'component.ts', css: componentCss },
|
|
180
|
+
]);
|
|
181
|
+
// --text-secondary appears in both but should warn only once
|
|
182
|
+
const textSecWarnings = result.warnings.filter(w => w.token === '--text-secondary');
|
|
183
|
+
expect(textSecWarnings).toHaveLength(1);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
//# sourceMappingURL=contrast-usage-probe.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contrast-usage-probe.test.js","sourceRoot":"","sources":["../../src/core/contrast-usage-probe.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Parser — Natural language → CockpitAction.
|
|
3
|
+
* Feature #778 (Il Sarto Parla), PBI #780 (Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* Two modes:
|
|
6
|
+
* - Local (rule-based): regex patterns for IT/EN, always works, zero API.
|
|
7
|
+
* - LLM (callback): delegates to external LLM, validates output, falls back to local.
|
|
8
|
+
*
|
|
9
|
+
* Pure functions, no I/O, no LLM client.
|
|
10
|
+
*/
|
|
11
|
+
import type { CockpitAction } from './cockpit-api.js';
|
|
12
|
+
import type { SectionSpec, PageSpecV1 } from './types.js';
|
|
13
|
+
export type ParsedIntent = {
|
|
14
|
+
action: CockpitAction;
|
|
15
|
+
confidence: 'high' | 'medium' | 'low';
|
|
16
|
+
description: string;
|
|
17
|
+
};
|
|
18
|
+
export type IntentParseResult = {
|
|
19
|
+
intent: ParsedIntent | null;
|
|
20
|
+
mode: 'local' | 'llm';
|
|
21
|
+
raw: string;
|
|
22
|
+
fallbackReason?: string;
|
|
23
|
+
};
|
|
24
|
+
export type IntentLlmCallback = (prompt: string, context: IntentLlmContext) => Promise<unknown>;
|
|
25
|
+
export type IntentLlmContext = {
|
|
26
|
+
pageSpec: PageSpecV1;
|
|
27
|
+
actionSchema: object;
|
|
28
|
+
sectionSchemas: Record<string, object>;
|
|
29
|
+
sectionSummary: Array<{
|
|
30
|
+
index: number;
|
|
31
|
+
type: string;
|
|
32
|
+
titleKey?: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
declare function resolveSectionType(raw: string): string | null;
|
|
36
|
+
declare function parseIndex(raw: string, totalSections: number): number | null;
|
|
37
|
+
declare function buildMinimalSection(sectionType: string): SectionSpec;
|
|
38
|
+
declare function buildSectionSummary(spec: PageSpecV1): Array<{
|
|
39
|
+
index: number;
|
|
40
|
+
type: string;
|
|
41
|
+
titleKey?: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Parse a natural language operator request into a CockpitAction.
|
|
45
|
+
*
|
|
46
|
+
* Supports IT and EN. If `llm` callback is provided, tries LLM first
|
|
47
|
+
* with automatic fallback to local rule-based parser.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* // Local mode
|
|
52
|
+
* const result = parseIntent("mostrami le sezioni", pageSpec);
|
|
53
|
+
*
|
|
54
|
+
* // LLM mode with fallback
|
|
55
|
+
* const result = await parseIntent("aggiungi una hero", pageSpec, myLlm);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseIntent(input: string, spec: PageSpecV1, llm?: IntentLlmCallback): Promise<IntentParseResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Synchronous local-only parsing. No LLM, always works.
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseIntentLocal(input: string, spec: PageSpecV1): IntentParseResult;
|
|
63
|
+
/**
|
|
64
|
+
* Exported for testing.
|
|
65
|
+
*/
|
|
66
|
+
export { resolveSectionType, parseIndex, buildMinimalSection, buildSectionSummary };
|
|
67
|
+
//# sourceMappingURL=intent-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent-parser.d.ts","sourceRoot":"","sources":["../../src/core/intent-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ1D,MAAM,MAAM,YAAY,GAAG;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,KACxB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,gBAAgB,GAAG;IAC3B,QAAQ,EAAE,UAAU,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,cAAc,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7E,CAAC;AAiCF,iBAAS,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAItD;AAgBD,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBrE;AAiQD,iBAAS,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAgC7D;AAyDD,iBAAS,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxG;AA4DD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,UAAU,EAChB,GAAG,CAAC,EAAE,iBAAiB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAK5B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,iBAAiB,CAEnF;AAED;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,CAAC"}
|