@glissade/cli 0.59.0 → 0.60.0-pre.1
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.js +16 -1
- package/dist/critique.js +53 -0
- package/dist/describeLint.js +16 -5
- package/package.json +10 -10
package/dist/cli.js
CHANGED
|
@@ -82,6 +82,7 @@ function parseCaptionsModeOrFail(raw) {
|
|
|
82
82
|
const USAGE = `usage:
|
|
83
83
|
gs render <scene-module> [options]
|
|
84
84
|
gs diff <scene-module> --at <t> --against <baseline.dl.json|.png>
|
|
85
|
+
gs critique <scene-module> [--json] machine-readable RENDERED diagnostics (OFF_CANVAS/TEXT_OVERFLOW/OCCLUSION) from the DisplayList — the rendered-geometric half of validateScene; samples an integer-frame grid, prints the flat canonically-sorted diagnostics (--json for the raw result)
|
|
85
86
|
gs verify-determinism <scene-module> [--shards <n>] [--against <frames.manifest>] [--range a..b] [--bisect] [--emit <p>]
|
|
86
87
|
gs dev <scene-module> [--record] [--port <n>]
|
|
87
88
|
gs import <lottie.json|asset.svg> [--out <dir>] [--allow-degraded]
|
|
@@ -212,7 +213,7 @@ async function main() {
|
|
|
212
213
|
process.stdout.write(`${describe().version}\n`);
|
|
213
214
|
return;
|
|
214
215
|
}
|
|
215
|
-
if (command !== "render" && command !== "diff" && command !== "verify-determinism" && command !== "dev" && command !== "import" && command !== "export" && command !== "narrate" && command !== "narration-lint" && command !== "sfx" && command !== "prepare" && command !== "measure-loudness" && command !== "fonts" && command !== "cache" && command !== "mcp" && command !== "build" && command !== "describe" && command !== "migrate" && command !== "repin" && command !== "parity" && command !== "master" && command !== "localize" && command !== "types") {
|
|
216
|
+
if (command !== "render" && command !== "diff" && command !== "critique" && command !== "verify-determinism" && command !== "dev" && command !== "import" && command !== "export" && command !== "narrate" && command !== "narration-lint" && command !== "sfx" && command !== "prepare" && command !== "measure-loudness" && command !== "fonts" && command !== "cache" && command !== "mcp" && command !== "build" && command !== "describe" && command !== "migrate" && command !== "repin" && command !== "parity" && command !== "master" && command !== "localize" && command !== "types") {
|
|
216
217
|
console.error(USAGE);
|
|
217
218
|
process.exit(command === void 0 || command === "help" || command === "--help" ? 0 : 1);
|
|
218
219
|
}
|
|
@@ -653,6 +654,20 @@ async function main() {
|
|
|
653
654
|
}
|
|
654
655
|
return;
|
|
655
656
|
}
|
|
657
|
+
if (command === "critique") {
|
|
658
|
+
const { critiqueCommand } = await import("./critique.js");
|
|
659
|
+
try {
|
|
660
|
+
const out = await critiqueCommand({
|
|
661
|
+
modulePath,
|
|
662
|
+
json: flags.has("json")
|
|
663
|
+
});
|
|
664
|
+
process.stdout.write(`${out.report}\n`);
|
|
665
|
+
if (out.hasErrors) process.exit(1);
|
|
666
|
+
} catch (err) {
|
|
667
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
668
|
+
}
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
656
671
|
if (command === "verify-determinism") {
|
|
657
672
|
let frameRange;
|
|
658
673
|
const rangeFlag = flags.get("range");
|
package/dist/critique.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { o as loadSceneModule } from "./render.js";
|
|
2
|
+
import { critique } from "@glissade/scene/diagnostics";
|
|
3
|
+
//#region src/critique.ts
|
|
4
|
+
/**
|
|
5
|
+
* `gs critique <scene-module>` (0.60): machine-readable RENDERED diagnostics from
|
|
6
|
+
* the DisplayList — the rendered-geometric half of `gs describe --lint` /
|
|
7
|
+
* validateScene. Loads the scene, injects the Skia measurer (so TEXT_OVERFLOW
|
|
8
|
+
* measures with the same metrics `gs render` lays out with), runs `critique`, and
|
|
9
|
+
* prints the flat, canonically-sorted diagnostics. `--json` emits the raw result
|
|
10
|
+
* for a machine consumer; exits non-zero iff any diagnostic is `error` severity
|
|
11
|
+
* (only static errors are — the rendered pass emits warnings/info).
|
|
12
|
+
*/
|
|
13
|
+
async function critiqueCommand(opts) {
|
|
14
|
+
try {
|
|
15
|
+
const { loadYogaLayoutEngine } = await import("@glissade/scene/layout");
|
|
16
|
+
await loadYogaLayoutEngine();
|
|
17
|
+
} catch {}
|
|
18
|
+
const mod = await loadSceneModule(opts.modulePath);
|
|
19
|
+
const scene = mod.createScene();
|
|
20
|
+
const { SkiaBackend } = await import("@glissade/backend-skia");
|
|
21
|
+
scene.setTextMeasurer(new SkiaBackend(scene.size.w, scene.size.h));
|
|
22
|
+
const result = critique(scene, mod.timeline);
|
|
23
|
+
if (opts.json) return {
|
|
24
|
+
result,
|
|
25
|
+
report: JSON.stringify(result, null, 2),
|
|
26
|
+
hasErrors: result.hasErrors
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
result,
|
|
30
|
+
report: formatCritique(result),
|
|
31
|
+
hasErrors: result.hasErrors
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function formatCritique(r) {
|
|
35
|
+
const lines = [];
|
|
36
|
+
if (r.renderedSkipped) lines.push(`rendered pass SKIPPED: ${r.renderedSkipReason ?? ""}`);
|
|
37
|
+
else lines.push(`sampled ${r.sampledFrames} integer-frame grid sample(s).`);
|
|
38
|
+
if (r.diagnostics.length === 0) {
|
|
39
|
+
lines.push("ok — no diagnostics (clean scene).");
|
|
40
|
+
return lines.join("\n");
|
|
41
|
+
}
|
|
42
|
+
for (const d of r.diagnostics) {
|
|
43
|
+
const where = d.node ? ` [${d.node}]` : d.track ? ` [${d.track}]` : "";
|
|
44
|
+
lines.push(`${d.severity.toUpperCase()} ${d.code}${where} (${d.source ?? "?"}): ${d.message}`);
|
|
45
|
+
}
|
|
46
|
+
const errs = r.diagnostics.filter((d) => d.severity === "error").length;
|
|
47
|
+
const warns = r.diagnostics.filter((d) => d.severity === "warning").length;
|
|
48
|
+
const infos = r.diagnostics.filter((d) => d.severity === "info").length;
|
|
49
|
+
lines.push(`\n${errs} error(s), ${warns} warning(s), ${infos} info.`);
|
|
50
|
+
return lines.join("\n");
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { critiqueCommand };
|
package/dist/describeLint.js
CHANGED
|
@@ -156,10 +156,20 @@ const EXEMPT_INTERNALS = new Set([
|
|
|
156
156
|
"vec2Equals",
|
|
157
157
|
"vec2Signal",
|
|
158
158
|
"velocityAt",
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
"
|
|
162
|
-
"
|
|
159
|
+
"DIAGNOSTIC_SCHEMA_VERSION",
|
|
160
|
+
"emitWithIds",
|
|
161
|
+
"diffDisplayLists",
|
|
162
|
+
"formatDisplayDiff",
|
|
163
|
+
"serializeDisplayList",
|
|
164
|
+
"parseDisplaySnapshot",
|
|
165
|
+
"DL_SNAPSHOT_VERSION",
|
|
166
|
+
"auditCacheCold",
|
|
167
|
+
"collectTextUsages",
|
|
168
|
+
"collectLocalizedTextUsages",
|
|
169
|
+
"validateSceneFonts",
|
|
170
|
+
"nearestId",
|
|
171
|
+
"levenshtein",
|
|
172
|
+
"sortDiagnostics"
|
|
163
173
|
]);
|
|
164
174
|
/**
|
|
165
175
|
* PATTERN-exempt runtime exports (no per-name entry needed): error classes
|
|
@@ -208,7 +218,7 @@ function describeLint(manifest, surface, opts = {}) {
|
|
|
208
218
|
const callables = /* @__PURE__ */ new Set();
|
|
209
219
|
for (const name of Object.keys(manifest.nodes)) callables.add(name);
|
|
210
220
|
for (const h of manifest.helpers) callables.add(h.name);
|
|
211
|
-
for (const e of manifest.surface ?? []) if (e.kind === "value" && (e.form === "constructor" || e.form === "function")) callables.add(e.name);
|
|
221
|
+
for (const e of manifest.surface ?? []) if ((e.kind === "value" || e.kind === "diagnostic") && (e.form === "constructor" || e.form === "function")) callables.add(e.name);
|
|
212
222
|
for (const name of [...callables].sort()) {
|
|
213
223
|
if (exempt.has(name) || isFn(name)) continue;
|
|
214
224
|
out.push(present(name) ? {
|
|
@@ -269,6 +279,7 @@ async function collectRuntimeSurface(manifest) {
|
|
|
269
279
|
"@glissade/core/clips",
|
|
270
280
|
"@glissade/scene",
|
|
271
281
|
"@glissade/scene/describe",
|
|
282
|
+
"@glissade/scene/diagnostics",
|
|
272
283
|
"@glissade/scene/layout-ctors",
|
|
273
284
|
"@glissade/scene/path"
|
|
274
285
|
]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.60.0-pre.1",
|
|
4
4
|
"description": "glissade CLI: headless rendering via backend-skia (+ FFmpeg mux).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"@napi-rs/canvas": "^0.1.65",
|
|
29
29
|
"esbuild": "0.28.0",
|
|
30
30
|
"jiti": "^2.4.2",
|
|
31
|
-
"@glissade/backend-skia": "0.
|
|
32
|
-
"@glissade/core": "0.
|
|
33
|
-
"@glissade/interact": "0.
|
|
34
|
-
"@glissade/lottie": "0.
|
|
35
|
-
"@glissade/narrate": "0.
|
|
36
|
-
"@glissade/player": "0.
|
|
37
|
-
"@glissade/scene": "0.
|
|
38
|
-
"@glissade/sfx": "0.
|
|
39
|
-
"@glissade/svg": "0.
|
|
31
|
+
"@glissade/backend-skia": "0.60.0-pre.1",
|
|
32
|
+
"@glissade/core": "0.60.0-pre.1",
|
|
33
|
+
"@glissade/interact": "0.60.0-pre.1",
|
|
34
|
+
"@glissade/lottie": "0.60.0-pre.1",
|
|
35
|
+
"@glissade/narrate": "0.60.0-pre.1",
|
|
36
|
+
"@glissade/player": "0.60.0-pre.1",
|
|
37
|
+
"@glissade/scene": "0.60.0-pre.1",
|
|
38
|
+
"@glissade/sfx": "0.60.0-pre.1",
|
|
39
|
+
"@glissade/svg": "0.60.0-pre.1"
|
|
40
40
|
},
|
|
41
41
|
"repository": {
|
|
42
42
|
"type": "git",
|