@bitmagic/cli 0.1.59-dev.1 → 0.1.59-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/theme.d.ts +3 -0
- package/dist/commands/theme.js +201 -0
- package/dist/commands/theme.js.map +1 -0
- package/dist/scaffold/project-files.d.ts +1 -0
- package/dist/scaffold/project-files.js +47 -1
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/project.js +2 -1
- package/dist/scaffold/project.js.map +1 -1
- package/dist/theme/hud-theme-catalog.d.ts +236 -0
- package/dist/theme/hud-theme-catalog.js +386 -0
- package/dist/theme/hud-theme-catalog.js.map +1 -0
- package/dist/theme/theme-color-math.d.ts +21 -0
- package/dist/theme/theme-color-math.js +99 -0
- package/dist/theme/theme-color-math.js.map +1 -0
- package/dist/theme/theme-io.d.ts +49 -0
- package/dist/theme/theme-io.js +190 -0
- package/dist/theme/theme-io.js.map +1 -0
- package/dist/theme/theme-merge.d.ts +36 -0
- package/dist/theme/theme-merge.js +81 -0
- package/dist/theme/theme-merge.js.map +1 -0
- package/dist/theme/theme-report.d.ts +28 -0
- package/dist/theme/theme-report.js +142 -0
- package/dist/theme/theme-report.js.map +1 -0
- package/dist/theme/theme-stored.d.ts +21 -0
- package/dist/theme/theme-stored.js +50 -0
- package/dist/theme/theme-stored.js.map +1 -0
- package/dist/theme/theme-validate.d.ts +41 -0
- package/dist/theme/theme-validate.js +406 -0
- package/dist/theme/theme-validate.js.map +1 -0
- package/dist/verify/classify.js +19 -0
- package/dist/verify/classify.js.map +1 -1
- package/dist/verify/hud-theme.d.ts +55 -0
- package/dist/verify/hud-theme.js +70 -0
- package/dist/verify/hud-theme.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The strict write-time HUD theme validator.
|
|
3
|
+
*
|
|
4
|
+
* STRICTER than the engine's load-time validator on purpose, and that asymmetry
|
|
5
|
+
* is the design: at WRITE time a bad per-element leaf is an error the agent can
|
|
6
|
+
* fix in the same turn, while at LOAD time the engine must keep rendering
|
|
7
|
+
* already-published themes, so it warns and drops the leaf instead. Everything
|
|
8
|
+
* this validator accepts, the engine accepts; the reverse is not required.
|
|
9
|
+
*
|
|
10
|
+
* This replaced `lightValidateTheme`, which skipped glow keys, every numeric
|
|
11
|
+
* range, the whole `elements` block, decoration slot suitability and decoration
|
|
12
|
+
* size/position/repeat — six ways a theme could pass the write tool and then
|
|
13
|
+
* silently render as the DEFAULT look at engine load, which reads as "theming
|
|
14
|
+
* is broken" rather than "the value was wrong". Parity with the engine is
|
|
15
|
+
* enforced by scripts/check-hud-catalog.ts, which runs both validators over a
|
|
16
|
+
* fixture corpus under tsx and compares verdicts.
|
|
17
|
+
*
|
|
18
|
+
* Validation rules mirror game/src/engine/hud/validateTheme.ts; vocabulary
|
|
19
|
+
* comes from the drift-checked catalog next door.
|
|
20
|
+
*/
|
|
21
|
+
import { HUD_DECORATIONS, HUD_DECORATION_SLOTS, HUD_ELEMENT_CLASSES, HUD_FONTS, HUD_GLOW_KEYS, HUD_ICON_KEYS, } from './hud-theme-catalog.js';
|
|
22
|
+
const HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
|
|
23
|
+
// Mirrors the engine's TILE_SIZE: "<n>px|% <n>px|%", decimals allowed.
|
|
24
|
+
const TILE_SIZE = /^\d{1,4}(?:\.\d{1,2})?(?:px|%) \d{1,4}(?:\.\d{1,2})?(?:px|%)$/;
|
|
25
|
+
const POSITION_VALUES = [
|
|
26
|
+
'top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left', 'center',
|
|
27
|
+
];
|
|
28
|
+
const REPEAT_VALUES = ['no-repeat', 'repeat', 'repeat-x', 'repeat-y'];
|
|
29
|
+
const BORDER_REPEAT_VALUES = ['stretch', 'repeat', 'round', 'space'];
|
|
30
|
+
const COLOR_KEYS = [
|
|
31
|
+
'primary', 'danger', 'warning', 'success', 'background', 'surface', 'text', 'textMuted', 'outline',
|
|
32
|
+
];
|
|
33
|
+
const REQUIRED_COLOR_KEYS = ['primary', 'danger', 'background', 'surface', 'text'];
|
|
34
|
+
// Levenshtein, matching the engine: suggest only when the distance is small
|
|
35
|
+
// relative to the input. A wild guess gets the full candidate list from the
|
|
36
|
+
// error message, never false confidence in one arbitrary name.
|
|
37
|
+
function editDistance(a, b) {
|
|
38
|
+
let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
39
|
+
for (let i = 1; i <= a.length; i++) {
|
|
40
|
+
const cur = [i];
|
|
41
|
+
for (let j = 1; j <= b.length; j++) {
|
|
42
|
+
const deletion = (prev[j] ?? 0) + 1;
|
|
43
|
+
const insertion = (cur[j - 1] ?? 0) + 1;
|
|
44
|
+
const substitution = (prev[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1);
|
|
45
|
+
cur[j] = Math.min(deletion, insertion, substitution);
|
|
46
|
+
}
|
|
47
|
+
prev = cur;
|
|
48
|
+
}
|
|
49
|
+
return prev[b.length] ?? 0;
|
|
50
|
+
}
|
|
51
|
+
export function suggestClosest(value, candidates) {
|
|
52
|
+
const v = value.toLowerCase();
|
|
53
|
+
let best;
|
|
54
|
+
let bestScore = Infinity;
|
|
55
|
+
for (const c of candidates) {
|
|
56
|
+
const score = editDistance(v, c.toLowerCase());
|
|
57
|
+
if (score < bestScore) {
|
|
58
|
+
bestScore = score;
|
|
59
|
+
best = c;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const maxDistance = Math.max(2, Math.ceil(v.length / 3));
|
|
63
|
+
return bestScore <= maxDistance ? best : undefined;
|
|
64
|
+
}
|
|
65
|
+
function isObject(v) {
|
|
66
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
67
|
+
}
|
|
68
|
+
function checkNumber(ctx, path, value, min, max) {
|
|
69
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < min || value > max) {
|
|
70
|
+
ctx.errors.push({ path, message: `${JSON.stringify(value)} is not a number in [${min}, ${max}]` });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function checkHexAt(ctx, path, value) {
|
|
74
|
+
if (typeof value !== 'string' || !HEX_COLOR.test(value)) {
|
|
75
|
+
ctx.errors.push({
|
|
76
|
+
path,
|
|
77
|
+
message: `${JSON.stringify(value)} is not a 6-digit hex color`,
|
|
78
|
+
suggestion: 'Use e.g. "#A0DAB9" — six hex digits with a leading #.',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function checkKeyed(ctx, path, value, allowed) {
|
|
83
|
+
if (typeof value === 'string' && allowed.includes(value))
|
|
84
|
+
return;
|
|
85
|
+
const close = typeof value === 'string' ? suggestClosest(value, allowed) : undefined;
|
|
86
|
+
ctx.errors.push({
|
|
87
|
+
path,
|
|
88
|
+
message: `${JSON.stringify(value)} is not one of: ${allowed.join(', ')}`,
|
|
89
|
+
...(close ? { suggestion: `Closest match: "${close}"` } : {}),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function checkFontBlock(ctx, path, raw, required) {
|
|
93
|
+
if (raw === undefined) {
|
|
94
|
+
if (required)
|
|
95
|
+
ctx.errors.push({ path, message: 'font is required (object with at least { key })' });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!isObject(raw)) {
|
|
99
|
+
ctx.errors.push({ path, message: 'font must be an object' });
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (raw.key === undefined) {
|
|
103
|
+
if (required)
|
|
104
|
+
ctx.errors.push({ path: `${path}.key`, message: 'font.key is required (string)' });
|
|
105
|
+
}
|
|
106
|
+
else if (typeof raw.key !== 'string' || !(raw.key in HUD_FONTS)) {
|
|
107
|
+
const fontKeys = Object.keys(HUD_FONTS);
|
|
108
|
+
const close = typeof raw.key === 'string' ? suggestClosest(raw.key, fontKeys) : undefined;
|
|
109
|
+
ctx.errors.push({
|
|
110
|
+
path: `${path}.key`,
|
|
111
|
+
message: `${JSON.stringify(raw.key)} is not a curated font key`,
|
|
112
|
+
suggestion: close
|
|
113
|
+
? `Closest match: "${close}". Full list: ${fontKeys.join(', ')}`
|
|
114
|
+
: `Full list: ${fontKeys.join(', ')}`,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Auto-correct case IN PLACE when the font doesn't support it — the
|
|
119
|
+
// corrected object is what gets written, and the warning explains the
|
|
120
|
+
// swap so the agent can mention it to the user.
|
|
121
|
+
//
|
|
122
|
+
// Only a VALID case value is eligible: the auto-correct used to run
|
|
123
|
+
// first and mutate any string (including "lower"/"uppercase") to
|
|
124
|
+
// suitsCase[0], so the enum check below then saw the corrected value and
|
|
125
|
+
// the kit passed with a warning where the engine hard-rejects the whole
|
|
126
|
+
// theme — kit-ok/engine-reject, the exact parity direction the gate
|
|
127
|
+
// exists to forbid.
|
|
128
|
+
const entry = HUD_FONTS[raw.key];
|
|
129
|
+
if ((raw.case === 'upper' || raw.case === 'normal')
|
|
130
|
+
&& !entry.suitsCase.includes(raw.case)) {
|
|
131
|
+
const originalCase = raw.case;
|
|
132
|
+
const correctedCase = entry.suitsCase[0];
|
|
133
|
+
raw.case = correctedCase;
|
|
134
|
+
ctx.warnings.push({
|
|
135
|
+
path: `${path}.case`,
|
|
136
|
+
message: `font "${raw.key}" is designed for case "${correctedCase}" — auto-corrected from "${originalCase}". Pick a different font (e.g. "bebas-neue", "rubik-mono-one") if you want case "${originalCase}".`,
|
|
137
|
+
suggestion: `Either keep the auto-correction (case: "${correctedCase}") or change font.key.`,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (raw.case !== undefined && raw.case !== 'upper' && raw.case !== 'normal') {
|
|
142
|
+
ctx.errors.push({ path: `${path}.case`, message: `${JSON.stringify(raw.case)} is not "upper" or "normal"` });
|
|
143
|
+
}
|
|
144
|
+
if (raw.weightBody !== undefined && ![300, 400, 500, 700].includes(raw.weightBody)) {
|
|
145
|
+
ctx.errors.push({ path: `${path}.weightBody`, message: `${JSON.stringify(raw.weightBody)} is not one of 300, 400, 500, 700` });
|
|
146
|
+
}
|
|
147
|
+
if (raw.weightHeading !== undefined && ![400, 500, 700, 900].includes(raw.weightHeading)) {
|
|
148
|
+
ctx.errors.push({ path: `${path}.weightHeading`, message: `${JSON.stringify(raw.weightHeading)} is not one of 400, 500, 700, 900` });
|
|
149
|
+
}
|
|
150
|
+
if (raw.trackingLabel !== undefined)
|
|
151
|
+
checkNumber(ctx, `${path}.trackingLabel`, raw.trackingLabel, 0, 4);
|
|
152
|
+
if (raw.outlineWidth !== undefined)
|
|
153
|
+
checkNumber(ctx, `${path}.outlineWidth`, raw.outlineWidth, 0, 3);
|
|
154
|
+
if (raw.sizeScale !== undefined)
|
|
155
|
+
checkNumber(ctx, `${path}.sizeScale`, raw.sizeScale, 0.85, 1.3);
|
|
156
|
+
}
|
|
157
|
+
function checkColorsBlock(ctx, path, raw, required) {
|
|
158
|
+
if (raw === undefined) {
|
|
159
|
+
if (required)
|
|
160
|
+
ctx.errors.push({ path, message: 'colors is required' });
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (!isObject(raw)) {
|
|
164
|
+
ctx.errors.push({ path, message: 'colors must be an object' });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (required) {
|
|
168
|
+
for (const key of REQUIRED_COLOR_KEYS) {
|
|
169
|
+
if (raw[key] === undefined) {
|
|
170
|
+
ctx.errors.push({ path: `${path}.${key}`, message: `colors.${key} is required (hex string)` });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
for (const key of Object.keys(raw)) {
|
|
175
|
+
if (!COLOR_KEYS.includes(key)) {
|
|
176
|
+
const close = suggestClosest(key, COLOR_KEYS);
|
|
177
|
+
ctx.errors.push({
|
|
178
|
+
path: `${path}.${key}`,
|
|
179
|
+
message: `unknown color token "${key}"`,
|
|
180
|
+
suggestion: close ? `Closest match: "${close}". Known: ${COLOR_KEYS.join(', ')}` : `Known: ${COLOR_KEYS.join(', ')}`,
|
|
181
|
+
});
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
checkHexAt(ctx, `${path}.${key}`, raw[key]);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function checkShapeBlock(ctx, path, raw) {
|
|
188
|
+
if (raw === undefined)
|
|
189
|
+
return;
|
|
190
|
+
if (!isObject(raw)) {
|
|
191
|
+
ctx.errors.push({ path, message: 'shape must be an object' });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (raw.radiusPill !== undefined)
|
|
195
|
+
checkNumber(ctx, `${path}.radiusPill`, raw.radiusPill, 0, 500);
|
|
196
|
+
if (raw.radiusCard !== undefined)
|
|
197
|
+
checkNumber(ctx, `${path}.radiusCard`, raw.radiusCard, 0, 32);
|
|
198
|
+
if (raw.borderWidth !== undefined)
|
|
199
|
+
checkNumber(ctx, `${path}.borderWidth`, raw.borderWidth, 0, 6);
|
|
200
|
+
if (raw.bevel !== undefined)
|
|
201
|
+
checkNumber(ctx, `${path}.bevel`, raw.bevel, 0, 1);
|
|
202
|
+
if (raw.gloss !== undefined)
|
|
203
|
+
checkNumber(ctx, `${path}.gloss`, raw.gloss, 0, 1);
|
|
204
|
+
if (raw.glow !== undefined)
|
|
205
|
+
checkKeyed(ctx, `${path}.glow`, raw.glow, HUD_GLOW_KEYS);
|
|
206
|
+
if (raw.glowColor !== undefined)
|
|
207
|
+
checkHexAt(ctx, `${path}.glowColor`, raw.glowColor);
|
|
208
|
+
if (raw.imageRendering !== undefined && raw.imageRendering !== 'auto' && raw.imageRendering !== 'pixelated') {
|
|
209
|
+
ctx.errors.push({ path: `${path}.imageRendering`, message: `${JSON.stringify(raw.imageRendering)} is not "auto" or "pixelated"` });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function checkDecorationValue(ctx, path, slotName, value) {
|
|
213
|
+
if (typeof value === 'string') {
|
|
214
|
+
if (!(value in HUD_DECORATIONS)) {
|
|
215
|
+
const decKeys = Object.keys(HUD_DECORATIONS);
|
|
216
|
+
const close = suggestClosest(value, decKeys);
|
|
217
|
+
ctx.errors.push({
|
|
218
|
+
path,
|
|
219
|
+
message: `"${value}" is not a curated decoration key`,
|
|
220
|
+
suggestion: close
|
|
221
|
+
? `Closest match: "${close}". Full list: ${decKeys.join(', ')}`
|
|
222
|
+
: `Full list: ${decKeys.join(', ')}`,
|
|
223
|
+
});
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// Suitability is a WARNING, matching the engine: an unsuited pairing
|
|
227
|
+
// renders, it just usually looks wrong.
|
|
228
|
+
const entry = HUD_DECORATIONS[value];
|
|
229
|
+
if (!entry.suitsSlots.includes(slotName)) {
|
|
230
|
+
ctx.warnings.push({
|
|
231
|
+
path,
|
|
232
|
+
message: `decoration "${value}" isn't designed for slot "${slotName}" (suits: ${entry.suitsSlots.join(', ')})`,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (isObject(value)) {
|
|
238
|
+
if (typeof value.svg !== 'string') {
|
|
239
|
+
ctx.errors.push({ path: `${path}.svg`, message: 'inline decoration must have an svg string' });
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (value.svg.length > 16384) {
|
|
243
|
+
ctx.errors.push({ path: `${path}.svg`, message: 'inline SVG exceeds 16kb limit' });
|
|
244
|
+
}
|
|
245
|
+
if (slotName === 'borderImage') {
|
|
246
|
+
if (value.borderSlice !== undefined)
|
|
247
|
+
checkNumber(ctx, `${path}.borderSlice`, value.borderSlice, 0, 200);
|
|
248
|
+
if (value.repeat !== undefined)
|
|
249
|
+
checkKeyed(ctx, `${path}.repeat`, value.repeat, BORDER_REPEAT_VALUES);
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
if (value.size !== undefined && value.size !== 'cover' && value.size !== 'contain' && value.size !== 'auto'
|
|
253
|
+
&& !(typeof value.size === 'string' && TILE_SIZE.test(value.size))) {
|
|
254
|
+
ctx.errors.push({
|
|
255
|
+
path: `${path}.size`,
|
|
256
|
+
message: `${JSON.stringify(value.size)} is not "cover", "contain", "auto", or an explicit tile size`,
|
|
257
|
+
suggestion: 'Use "32px 32px" for a repeating pattern (a viewBox-only SVG has no intrinsic size, so "auto" stretches one copy over the whole element), or one of the keywords.',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if (value.position !== undefined)
|
|
261
|
+
checkKeyed(ctx, `${path}.position`, value.position, POSITION_VALUES);
|
|
262
|
+
if (value.repeat !== undefined)
|
|
263
|
+
checkKeyed(ctx, `${path}.repeat`, value.repeat, REPEAT_VALUES);
|
|
264
|
+
}
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
ctx.errors.push({ path, message: 'expected curated decoration key string or inline SVG object' });
|
|
268
|
+
}
|
|
269
|
+
function checkDecorationsBlock(ctx, path, raw) {
|
|
270
|
+
if (raw === undefined || raw === null)
|
|
271
|
+
return;
|
|
272
|
+
if (!isObject(raw)) {
|
|
273
|
+
ctx.errors.push({ path, message: 'decorations must be an object keyed by HUD element class' });
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
for (const elementClass of Object.keys(raw)) {
|
|
277
|
+
if (!HUD_ELEMENT_CLASSES.includes(elementClass)) {
|
|
278
|
+
const close = suggestClosest(elementClass, HUD_ELEMENT_CLASSES);
|
|
279
|
+
ctx.errors.push({
|
|
280
|
+
path: `${path}.${elementClass}`,
|
|
281
|
+
message: `unknown HUD element class "${elementClass}"`,
|
|
282
|
+
suggestion: close
|
|
283
|
+
? `Closest match: "${close}". Known: ${HUD_ELEMENT_CLASSES.join(', ')}`
|
|
284
|
+
: `Known: ${HUD_ELEMENT_CLASSES.join(', ')}`,
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const slots = raw[elementClass];
|
|
289
|
+
if (!isObject(slots))
|
|
290
|
+
continue;
|
|
291
|
+
for (const slotName of Object.keys(slots)) {
|
|
292
|
+
if (!HUD_DECORATION_SLOTS.includes(slotName)) {
|
|
293
|
+
const close = suggestClosest(slotName, HUD_DECORATION_SLOTS);
|
|
294
|
+
ctx.errors.push({
|
|
295
|
+
path: `${path}.${elementClass}.${slotName}`,
|
|
296
|
+
message: `unknown slot "${slotName}"`,
|
|
297
|
+
suggestion: close
|
|
298
|
+
? `Closest match: "${close}". Known: ${HUD_DECORATION_SLOTS.join(', ')}`
|
|
299
|
+
: `Known: ${HUD_DECORATION_SLOTS.join(', ')}`,
|
|
300
|
+
});
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
checkDecorationValue(ctx, `${path}.${elementClass}.${slotName}`, slotName, slots[slotName]);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function checkElementsBlock(ctx, path, raw) {
|
|
308
|
+
if (raw === undefined || raw === null)
|
|
309
|
+
return;
|
|
310
|
+
if (!isObject(raw)) {
|
|
311
|
+
ctx.errors.push({ path, message: 'elements must be an object keyed by HUD element class' });
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
for (const elementClass of Object.keys(raw)) {
|
|
315
|
+
if (!HUD_ELEMENT_CLASSES.includes(elementClass)) {
|
|
316
|
+
const close = suggestClosest(elementClass, HUD_ELEMENT_CLASSES);
|
|
317
|
+
ctx.errors.push({
|
|
318
|
+
path: `${path}.${elementClass}`,
|
|
319
|
+
message: `unknown HUD element class "${elementClass}"`,
|
|
320
|
+
suggestion: close
|
|
321
|
+
? `Closest match: "${close}". Known: ${HUD_ELEMENT_CLASSES.join(', ')}`
|
|
322
|
+
: `Known: ${HUD_ELEMENT_CLASSES.join(', ')}`,
|
|
323
|
+
});
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const override = raw[elementClass];
|
|
327
|
+
if (!isObject(override)) {
|
|
328
|
+
ctx.errors.push({ path: `${path}.${elementClass}`, message: 'expected a partial theme object' });
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
// At write time these are ERRORS, unlike the engine's load-time
|
|
332
|
+
// warn-and-drop: the agent can fix the leaf in the same turn, and an
|
|
333
|
+
// override the engine would drop is an override the user asked for and
|
|
334
|
+
// will not get.
|
|
335
|
+
checkFontBlock(ctx, `${path}.${elementClass}.font`, override.font, false);
|
|
336
|
+
if (override.colors !== undefined)
|
|
337
|
+
checkColorsBlock(ctx, `${path}.${elementClass}.colors`, override.colors, false);
|
|
338
|
+
checkShapeBlock(ctx, `${path}.${elementClass}.shape`, override.shape);
|
|
339
|
+
checkDecorationsBlock(ctx, `${path}.${elementClass}.decorations`, override.decorations);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Whether an issue would make the ENGINE reject the whole theme, or only drop a
|
|
344
|
+
* leaf while the theme keeps rendering.
|
|
345
|
+
*
|
|
346
|
+
* This validator is deliberately stricter than the engine at two spots, and the
|
|
347
|
+
* difference matters when DESCRIBING a stored theme: per-element
|
|
348
|
+
* font/colors/shape leaves are warn-and-dropped at engine load (the theme still
|
|
349
|
+
* renders minus the leaf), and unknown top-level color tokens are ignored
|
|
350
|
+
* outright. Telling a user "the engine is falling back to the default look"
|
|
351
|
+
* over one droppable leaf describes a fallback that is not happening — and an
|
|
352
|
+
* agent acting on that "repairs" a theme the user is actually seeing.
|
|
353
|
+
*/
|
|
354
|
+
export function isEngineFatalIssue(issue) {
|
|
355
|
+
if (/^elements\.[^.]+\.(colors|shape|font)\./.test(issue.path))
|
|
356
|
+
return false;
|
|
357
|
+
if (issue.message.startsWith('unknown color token'))
|
|
358
|
+
return false;
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
export function validateThemeStrict(theme) {
|
|
362
|
+
const ctx = { errors: [], warnings: [] };
|
|
363
|
+
if (!isObject(theme)) {
|
|
364
|
+
ctx.errors.push({ path: '', message: 'theme must be an object' });
|
|
365
|
+
return { ok: false, errors: ctx.errors, warnings: ctx.warnings };
|
|
366
|
+
}
|
|
367
|
+
if (typeof theme.name !== 'string' || theme.name.length === 0) {
|
|
368
|
+
ctx.errors.push({ path: 'name', message: 'name is required (non-empty string)' });
|
|
369
|
+
}
|
|
370
|
+
checkFontBlock(ctx, 'font', theme.font, true);
|
|
371
|
+
checkColorsBlock(ctx, 'colors', theme.colors, true);
|
|
372
|
+
checkShapeBlock(ctx, 'shape', theme.shape);
|
|
373
|
+
checkDecorationsBlock(ctx, 'decorations', theme.decorations);
|
|
374
|
+
checkElementsBlock(ctx, 'elements', theme.elements);
|
|
375
|
+
// icons
|
|
376
|
+
const icons = theme.icons;
|
|
377
|
+
if (icons !== undefined && icons !== null) {
|
|
378
|
+
if (!isObject(icons)) {
|
|
379
|
+
ctx.errors.push({ path: 'icons', message: 'icons must be an object keyed by slot name (heart, mouse, arrow)' });
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
for (const key of Object.keys(icons)) {
|
|
383
|
+
if (!HUD_ICON_KEYS.includes(key)) {
|
|
384
|
+
ctx.errors.push({
|
|
385
|
+
path: `icons.${key}`,
|
|
386
|
+
message: `unknown icon slot "${key}"`,
|
|
387
|
+
suggestion: `Known: ${HUD_ICON_KEYS.join(', ')}`,
|
|
388
|
+
});
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const value = icons[key];
|
|
392
|
+
if (value === undefined || value === null)
|
|
393
|
+
continue;
|
|
394
|
+
if (typeof value !== 'string') {
|
|
395
|
+
ctx.errors.push({ path: `icons.${key}`, message: 'icon SVG must be a string' });
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (value.length > 16384) {
|
|
399
|
+
ctx.errors.push({ path: `icons.${key}`, message: 'icon SVG exceeds 16kb limit' });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return { ok: ctx.errors.length === 0, errors: ctx.errors, warnings: ctx.warnings };
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=theme-validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-validate.js","sourceRoot":"","sources":["../../src/theme/theme-validate.ts"],"names":[],"mappings":"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"}
|
package/dist/verify/classify.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EARLY_WINDOW_SECONDS } from './events.js';
|
|
2
|
+
import { parseHudThemeProblem } from './hud-theme.js';
|
|
2
3
|
/**
|
|
3
4
|
* Both event thresholds warn rather than fail, deliberately: verify provides no gameplay input,
|
|
4
5
|
* so only events that fire SPONTANEOUSLY are defensible signals, and even those need real-world
|
|
@@ -168,6 +169,24 @@ export function classifyVerifyRun(observations, context = {}) {
|
|
|
168
169
|
+ 'the WebGPU path may or may not have been exercised.');
|
|
169
170
|
}
|
|
170
171
|
}
|
|
172
|
+
// A `hud.theme` the engine could not resolve. It never blocks a load — it warns once and renders
|
|
173
|
+
// the DEFAULT look — so the game runs, the screenshot is fine, and the only symptom is that the
|
|
174
|
+
// theme the author asked for never appeared. A warning rather than a failure: the game is
|
|
175
|
+
// playable and shippable, it is just not wearing the look it was told to wear.
|
|
176
|
+
//
|
|
177
|
+
// Parsed straight from `consoleLines`, which every caller already provides, so this needs no new
|
|
178
|
+
// observation and is inert wherever the line is absent — including `bitmagic publish`'s smoke
|
|
179
|
+
// run, which calls this function with observations only.
|
|
180
|
+
const themeProblem = parseHudThemeProblem(observations.consoleLines);
|
|
181
|
+
if (themeProblem) {
|
|
182
|
+
warnings.push(themeProblem.kind === 'preset'
|
|
183
|
+
? `The HUD theme did not apply — the game rendered the engine's default look instead. ${themeProblem.detail} `
|
|
184
|
+
+ 'Fix the `hud.theme` value in world.json; preset names are hyphenated (`rift-raider`, `village-keep`), '
|
|
185
|
+
+ 'and the style keys you find in engine source are not valid theme values.'
|
|
186
|
+
: `The HUD theme did not apply — the game rendered the engine's default look instead. ${themeProblem.detail} `
|
|
187
|
+
+ 'Fix the named fields in `hud.theme` in world.json; see engine/agent-docs/HUD_THEMES.md '
|
|
188
|
+
+ 'for the token vocabulary, or set a preset name instead of an inline theme.');
|
|
189
|
+
}
|
|
171
190
|
// The engine's own mobile-parity check, which it runs at every game start and which nothing
|
|
172
191
|
// read until now. Null means it reported no gap — a clean game, an older engine, or a genre
|
|
173
192
|
// whose controller has no parity check (the 2D genres) — and "not observed" is never a failure.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/verify/classify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAA0B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/verify/classify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the engine's HUD-theme verdict out of the console verify already captures.
|
|
3
|
+
*
|
|
4
|
+
* A bad `hud.theme` in world.json is one of the quietest failures a project can carry. The engine
|
|
5
|
+
* never throws over it — `resolveWorldTheme` deliberately treats a broken theme as recoverable and
|
|
6
|
+
* a blocked game load as not — so it logs one warning and renders the DEFAULT look. The game runs,
|
|
7
|
+
* the screenshot is fine, verify passes, and the only symptom is that the theme the author asked
|
|
8
|
+
* for never appeared. That reads as "theming is broken" rather than "the name was misspelled", and
|
|
9
|
+
* it survives for as long as nobody diffs the intended look against the shipped one.
|
|
10
|
+
*
|
|
11
|
+
* The hosted agent is protected from this by `write-hud-theme`, which validates before it writes
|
|
12
|
+
* and answers with a closest-match suggestion. `bitmagic theme set|patch` now gives the CLI lane the
|
|
13
|
+
* same write-time guard over a gate-enforced mirror of that validator — but only for edits made
|
|
14
|
+
* THROUGH it. A hand edit to world.json, a vendored engine older than the CLI's copy, or a theme
|
|
15
|
+
* that validates yet still fails in the browser all land here, which is why this check stays: it is
|
|
16
|
+
* the only one that reads what the engine itself said.
|
|
17
|
+
*
|
|
18
|
+
* WHY PARSE THE CONSOLE rather than validate statically here. The obvious alternative is to read
|
|
19
|
+
* world.json and check it against the engine's own validator, and it is not available: the vendored
|
|
20
|
+
* engine emits with its path-mapped specifiers intact (`from 'engine/hud/ThemeTokens.js'`), which
|
|
21
|
+
* resolve only through the browser import map, so `validateAndResolveTheme` cannot be imported from
|
|
22
|
+
* Node. The remaining static option is a hand-mirrored preset list in the CLI, i.e. a third copy of
|
|
23
|
+
* the same list to keep in sync. Parsing what the engine already said costs no mirror, cannot drift,
|
|
24
|
+
* and inherits the engine's own error text — including the field paths from an invalid inline theme
|
|
25
|
+
* and the live list of known presets, neither of which a mirror would have.
|
|
26
|
+
*
|
|
27
|
+
* The cost is honest and worth naming: this only sees a theme on a game that actually booted. A
|
|
28
|
+
* project whose game fails to load has bigger findings in the same run.
|
|
29
|
+
*/
|
|
30
|
+
/** The engine's marker on every theme-resolution warning. Also what a reader greps for. */
|
|
31
|
+
export declare const HUD_THEME_MARKER = "[HUD]";
|
|
32
|
+
export interface HudThemeProblem {
|
|
33
|
+
/**
|
|
34
|
+
* `preset` — the name matched nothing, so the game silently rendered the default.
|
|
35
|
+
* `custom` — an inline theme was structurally invalid and was dropped whole.
|
|
36
|
+
*/
|
|
37
|
+
kind: 'preset' | 'custom';
|
|
38
|
+
/**
|
|
39
|
+
* The engine's own sentence, minus the marker. Carries the detail a re-implementation here
|
|
40
|
+
* would have had to invent: the offending name and the live preset list, or the failing field
|
|
41
|
+
* paths.
|
|
42
|
+
*/
|
|
43
|
+
detail: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The theme problem the engine reported during this run, or null when it reported none.
|
|
47
|
+
*
|
|
48
|
+
* Null is "not observed" and never a failure. Three legitimate ways to get it: the theme resolved
|
|
49
|
+
* cleanly, the project sets no theme at all, or the engine predates the warning.
|
|
50
|
+
*
|
|
51
|
+
* The LAST matching line wins, for the same reason it does in the mobile-parity reader: a run that
|
|
52
|
+
* starts gameplay more than once logs the check once per start, and the newest verdict describes
|
|
53
|
+
* the game as it ended up.
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseHudThemeProblem(consoleLines: string[]): HudThemeProblem | null;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the engine's HUD-theme verdict out of the console verify already captures.
|
|
3
|
+
*
|
|
4
|
+
* A bad `hud.theme` in world.json is one of the quietest failures a project can carry. The engine
|
|
5
|
+
* never throws over it — `resolveWorldTheme` deliberately treats a broken theme as recoverable and
|
|
6
|
+
* a blocked game load as not — so it logs one warning and renders the DEFAULT look. The game runs,
|
|
7
|
+
* the screenshot is fine, verify passes, and the only symptom is that the theme the author asked
|
|
8
|
+
* for never appeared. That reads as "theming is broken" rather than "the name was misspelled", and
|
|
9
|
+
* it survives for as long as nobody diffs the intended look against the shipped one.
|
|
10
|
+
*
|
|
11
|
+
* The hosted agent is protected from this by `write-hud-theme`, which validates before it writes
|
|
12
|
+
* and answers with a closest-match suggestion. `bitmagic theme set|patch` now gives the CLI lane the
|
|
13
|
+
* same write-time guard over a gate-enforced mirror of that validator — but only for edits made
|
|
14
|
+
* THROUGH it. A hand edit to world.json, a vendored engine older than the CLI's copy, or a theme
|
|
15
|
+
* that validates yet still fails in the browser all land here, which is why this check stays: it is
|
|
16
|
+
* the only one that reads what the engine itself said.
|
|
17
|
+
*
|
|
18
|
+
* WHY PARSE THE CONSOLE rather than validate statically here. The obvious alternative is to read
|
|
19
|
+
* world.json and check it against the engine's own validator, and it is not available: the vendored
|
|
20
|
+
* engine emits with its path-mapped specifiers intact (`from 'engine/hud/ThemeTokens.js'`), which
|
|
21
|
+
* resolve only through the browser import map, so `validateAndResolveTheme` cannot be imported from
|
|
22
|
+
* Node. The remaining static option is a hand-mirrored preset list in the CLI, i.e. a third copy of
|
|
23
|
+
* the same list to keep in sync. Parsing what the engine already said costs no mirror, cannot drift,
|
|
24
|
+
* and inherits the engine's own error text — including the field paths from an invalid inline theme
|
|
25
|
+
* and the live list of known presets, neither of which a mirror would have.
|
|
26
|
+
*
|
|
27
|
+
* The cost is honest and worth naming: this only sees a theme on a game that actually booted. A
|
|
28
|
+
* project whose game fails to load has bigger findings in the same run.
|
|
29
|
+
*/
|
|
30
|
+
/** The engine's marker on every theme-resolution warning. Also what a reader greps for. */
|
|
31
|
+
export const HUD_THEME_MARKER = '[HUD]';
|
|
32
|
+
/** `resolveWorldTheme`'s wording when `hud.theme` is a string that names no preset. */
|
|
33
|
+
const UNKNOWN_PRESET = 'Unknown theme preset';
|
|
34
|
+
/** …and when it is an object the validator rejected. */
|
|
35
|
+
const INVALID_THEME = 'Custom theme failed validation';
|
|
36
|
+
/**
|
|
37
|
+
* The theme problem the engine reported during this run, or null when it reported none.
|
|
38
|
+
*
|
|
39
|
+
* Null is "not observed" and never a failure. Three legitimate ways to get it: the theme resolved
|
|
40
|
+
* cleanly, the project sets no theme at all, or the engine predates the warning.
|
|
41
|
+
*
|
|
42
|
+
* The LAST matching line wins, for the same reason it does in the mobile-parity reader: a run that
|
|
43
|
+
* starts gameplay more than once logs the check once per start, and the newest verdict describes
|
|
44
|
+
* the game as it ended up.
|
|
45
|
+
*/
|
|
46
|
+
export function parseHudThemeProblem(consoleLines) {
|
|
47
|
+
for (let i = consoleLines.length - 1; i >= 0; i--) {
|
|
48
|
+
const problem = parseLine(consoleLines[i]);
|
|
49
|
+
if (problem !== null)
|
|
50
|
+
return problem;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function parseLine(line) {
|
|
55
|
+
const marker = line.indexOf(HUD_THEME_MARKER);
|
|
56
|
+
if (marker === -1)
|
|
57
|
+
return null;
|
|
58
|
+
// Everything after the marker, with the console-type prefix (`warning: `) dropped.
|
|
59
|
+
const detail = line.slice(marker + HUD_THEME_MARKER.length).trim();
|
|
60
|
+
if (detail.length === 0)
|
|
61
|
+
return null;
|
|
62
|
+
if (detail.includes(UNKNOWN_PRESET))
|
|
63
|
+
return { kind: 'preset', detail };
|
|
64
|
+
if (detail.includes(INVALID_THEME))
|
|
65
|
+
return { kind: 'custom', detail };
|
|
66
|
+
// Other `[HUD]` lines exist (a theme that resolved but carried warnings, for one). Those are
|
|
67
|
+
// not this check's business, and claiming them would turn a working theme into a finding.
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=hud-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hud-theme.js","sourceRoot":"","sources":["../../src/verify/hud-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAExC,uFAAuF;AACvF,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAE9C,wDAAwD;AACxD,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAgBvD;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAsB;IACzD,KAAK,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,OAAO,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/B,mFAAmF;IACnF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACvE,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEtE,6FAA6F;IAC7F,0FAA0F;IAC1F,OAAO,IAAI,CAAC;AACd,CAAC"}
|