@glissade/cli 0.28.0-pre.1 → 0.29.0-pre.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/dist/build.js +280 -0
- package/dist/cacheVerify.js +1 -1
- package/dist/cli.js +20 -1
- package/dist/config.d.ts +17 -0
- package/dist/config.js +2 -0
- package/dist/index.js +1 -1
- package/package.json +14 -10
package/dist/build.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime.js";
|
|
2
|
+
import { t as glissadeVersion } from "./version.js";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
//#region src/buildPlan.ts
|
|
8
|
+
/** The canonical order; a scene runs the subset that applies to it. */
|
|
9
|
+
const PIPELINE = [
|
|
10
|
+
"narrate",
|
|
11
|
+
"sfx",
|
|
12
|
+
"measure-loudness",
|
|
13
|
+
"render"
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Plan one scene's steps. `steps` is the applicable subset in PIPELINE order (a
|
|
17
|
+
* scene with no narration omits 'narrate', etc.). Returns a run/skip decision per
|
|
18
|
+
* step; the first step that runs forces every later step to run (propagation).
|
|
19
|
+
*/
|
|
20
|
+
function planScene(scene, steps, probe) {
|
|
21
|
+
const plans = [];
|
|
22
|
+
let upstreamRan = false;
|
|
23
|
+
for (const step of steps) {
|
|
24
|
+
let action;
|
|
25
|
+
let reason;
|
|
26
|
+
if (upstreamRan) {
|
|
27
|
+
action = "run";
|
|
28
|
+
reason = "upstream re-ran";
|
|
29
|
+
} else if (!probe.outputExists(step)) {
|
|
30
|
+
action = "run";
|
|
31
|
+
reason = "output missing";
|
|
32
|
+
} else {
|
|
33
|
+
const rec = probe.recordedHash(step);
|
|
34
|
+
if (rec === void 0) {
|
|
35
|
+
action = "run";
|
|
36
|
+
reason = "never built";
|
|
37
|
+
} else if (rec !== probe.currentHash(step)) {
|
|
38
|
+
action = "run";
|
|
39
|
+
reason = "inputs changed";
|
|
40
|
+
} else {
|
|
41
|
+
action = "skip";
|
|
42
|
+
reason = "fresh";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (action === "run") upstreamRan = true;
|
|
46
|
+
plans.push({
|
|
47
|
+
scene,
|
|
48
|
+
step,
|
|
49
|
+
action,
|
|
50
|
+
reason
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return plans;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/build.ts
|
|
57
|
+
/**
|
|
58
|
+
* `gs build` (0.29): the content-graph DAG runner. A `glissade.config.ts` lists the
|
|
59
|
+
* project's scenes; `gs build` derives each scene's narrate → sfx → measure-loudness
|
|
60
|
+
* → render pipeline, content-hashes every step's inputs (source + upstream outputs +
|
|
61
|
+
* glissade version), and runs ONLY the stale subtree. A one-segment re-narration
|
|
62
|
+
* re-narrates that asset, re-syncs ITS sfx, re-measures ITS loudness, re-renders it —
|
|
63
|
+
* and touches nothing else. `--explain` prints the plan without running anything.
|
|
64
|
+
*
|
|
65
|
+
* Step execution is injectable (`deps.runStep`) so the orchestration — staleness
|
|
66
|
+
* across builds, propagation, the manifest — is unit-testable without a TTS venv or
|
|
67
|
+
* ffmpeg; the default `runStep` delegates to the shipped narrate/sfx/loudness/render.
|
|
68
|
+
*/
|
|
69
|
+
var build_exports = /* @__PURE__ */ __exportAll({
|
|
70
|
+
applicableSteps: () => applicableSteps,
|
|
71
|
+
buildCommand: () => buildCommand,
|
|
72
|
+
defineProject: () => defineProject,
|
|
73
|
+
hashInputs: () => hashInputs,
|
|
74
|
+
loadConfig: () => loadConfig,
|
|
75
|
+
outputVideo: () => outputVideo,
|
|
76
|
+
resolveScenes: () => resolveScenes,
|
|
77
|
+
stepInputs: () => stepInputs,
|
|
78
|
+
stepOutput: () => stepOutput
|
|
79
|
+
});
|
|
80
|
+
/** Identity helper for a typed `glissade.config.ts` default export. */
|
|
81
|
+
function defineProject(config) {
|
|
82
|
+
return config;
|
|
83
|
+
}
|
|
84
|
+
async function loadConfig(configPath) {
|
|
85
|
+
const { createJiti } = await import("jiti");
|
|
86
|
+
const cfg = await createJiti(pathToFileURL(`${process.cwd()}/`).href).import(pathToFileURL(resolve(configPath)).href, { default: true });
|
|
87
|
+
if (!cfg || !Array.isArray(cfg.scenes)) throw new Error(`${configPath}: config must default-export { scenes: string[] } — use defineProject({ scenes: [...] })`);
|
|
88
|
+
return cfg;
|
|
89
|
+
}
|
|
90
|
+
/** Expand scene patterns (explicit paths + `dir/**\/*.ts` / `dir/*.ts` globs) to concrete files under `root`. */
|
|
91
|
+
function resolveScenes(patterns, root) {
|
|
92
|
+
const found = /* @__PURE__ */ new Set();
|
|
93
|
+
for (const pat of patterns) {
|
|
94
|
+
if (!pat.includes("*")) {
|
|
95
|
+
found.add(resolve(root, pat));
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const starAt = pat.indexOf("*");
|
|
99
|
+
const prefix = pat.slice(0, starAt);
|
|
100
|
+
const baseDir = resolve(root, prefix.includes("/") ? prefix.slice(0, prefix.lastIndexOf("/")) : ".");
|
|
101
|
+
const recursive = pat.includes("**");
|
|
102
|
+
const tail = pat.slice(pat.lastIndexOf("/") + 1);
|
|
103
|
+
const re = new RegExp(`^${tail.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*")}$`);
|
|
104
|
+
walk(baseDir, recursive, (file) => {
|
|
105
|
+
if (re.test(basename(file))) found.add(file);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return [...found].sort();
|
|
109
|
+
}
|
|
110
|
+
function walk(dir, recursive, onFile) {
|
|
111
|
+
let entries;
|
|
112
|
+
try {
|
|
113
|
+
entries = readdirSync(dir);
|
|
114
|
+
} catch {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
for (const e of entries) {
|
|
118
|
+
if (e === "node_modules" || e.startsWith(".")) continue;
|
|
119
|
+
const full = join(dir, e);
|
|
120
|
+
let s;
|
|
121
|
+
try {
|
|
122
|
+
s = statSync(full);
|
|
123
|
+
} catch {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (s.isDirectory()) {
|
|
127
|
+
if (recursive) walk(full, recursive, onFile);
|
|
128
|
+
} else onFile(full);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const stripExt = (scene) => scene.replace(/\.[jt]sx?$/, "");
|
|
132
|
+
const sib = (scene, ext) => `${stripExt(scene)}${ext}`;
|
|
133
|
+
/** Where a scene's rendered video lands (config `out` dir, else alongside the source). */
|
|
134
|
+
function outputVideo(scene, cfg, root) {
|
|
135
|
+
return cfg.out ? join(resolve(root, cfg.out), `${basename(stripExt(scene))}.mp4`) : `${stripExt(scene)}.mp4`;
|
|
136
|
+
}
|
|
137
|
+
/** The input files whose bytes decide a step's freshness (upstream outputs included). */
|
|
138
|
+
function stepInputs(scene, step) {
|
|
139
|
+
switch (step) {
|
|
140
|
+
case "narrate": return [scene, sib(scene, ".narration.json")];
|
|
141
|
+
case "sfx": return [sib(scene, ".sfx.json"), sib(scene, ".narration.timing.json")];
|
|
142
|
+
case "measure-loudness": return [
|
|
143
|
+
sib(scene, ".narration.timing.json"),
|
|
144
|
+
sib(scene, ".music.timing.json"),
|
|
145
|
+
sib(scene, ".sfx.timing.json")
|
|
146
|
+
];
|
|
147
|
+
case "render": return [
|
|
148
|
+
scene,
|
|
149
|
+
sib(scene, ".narration.timing.json"),
|
|
150
|
+
sib(scene, ".music.timing.json"),
|
|
151
|
+
sib(scene, ".sfx.timing.json"),
|
|
152
|
+
sib(scene, ".loudness.json")
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** The committed output whose existence gates a step (missing → must run). */
|
|
157
|
+
function stepOutput(scene, step, videoPath) {
|
|
158
|
+
switch (step) {
|
|
159
|
+
case "narrate": return sib(scene, ".narration.timing.json");
|
|
160
|
+
case "sfx": return sib(scene, ".sfx.timing.json");
|
|
161
|
+
case "measure-loudness": return sib(scene, ".loudness.json");
|
|
162
|
+
case "render": return videoPath;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Which pipeline steps apply to a scene: narrate/sfx only if their source sidecar exists;
|
|
166
|
+
* measure-loudness only if any audio timing is present; render always. */
|
|
167
|
+
function applicableSteps(scene) {
|
|
168
|
+
const steps = [];
|
|
169
|
+
if (existsSync(sib(scene, ".narration.json"))) steps.push("narrate");
|
|
170
|
+
if (existsSync(sib(scene, ".sfx.json"))) steps.push("sfx");
|
|
171
|
+
if ([
|
|
172
|
+
".narration.json",
|
|
173
|
+
".music.timing.json",
|
|
174
|
+
".sfx.json"
|
|
175
|
+
].some((e) => existsSync(sib(scene, e)))) steps.push("measure-loudness");
|
|
176
|
+
steps.push("render");
|
|
177
|
+
return PIPELINE.filter((s) => steps.includes(s));
|
|
178
|
+
}
|
|
179
|
+
function hashInputs(paths, salt) {
|
|
180
|
+
const h = createHash("sha256").update(salt).update("\0");
|
|
181
|
+
for (const p of paths) {
|
|
182
|
+
h.update(p).update("\0");
|
|
183
|
+
h.update(existsSync(p) ? readFileSync(p) : Buffer.from("\0ABSENT\0"));
|
|
184
|
+
h.update("\0");
|
|
185
|
+
}
|
|
186
|
+
return `sha256:${h.digest("hex")}`;
|
|
187
|
+
}
|
|
188
|
+
const manifestPath = (root) => join(root, ".gsbuild.json");
|
|
189
|
+
function loadManifest(root) {
|
|
190
|
+
const p = manifestPath(root);
|
|
191
|
+
if (existsSync(p)) try {
|
|
192
|
+
const m = JSON.parse(readFileSync(p, "utf8"));
|
|
193
|
+
if (m.version === 1 && m.scenes) return m;
|
|
194
|
+
} catch {}
|
|
195
|
+
return {
|
|
196
|
+
version: 1,
|
|
197
|
+
scenes: {}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function saveManifest(root, m) {
|
|
201
|
+
writeFileSync(manifestPath(root), JSON.stringify(m, null, 2));
|
|
202
|
+
}
|
|
203
|
+
async function buildCommand(opts, deps = { runStep: defaultRunStep }) {
|
|
204
|
+
const cfg = await loadConfig(opts.config);
|
|
205
|
+
const root = dirname(resolve(opts.config));
|
|
206
|
+
let scenes = resolveScenes(cfg.scenes, root);
|
|
207
|
+
if (opts.only?.length) scenes = scenes.filter((s) => opts.only.some((o) => s.includes(o)));
|
|
208
|
+
const version = glissadeVersion();
|
|
209
|
+
const manifest = loadManifest(root);
|
|
210
|
+
const log = opts.onLog ?? (() => {});
|
|
211
|
+
const allPlans = [];
|
|
212
|
+
let ran = 0;
|
|
213
|
+
let skipped = 0;
|
|
214
|
+
for (const scene of scenes) {
|
|
215
|
+
const key = relative(root, scene);
|
|
216
|
+
const rec = manifest.scenes[key] ?? {};
|
|
217
|
+
const videoPath = outputVideo(scene, cfg, root);
|
|
218
|
+
const plans = planScene(key, applicableSteps(scene), {
|
|
219
|
+
currentHash: (step) => hashInputs(stepInputs(scene, step), version),
|
|
220
|
+
recordedHash: (step) => rec[step],
|
|
221
|
+
outputExists: (step) => existsSync(stepOutput(scene, step, videoPath))
|
|
222
|
+
});
|
|
223
|
+
for (const plan of plans) {
|
|
224
|
+
log(`${key} ${plan.step}: ${plan.action} (${plan.reason})`);
|
|
225
|
+
if (plan.action === "skip") {
|
|
226
|
+
skipped++;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
ran++;
|
|
230
|
+
if (!opts.explain) {
|
|
231
|
+
await deps.runStep(scene, plan.step, cfg, videoPath);
|
|
232
|
+
rec[plan.step] = hashInputs(stepInputs(scene, plan.step), version);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
manifest.scenes[key] = rec;
|
|
236
|
+
allPlans.push(...plans);
|
|
237
|
+
}
|
|
238
|
+
if (!opts.explain) saveManifest(root, manifest);
|
|
239
|
+
return {
|
|
240
|
+
scenes: scenes.length,
|
|
241
|
+
ran,
|
|
242
|
+
skipped,
|
|
243
|
+
plans: allPlans
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/** Default step executor — the shipped commands. */
|
|
247
|
+
async function defaultRunStep(scene, step, cfg, videoPath) {
|
|
248
|
+
switch (step) {
|
|
249
|
+
case "narrate": {
|
|
250
|
+
const { narrateCommand } = await import("./narrate.js");
|
|
251
|
+
await narrateCommand({ input: scene });
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
case "sfx": {
|
|
255
|
+
const { prepareSfx } = await import("./sfx.js");
|
|
256
|
+
prepareSfx(sib(scene, ".sfx.json"));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
case "measure-loudness": {
|
|
260
|
+
const { measureLoudnessCommand } = await import("./loudness.js").then((n) => n.c);
|
|
261
|
+
await measureLoudnessCommand({ modulePath: scene });
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
case "render": {
|
|
265
|
+
const { render } = await import("./render.js").then((n) => n.p);
|
|
266
|
+
await render({
|
|
267
|
+
modulePath: scene,
|
|
268
|
+
out: videoPath,
|
|
269
|
+
...cfg.defaults?.fps !== void 0 ? { fps: cfg.defaults.fps } : {},
|
|
270
|
+
...cfg.defaults?.cache ? { cache: {
|
|
271
|
+
dir: cfg.defaults.cache,
|
|
272
|
+
mode: "read-write"
|
|
273
|
+
} } : {}
|
|
274
|
+
});
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
//#endregion
|
|
280
|
+
export { defineProject as n, build_exports as t };
|
package/dist/cacheVerify.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime.js";
|
|
2
2
|
import { o as loadSceneModule } from "./render.js";
|
|
3
|
-
import { i as capsId, n as FrameCache, o as frameCacheKey } from "./frameCache.js";
|
|
4
3
|
import { t as glissadeVersion } from "./version.js";
|
|
4
|
+
import { i as capsId, n as FrameCache, o as frameCacheKey } from "./frameCache.js";
|
|
5
5
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { join } from "node:path";
|
package/dist/cli.js
CHANGED
|
@@ -77,6 +77,7 @@ const USAGE = `usage:
|
|
|
77
77
|
gs fonts audit <scene-module> list registered families, formats, and missing-glyph runs (§3.6)
|
|
78
78
|
gs cache verify <scene-module> [--range a..b] [--sample <n>] assert cache hits == cold renders (§3.5)
|
|
79
79
|
gs mcp <scene-module> start an MCP stdio server for this scene: describe / list_targets / apply_patch / undo / render_frame (the AI-native write layer)
|
|
80
|
+
gs build [filter...] [--config <glissade.config.ts>] [--explain] content-graph DAG runner: narrate→sfx→loudness→render per scene, runs ONLY the stale subtree
|
|
80
81
|
|
|
81
82
|
render options:
|
|
82
83
|
--out <path> output directory for a PNG sequence, or .mp4/.webm (needs ffmpeg). default: ./out
|
|
@@ -167,7 +168,7 @@ narration-lint options (lint the committed *.narration.timing.json + the real ca
|
|
|
167
168
|
`;
|
|
168
169
|
async function main() {
|
|
169
170
|
const [command, ...rest] = process.argv.slice(2);
|
|
170
|
-
if (command !== "render" && command !== "diff" && command !== "verify-determinism" && command !== "dev" && command !== "import" && command !== "narrate" && command !== "narration-lint" && command !== "sfx" && command !== "prepare" && command !== "measure-loudness" && command !== "fonts" && command !== "cache" && command !== "mcp") {
|
|
171
|
+
if (command !== "render" && command !== "diff" && command !== "verify-determinism" && command !== "dev" && command !== "import" && command !== "narrate" && command !== "narration-lint" && command !== "sfx" && command !== "prepare" && command !== "measure-loudness" && command !== "fonts" && command !== "cache" && command !== "mcp" && command !== "build") {
|
|
171
172
|
console.error(USAGE);
|
|
172
173
|
process.exit(command === void 0 || command === "help" || command === "--help" ? 0 : 1);
|
|
173
174
|
}
|
|
@@ -190,6 +191,24 @@ async function main() {
|
|
|
190
191
|
}
|
|
191
192
|
return;
|
|
192
193
|
}
|
|
194
|
+
if (command === "build") {
|
|
195
|
+
const { positional: bp, flags: bf } = parseArgs(rest);
|
|
196
|
+
const { buildCommand } = await import("./build.js").then((n) => n.t);
|
|
197
|
+
const config = bf.get("config") || "glissade.config.ts";
|
|
198
|
+
const explain = bf.has("explain");
|
|
199
|
+
try {
|
|
200
|
+
const r = await buildCommand({
|
|
201
|
+
config,
|
|
202
|
+
explain,
|
|
203
|
+
...bp.length ? { only: bp } : {},
|
|
204
|
+
onLog: (line) => process.stderr.write(`${line}\n`)
|
|
205
|
+
});
|
|
206
|
+
process.stderr.write(`gs build: ${r.ran} step${r.ran === 1 ? "" : "s"} ${explain ? "WOULD run" : "ran"}, ${r.skipped} fresh, across ${r.scenes} scene${r.scenes === 1 ? "" : "s"}${explain ? " (--explain: nothing executed)" : ""}\n`);
|
|
207
|
+
} catch (err) {
|
|
208
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
193
212
|
if (command === "cache") {
|
|
194
213
|
const { positional: cp, flags: cf } = parseArgs(rest);
|
|
195
214
|
const sub = cp[0];
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/build.d.ts
|
|
2
|
+
|
|
3
|
+
interface ProjectConfig {
|
|
4
|
+
/** scene module paths or globs (`episodes/**\/*.ts`), relative to the config file. */
|
|
5
|
+
scenes: string[];
|
|
6
|
+
/** output dir for rendered videos (default: alongside each scene as `<base>.mp4`). */
|
|
7
|
+
out?: string;
|
|
8
|
+
/** per-scene render/cache defaults. */
|
|
9
|
+
defaults?: {
|
|
10
|
+
fps?: number;
|
|
11
|
+
cache?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Identity helper for a typed `glissade.config.ts` default export. */
|
|
15
|
+
declare function defineProject(config: ProjectConfig): ProjectConfig;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { type ProjectConfig, defineProject };
|
package/dist/config.js
ADDED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { a as ffmpegAvailable, d as render, f as renderLocales, i as collectAudioClips, l as parseLocalesList, m as resolveLoudnessGainDb, n as SceneModuleError, o as loadSceneModule, r as buildMixWav, s as localeOutPath, t as LocaleArgsError, u as planFinalAudio } from "./render.js";
|
|
2
|
+
import { t as glissadeVersion } from "./version.js";
|
|
2
3
|
import { a as computeGainDb, d as parseLoudnormJson, f as peakClampBinds, i as PUBLISH_PROFILES, l as measureFile, m as resolveProfile, n as LOUDNESS_SCHEMA_VERSION, o as computeMixHash, p as readLoudness, r as LoudnessError, s as loudnessPathFor, t as DEFAULT_PROFILE_ID, u as measureLoudnessCommand } from "./loudness.js";
|
|
3
4
|
import { a as pickEncoder, i as parseEncoderList, n as availableEncoders, t as NoEncoderError } from "./encoders.js";
|
|
4
5
|
import { a as splitFrameRange, n as renderSharded, r as sceneHasGpuNodes, t as ShardError } from "./shards.js";
|
|
@@ -10,6 +11,5 @@ import { t as importCommand } from "./import.js";
|
|
|
10
11
|
import { i as snapshotAt, r as evaluateAt, t as diffCommand } from "./diff.js";
|
|
11
12
|
import { a as fixDiff, c as lintNarration, n as lintTimingPathFor, o as formatTable, r as narrationLintCommand, s as hasErrors, t as buildCaptionProbe } from "./narrationLintCommand.js";
|
|
12
13
|
import { a as clearFrameCache, c as parseCacheMaxSize, i as capsId, l as probeEntryHeader, n as FrameCache, o as frameCacheKey, r as FrameCacheError, t as DEFAULT_CACHE_MAX_SIZE } from "./frameCache.js";
|
|
13
|
-
import { t as glissadeVersion } from "./version.js";
|
|
14
14
|
import { t as cacheVerifyCommand } from "./cacheVerify.js";
|
|
15
15
|
export { AudioMixError, DEFAULT_CACHE_MAX_SIZE, DEFAULT_PROFILE_ID, FfmpegVideoFrameSource, FrameCache, FrameCacheError, LOUDNESS_SCHEMA_VERSION, LocaleArgsError, LoudnessError, MachineExportError, NoEncoderError, PUBLISH_PROFILES, SceneModuleError, ShardError, VideoProbeError, applyMixGainDb, atempoChain, availableEncoders, buildCaptionProbe, buildMixWav, cacheVerifyCommand, capsId, clearFrameCache, collectAudioClips, computeGainDb, computeMixHash, dev, diffCommand, evaluateAt, ffmpegAvailable, fixDiff, formatTable, frameCacheKey, gainExpression, glissadeVersion, hasErrors, importCommand, lintNarration, lintTimingPathFor, loadSceneModule, localeOutPath, loudnessPathFor, measureFile, measureLoudnessCommand, narrationLintCommand, parseCacheMaxSize, parseEncoderList, parseLocalesList, parseLoudnormJson, peakClampBinds, pickEncoder, planAudioMix, planFinalAudio, probeEntryHeader, probeVideo, readLoudness, render, renderLocales, renderSharded, resolveAssetPath, resolveLoudnessGainDb, resolveProfile, resolveRenderDoc, sceneHasGpuNodes, snapshotAt, splitFrameRange };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0-pre.0",
|
|
4
4
|
"description": "glissade CLI: headless rendering via backend-skia (+ FFmpeg mux).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
".": {
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./config": {
|
|
19
|
+
"types": "./dist/config.d.ts",
|
|
20
|
+
"default": "./dist/config.js"
|
|
17
21
|
}
|
|
18
22
|
},
|
|
19
23
|
"files": [
|
|
@@ -24,15 +28,15 @@
|
|
|
24
28
|
"@napi-rs/canvas": "^0.1.65",
|
|
25
29
|
"esbuild": "0.28.0",
|
|
26
30
|
"jiti": "^2.4.2",
|
|
27
|
-
"@glissade/backend-skia": "0.
|
|
28
|
-
"@glissade/
|
|
29
|
-
"@glissade/
|
|
30
|
-
"@glissade/lottie": "0.
|
|
31
|
-
"@glissade/narrate": "0.
|
|
32
|
-
"@glissade/player": "0.
|
|
33
|
-
"@glissade/scene": "0.
|
|
34
|
-
"@glissade/sfx": "0.
|
|
35
|
-
"@glissade/svg": "0.
|
|
31
|
+
"@glissade/backend-skia": "0.29.0-pre.0",
|
|
32
|
+
"@glissade/interact": "0.29.0-pre.0",
|
|
33
|
+
"@glissade/core": "0.29.0-pre.0",
|
|
34
|
+
"@glissade/lottie": "0.29.0-pre.0",
|
|
35
|
+
"@glissade/narrate": "0.29.0-pre.0",
|
|
36
|
+
"@glissade/player": "0.29.0-pre.0",
|
|
37
|
+
"@glissade/scene": "0.29.0-pre.0",
|
|
38
|
+
"@glissade/sfx": "0.29.0-pre.0",
|
|
39
|
+
"@glissade/svg": "0.29.0-pre.0"
|
|
36
40
|
},
|
|
37
41
|
"repository": {
|
|
38
42
|
"type": "git",
|