@koda-sl/baker-cli 0.275.0-dev.1f1c09c80 → 0.277.0-dev.1f1c09c80
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
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
ulid,
|
|
59
59
|
validateCanvasDeep,
|
|
60
60
|
ytDlpBlockSignal
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-AUOSDGWY.js";
|
|
62
62
|
import {
|
|
63
63
|
csvOrJson,
|
|
64
64
|
daysAgoIso,
|
|
@@ -3699,14 +3699,22 @@ var avatarSummarySchema = z7.object({
|
|
|
3699
3699
|
subjectDescription: z7.string(),
|
|
3700
3700
|
/** The identity sheet to wire into `--reference`. Absent until the build settles. */
|
|
3701
3701
|
sheetUrl: z7.string().optional(),
|
|
3702
|
+
/**
|
|
3703
|
+
* The avatar's pinned voice.
|
|
3704
|
+
*
|
|
3705
|
+
* A casting essential, not a profile detail: an avatar is a face AND a voice, and
|
|
3706
|
+
* casting the face without it is what makes a presenter speak in somebody else's.
|
|
3707
|
+
* It lived only behind `--full`, so an ad that grounded every frame on the identity
|
|
3708
|
+
* sheet still had its lines read by a voice cast from a prose description.
|
|
3709
|
+
*/
|
|
3710
|
+
voiceId: z7.string().optional(),
|
|
3711
|
+
voiceDescription: z7.string().optional(),
|
|
3702
3712
|
coverUrl: z7.string().optional(),
|
|
3703
3713
|
errorMessage: z7.string().optional()
|
|
3704
3714
|
});
|
|
3705
3715
|
var avatarDetailSchema = avatarSummarySchema.extend({
|
|
3706
3716
|
profile: avatarProfileSchema,
|
|
3707
3717
|
sourceUrls: z7.array(z7.string()),
|
|
3708
|
-
voiceId: z7.string().optional(),
|
|
3709
|
-
voiceDescription: z7.string().optional(),
|
|
3710
3718
|
createdAt: z7.number()
|
|
3711
3719
|
});
|
|
3712
3720
|
var avatarsListRequestSchema = z7.object({
|
|
@@ -28705,7 +28713,7 @@ function buildPhrases(blueprint, canonical2, compositeScenes, presenterPresent,
|
|
|
28705
28713
|
flush();
|
|
28706
28714
|
return phrases;
|
|
28707
28715
|
}
|
|
28708
|
-
function makeVoiceFactory(blueprint, canonical2, nodes, voiceLanguage) {
|
|
28716
|
+
function makeVoiceFactory(blueprint, canonical2, nodes, voiceLanguage, pinnedVoiceId) {
|
|
28709
28717
|
const bySpeaker = /* @__PURE__ */ new Map();
|
|
28710
28718
|
const describe = (speaker) => {
|
|
28711
28719
|
for (const scene of blueprint.scenes)
|
|
@@ -28721,7 +28729,9 @@ function makeVoiceFactory(blueprint, canonical2, nodes, voiceLanguage) {
|
|
|
28721
28729
|
const description = describe(speaker);
|
|
28722
28730
|
const traits = parseVoiceTraits(description);
|
|
28723
28731
|
if (voiceLanguage) traits.language = voiceLanguage;
|
|
28724
|
-
nodes.push(
|
|
28732
|
+
nodes.push(
|
|
28733
|
+
pinnedVoiceId ? { id, type: "voice_select", params: { description, voice_id: pinnedVoiceId, ...traits } } : { id, type: "voice_select", params: { description, ...traits } }
|
|
28734
|
+
);
|
|
28725
28735
|
bySpeaker.set(speaker, id);
|
|
28726
28736
|
return id;
|
|
28727
28737
|
};
|
|
@@ -29122,7 +29132,7 @@ function buildTimeline(blueprint, slots, opts, nodes) {
|
|
|
29122
29132
|
});
|
|
29123
29133
|
}
|
|
29124
29134
|
const canonical2 = collapseVoiceover(blueprint);
|
|
29125
|
-
const ensureVoiceNode = makeVoiceFactory(blueprint, canonical2, nodes, opts.voiceLanguage);
|
|
29135
|
+
const ensureVoiceNode = makeVoiceFactory(blueprint, canonical2, nodes, opts.voiceLanguage, opts.voiceId);
|
|
29126
29136
|
const aspect = resolveAspect(blueprint.source?.aspect_ratio, opts.aspect, genAspectsFor(opts.videoModel));
|
|
29127
29137
|
const env = {
|
|
29128
29138
|
blueprint,
|
|
@@ -31002,7 +31012,7 @@ function classifyReelFindings(json) {
|
|
|
31002
31012
|
if (!r.brand_mark_visible) {
|
|
31003
31013
|
findings.push({
|
|
31004
31014
|
severity: "warning",
|
|
31005
|
-
what: "No brand mark is visible in any frame.
|
|
31015
|
+
what: "No brand mark is visible in any frame. THIS IS NOT A RE-RENDER: the mark is drawn by the caption composition as an ordinary `<img>`, never generated as a picture \u2014 so fix the mark itself (a bad path, or an SVG whose geometry clips its own wordmark) or the `.brand-mark` / `.endcard-logo` rules in `<composition>/index.html`, then re-run. Every clip comes back from the cache and only the composition pass renders again, so it costs seconds and no generation."
|
|
31006
31016
|
});
|
|
31007
31017
|
}
|
|
31008
31018
|
if (!r.shows_more_than_a_face) {
|
|
@@ -31429,7 +31439,7 @@ ${describeRewrites(healed.rewrites)}
|
|
|
31429
31439
|
`Reviewed the finished video and found ${review.length} thing${review.length === 1 ? "" : "s"} to fix. Show the user what is wrong before you show them the ad.`,
|
|
31430
31440
|
...review.map((f) => `${f.severity === "blocking" ? "MUST FIX" : "SHOULD FIX"} \u2014 ${f.what}`),
|
|
31431
31441
|
...review.some((f) => f.scene) ? [
|
|
31432
|
-
`Fix them, then re-run: edit the \`show\` of the scene files named above \u2014 a shot with a person handling equipment is where limbs and objects go wrong, so widen it, move the hands out of frame, or drop the person from that beat. Re-running re-renders ONLY the scenes you edited; everything else comes from the cache (this run: ${result.stats?.cached_nodes ?? 0} of ${result.stats?.total_nodes ?? 0} nodes were cached).`
|
|
31442
|
+
`Anything about the MARK or the closing card is a composition fix, not a re-render: both are drawn as HTML by the caption composition, so editing it and re-running re-renders only that pass \u2014 the clips are cached and no generation is paid for again. Fix them, then re-run: edit the \`show\` of the scene files named above \u2014 a shot with a person handling equipment is where limbs and objects go wrong, so widen it, move the hands out of frame, or drop the person from that beat. Re-running re-renders ONLY the scenes you edited; everything else comes from the cache (this run: ${result.stats?.cached_nodes ?? 0} of ${result.stats?.total_nodes ?? 0} nodes were cached).`
|
|
31433
31443
|
] : []
|
|
31434
31444
|
] : [];
|
|
31435
31445
|
if (poster) {
|
|
@@ -32775,7 +32785,8 @@ function adSpecCastElements(spec, avatar) {
|
|
|
32775
32785
|
function motionPrompt(beat, isClosingCard, place, physics) {
|
|
32776
32786
|
if (isClosingCard) return BRAND_PLATE;
|
|
32777
32787
|
const shot = `${beat.show}${place}${physics}`;
|
|
32778
|
-
|
|
32788
|
+
if (beat.on_camera) return shot;
|
|
32789
|
+
return `${shot} Nobody in frame is speaking: mouths CLOSED and STILL throughout, no talking, no lip movement. Whoever is in shot is looking, reacting or working \u2014 never addressing the camera.`;
|
|
32779
32790
|
}
|
|
32780
32791
|
function staticTranscript(spec) {
|
|
32781
32792
|
const out = [];
|
|
@@ -32864,6 +32875,7 @@ function adSpecToBlueprint(spec) {
|
|
|
32864
32875
|
}
|
|
32865
32876
|
|
|
32866
32877
|
// src/engine/scaffold/ad-brand-overlay.ts
|
|
32878
|
+
var markFallback = (name) => name.trim() ? ` onerror="this.replaceWith(Object.assign(document.createElement('span'),{className:this.className+' brand-wordmark',textContent:${JSON.stringify(name.trim())}}))"` : "";
|
|
32867
32879
|
var escapeHtml2 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
32868
32880
|
function firstHex(palette) {
|
|
32869
32881
|
const hex = (palette ?? []).find((h) => /^#?[0-9a-fA-F]{6}$/.test(h.trim()));
|
|
@@ -32883,12 +32895,14 @@ function buildAdBrandOverlay(opts) {
|
|
|
32883
32895
|
];
|
|
32884
32896
|
if (logo) {
|
|
32885
32897
|
parts.push(
|
|
32886
|
-
`<img class="clip brand-mark" src="${escapeHtml2(logo.file)}" alt="${escapeHtml2(logo.alt)}" data-start="0" data-dur="${totalS}" />`
|
|
32898
|
+
`<img class="clip brand-mark" src="${escapeHtml2(logo.file)}" alt="${escapeHtml2(logo.alt)}" data-start="0" data-dur="${totalS}"${markFallback(logo.alt)} />`
|
|
32887
32899
|
);
|
|
32888
32900
|
}
|
|
32889
32901
|
const cardBits = [];
|
|
32890
32902
|
if (logo) {
|
|
32891
|
-
cardBits.push(
|
|
32903
|
+
cardBits.push(
|
|
32904
|
+
`<img class="endcard-logo" src="${escapeHtml2(logo.file)}" alt="${escapeHtml2(logo.alt)}"${markFallback(logo.alt)} />`
|
|
32905
|
+
);
|
|
32892
32906
|
}
|
|
32893
32907
|
if (cta?.trim()) {
|
|
32894
32908
|
const style = accent ? ` style="background:${escapeHtml2(accent)}"` : "";
|
|
@@ -32959,6 +32973,11 @@ function adBrandOverlayCss() {
|
|
|
32959
32973
|
" .endcard-logo { width: 62%; height: auto; max-height: 300px; object-fit: contain;",
|
|
32960
32974
|
" padding: 46px 56px; border-radius: 40px; background: rgba(255,255,255,0.96);",
|
|
32961
32975
|
" box-shadow: 0 10px 40px rgba(0,0,0,0.28); }",
|
|
32976
|
+
" /* The name, when the mark itself could not be drawn. */",
|
|
32977
|
+
" .brand-wordmark { display: inline-block; font-family: 'Arial Black', 'Helvetica Neue', Arial, sans-serif;",
|
|
32978
|
+
" font-weight: 900; color: #14231b; letter-spacing: -0.01em; }",
|
|
32979
|
+
" .brand-mark.brand-wordmark { font-size: 34px; line-height: 1; height: auto; }",
|
|
32980
|
+
" .endcard-logo.brand-wordmark { font-size: 96px; line-height: 1; width: auto; }",
|
|
32962
32981
|
" /* Capped and wrapping, not sized to its content: measured in a real browser,",
|
|
32963
32982
|
" `GET YOUR FREE QUOTE` renders 948px wide against a 1080px canvas, so the next",
|
|
32964
32983
|
" slightly longer call to action runs off the frame. Two lines beat an edge. */",
|
|
@@ -33211,6 +33230,10 @@ var scaffoldAdCommand = defineCommand104({
|
|
|
33211
33230
|
// Told, not guessed: the voice description is written in the ad's own language
|
|
33212
33231
|
// and the engine's trait parser reads English only.
|
|
33213
33232
|
voiceLanguage: voiceLanguageFor(spec.data),
|
|
33233
|
+
// The cast avatar's own voice. An avatar is a face AND a voice; grounding every
|
|
33234
|
+
// frame on their identity sheet while a separately cast voice reads the lines is
|
|
33235
|
+
// how a presenter ends up speaking in somebody else's.
|
|
33236
|
+
...avatar?.voiceId ? { voiceId: avatar.voiceId } : {},
|
|
33214
33237
|
...spec.data.voiceover === false ? { staticTranscriptPath: path24.relative(outDir, transcriptPath) } : {}
|
|
33215
33238
|
};
|
|
33216
33239
|
const canvas = scaffoldVideoCanvas(blueprint, adSpecCastElements(spec.data, avatar), opts);
|
|
@@ -33264,6 +33287,9 @@ var scaffoldAdCommand = defineCommand104({
|
|
|
33264
33287
|
] : [],
|
|
33265
33288
|
...avatarError ? [avatarError] : [],
|
|
33266
33289
|
...avatar ? [
|
|
33290
|
+
...avatar?.voiceId ? [] : [
|
|
33291
|
+
`Avatar \`${handle}\` has no pinned voice, so the ad's lines are read by a voice cast from a description \u2014 it will not sound like them. Give them one (\`baker avatars\` voice) before this ships.`
|
|
33292
|
+
],
|
|
33267
33293
|
`Every beat the customer appears in is grounded on \`${handle}\`'s identity sheet, and their subject description was copied into the frames verbatim \u2014 so it is the same face throughout and the same face as the rest of this company's work.`
|
|
33268
33294
|
] : [],
|
|
33269
33295
|
...presenterIsInEveryShot(spec.data) ? [
|