@koda-sl/baker-cli 0.39.29 → 0.66.2
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 +1754 -7
- package/canvas/avocado-tutorial.json +89 -0
- package/canvas/hello-world-composition/index.html +83 -0
- package/canvas/hello-world-composition/meta.json +41 -0
- package/canvas/hello-world-overlay.json +37 -0
- package/canvas/phone-scroll-composition/index.html +141 -0
- package/canvas/phone-scroll-composition/meta.json +39 -0
- package/canvas/tiktok-captions-composition/index.html +126 -0
- package/canvas/tiktok-captions-composition/meta.json +46 -0
- package/canvas/video-overlay-composition/index.html +239 -0
- package/canvas/video-overlay-composition/meta.json +29 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/ads/meta/creatives.js +1 -1
- package/dist/commands/canvas/catalog.d.ts +2 -0
- package/dist/commands/canvas/catalog.d.ts.map +1 -0
- package/dist/commands/canvas/catalog.js +13 -0
- package/dist/commands/canvas/catalog.js.map +1 -0
- package/dist/commands/canvas/index.d.ts +2 -0
- package/dist/commands/canvas/index.d.ts.map +1 -0
- package/dist/commands/canvas/index.js +32 -0
- package/dist/commands/canvas/index.js.map +1 -0
- package/dist/commands/canvas/inspect.d.ts +16 -0
- package/dist/commands/canvas/inspect.d.ts.map +1 -0
- package/dist/commands/canvas/inspect.js +115 -0
- package/dist/commands/canvas/inspect.js.map +1 -0
- package/dist/commands/canvas/run.d.ts +24 -0
- package/dist/commands/canvas/run.d.ts.map +1 -0
- package/dist/commands/canvas/run.js +56 -0
- package/dist/commands/canvas/run.js.map +1 -0
- package/dist/commands/canvas/scaffold-static-ad.d.ts +40 -0
- package/dist/commands/canvas/scaffold-static-ad.d.ts.map +1 -0
- package/dist/commands/canvas/scaffold-static-ad.js +265 -0
- package/dist/commands/canvas/scaffold-static-ad.js.map +1 -0
- package/dist/commands/canvas/scaffold-video.d.ts +44 -0
- package/dist/commands/canvas/scaffold-video.d.ts.map +1 -0
- package/dist/commands/canvas/scaffold-video.js +235 -0
- package/dist/commands/canvas/scaffold-video.js.map +1 -0
- package/dist/commands/canvas/validate.d.ts +8 -0
- package/dist/commands/canvas/validate.d.ts.map +1 -0
- package/dist/commands/canvas/validate.js +37 -0
- package/dist/commands/canvas/validate.js.map +1 -0
- package/dist/commands/images/find.d.ts +1 -1
- package/dist/commands/images/find.d.ts.map +1 -1
- package/dist/commands/images/find.js +12 -3
- package/dist/commands/images/find.js.map +1 -1
- package/dist/commands/images/google.d.ts +1 -1
- package/dist/commands/images/google.d.ts.map +1 -1
- package/dist/commands/images/google.js +12 -3
- package/dist/commands/images/google.js.map +1 -1
- package/dist/commands/images/stock.d.ts +1 -1
- package/dist/commands/images/stock.d.ts.map +1 -1
- package/dist/commands/images/stock.js +7 -3
- package/dist/commands/images/stock.js.map +1 -1
- package/dist/engine/client/backend-client.d.ts +50 -0
- package/dist/engine/client/backend-client.d.ts.map +1 -0
- package/dist/engine/client/backend-client.js +20 -0
- package/dist/engine/client/backend-client.js.map +1 -0
- package/dist/engine/client/env.d.ts +7 -0
- package/dist/engine/client/env.d.ts.map +1 -0
- package/dist/engine/client/env.js +18 -0
- package/dist/engine/client/env.js.map +1 -0
- package/dist/engine/client/http.d.ts +56 -0
- package/dist/engine/client/http.d.ts.map +1 -0
- package/dist/engine/client/http.js +168 -0
- package/dist/engine/client/http.js.map +1 -0
- package/dist/engine/engine/cache-key.d.ts +19 -0
- package/dist/engine/engine/cache-key.d.ts.map +1 -0
- package/dist/engine/engine/cache-key.js +33 -0
- package/dist/engine/engine/cache-key.js.map +1 -0
- package/dist/engine/engine/canonical.d.ts +14 -0
- package/dist/engine/engine/canonical.d.ts.map +1 -0
- package/dist/engine/engine/canonical.js +53 -0
- package/dist/engine/engine/canonical.js.map +1 -0
- package/dist/engine/engine/composition-hash.d.ts +14 -0
- package/dist/engine/engine/composition-hash.d.ts.map +1 -0
- package/dist/engine/engine/composition-hash.js +51 -0
- package/dist/engine/engine/composition-hash.js.map +1 -0
- package/dist/engine/engine/composition-meta.d.ts +77 -0
- package/dist/engine/engine/composition-meta.d.ts.map +1 -0
- package/dist/engine/engine/composition-meta.js +199 -0
- package/dist/engine/engine/composition-meta.js.map +1 -0
- package/dist/engine/engine/context.d.ts +16 -0
- package/dist/engine/engine/context.d.ts.map +1 -0
- package/dist/engine/engine/context.js +2 -0
- package/dist/engine/engine/context.js.map +1 -0
- package/dist/engine/engine/define.d.ts +69 -0
- package/dist/engine/engine/define.d.ts.map +1 -0
- package/dist/engine/engine/define.js +9 -0
- package/dist/engine/engine/define.js.map +1 -0
- package/dist/engine/engine/didyoumean.d.ts +2 -0
- package/dist/engine/engine/didyoumean.d.ts.map +1 -0
- package/dist/engine/engine/didyoumean.js +58 -0
- package/dist/engine/engine/didyoumean.js.map +1 -0
- package/dist/engine/engine/errors.d.ts +41 -0
- package/dist/engine/engine/errors.d.ts.map +1 -0
- package/dist/engine/engine/errors.js +45 -0
- package/dist/engine/engine/errors.js.map +1 -0
- package/dist/engine/engine/executor.d.ts +72 -0
- package/dist/engine/engine/executor.d.ts.map +1 -0
- package/dist/engine/engine/executor.js +445 -0
- package/dist/engine/engine/executor.js.map +1 -0
- package/dist/engine/engine/refs.d.ts +12 -0
- package/dist/engine/engine/refs.d.ts.map +1 -0
- package/dist/engine/engine/refs.js +48 -0
- package/dist/engine/engine/refs.js.map +1 -0
- package/dist/engine/engine/registry.d.ts +11 -0
- package/dist/engine/engine/registry.d.ts.map +1 -0
- package/dist/engine/engine/registry.js +26 -0
- package/dist/engine/engine/registry.js.map +1 -0
- package/dist/engine/engine/scheduler.d.ts +10 -0
- package/dist/engine/engine/scheduler.d.ts.map +1 -0
- package/dist/engine/engine/scheduler.js +89 -0
- package/dist/engine/engine/scheduler.js.map +1 -0
- package/dist/engine/engine/validator.d.ts +31 -0
- package/dist/engine/engine/validator.d.ts.map +1 -0
- package/dist/engine/engine/validator.js +501 -0
- package/dist/engine/engine/validator.js.map +1 -0
- package/dist/engine/index.d.ts +33 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +104 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/lib/ulid.d.ts +3 -0
- package/dist/engine/lib/ulid.d.ts.map +1 -0
- package/dist/engine/lib/ulid.js +36 -0
- package/dist/engine/lib/ulid.js.map +1 -0
- package/dist/engine/models/canvas-ad-params.test.d.ts +2 -0
- package/dist/engine/models/canvas-ad-params.test.d.ts.map +1 -0
- package/dist/engine/models/canvas-ad-params.test.js +60 -0
- package/dist/engine/models/canvas-ad-params.test.js.map +1 -0
- package/dist/engine/models/registry.d.ts +63 -0
- package/dist/engine/models/registry.d.ts.map +1 -0
- package/dist/engine/models/registry.js +432 -0
- package/dist/engine/models/registry.js.map +1 -0
- package/dist/engine/models/validateParams.d.ts +38 -0
- package/dist/engine/models/validateParams.d.ts.map +1 -0
- package/dist/engine/models/validateParams.js +166 -0
- package/dist/engine/models/validateParams.js.map +1 -0
- package/dist/engine/nodes/ingest.d.ts +113 -0
- package/dist/engine/nodes/ingest.d.ts.map +1 -0
- package/dist/engine/nodes/ingest.js +555 -0
- package/dist/engine/nodes/ingest.js.map +1 -0
- package/dist/engine/nodes/ingest.svg.test.d.ts +2 -0
- package/dist/engine/nodes/ingest.svg.test.d.ts.map +1 -0
- package/dist/engine/nodes/ingest.svg.test.js +30 -0
- package/dist/engine/nodes/ingest.svg.test.js.map +1 -0
- package/dist/engine/nodes/local/audioTimeline.d.ts +82 -0
- package/dist/engine/nodes/local/audioTimeline.d.ts.map +1 -0
- package/dist/engine/nodes/local/audioTimeline.js +97 -0
- package/dist/engine/nodes/local/audioTimeline.js.map +1 -0
- package/dist/engine/nodes/local/ffmpeg.d.ts +56 -0
- package/dist/engine/nodes/local/ffmpeg.d.ts.map +1 -0
- package/dist/engine/nodes/local/ffmpeg.js +50 -0
- package/dist/engine/nodes/local/ffmpeg.js.map +1 -0
- package/dist/engine/nodes/local/fontSpecimen.d.ts +50 -0
- package/dist/engine/nodes/local/fontSpecimen.d.ts.map +1 -0
- package/dist/engine/nodes/local/fontSpecimen.js +198 -0
- package/dist/engine/nodes/local/fontSpecimen.js.map +1 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.d.ts +116 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.d.ts.map +1 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.js +230 -0
- package/dist/engine/nodes/local/hyperframe-snapshot.js.map +1 -0
- package/dist/engine/nodes/local/hyperframe.d.ts +123 -0
- package/dist/engine/nodes/local/hyperframe.d.ts.map +1 -0
- package/dist/engine/nodes/local/hyperframe.js +367 -0
- package/dist/engine/nodes/local/hyperframe.js.map +1 -0
- package/dist/engine/nodes/local/imagemagick.d.ts +56 -0
- package/dist/engine/nodes/local/imagemagick.d.ts.map +1 -0
- package/dist/engine/nodes/local/imagemagick.js +71 -0
- package/dist/engine/nodes/local/imagemagick.js.map +1 -0
- package/dist/engine/nodes/local/lib/assets.d.ts +20 -0
- package/dist/engine/nodes/local/lib/assets.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/assets.js +40 -0
- package/dist/engine/nodes/local/lib/assets.js.map +1 -0
- package/dist/engine/nodes/local/lib/cli-runner.d.ts +78 -0
- package/dist/engine/nodes/local/lib/cli-runner.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/cli-runner.js +254 -0
- package/dist/engine/nodes/local/lib/cli-runner.js.map +1 -0
- package/dist/engine/nodes/local/lib/ffmpeg.d.ts +23 -0
- package/dist/engine/nodes/local/lib/ffmpeg.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/ffmpeg.js +75 -0
- package/dist/engine/nodes/local/lib/ffmpeg.js.map +1 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts +2 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.js +47 -0
- package/dist/engine/nodes/local/lib/hyperframe-errors.js.map +1 -0
- package/dist/engine/nodes/local/lib/templating.d.ts +22 -0
- package/dist/engine/nodes/local/lib/templating.d.ts.map +1 -0
- package/dist/engine/nodes/local/lib/templating.js +85 -0
- package/dist/engine/nodes/local/lib/templating.js.map +1 -0
- package/dist/engine/nodes/local/text.d.ts +6 -0
- package/dist/engine/nodes/local/text.d.ts.map +1 -0
- package/dist/engine/nodes/local/text.js +15 -0
- package/dist/engine/nodes/local/text.js.map +1 -0
- package/dist/engine/nodes/remote/delegate.d.ts +25 -0
- package/dist/engine/nodes/remote/delegate.d.ts.map +1 -0
- package/dist/engine/nodes/remote/delegate.js +160 -0
- package/dist/engine/nodes/remote/delegate.js.map +1 -0
- package/dist/engine/nodes/remote/dialogue.d.ts +34 -0
- package/dist/engine/nodes/remote/dialogue.d.ts.map +1 -0
- package/dist/engine/nodes/remote/dialogue.js +54 -0
- package/dist/engine/nodes/remote/dialogue.js.map +1 -0
- package/dist/engine/nodes/remote/image.d.ts +42 -0
- package/dist/engine/nodes/remote/image.d.ts.map +1 -0
- package/dist/engine/nodes/remote/image.js +43 -0
- package/dist/engine/nodes/remote/image.js.map +1 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.d.ts +30 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.js +42 -0
- package/dist/engine/nodes/remote/imageAspectAdapt.js.map +1 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts +39 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.js +37 -0
- package/dist/engine/nodes/remote/imageBackgroundRemove.js.map +1 -0
- package/dist/engine/nodes/remote/imageDescribe.d.ts +29 -0
- package/dist/engine/nodes/remote/imageDescribe.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageDescribe.js +25 -0
- package/dist/engine/nodes/remote/imageDescribe.js.map +1 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.d.ts +34 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.js +38 -0
- package/dist/engine/nodes/remote/imageReferenceSheet.js.map +1 -0
- package/dist/engine/nodes/remote/imageSearch.d.ts +18 -0
- package/dist/engine/nodes/remote/imageSearch.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageSearch.js +22 -0
- package/dist/engine/nodes/remote/imageSearch.js.map +1 -0
- package/dist/engine/nodes/remote/imageSelect.d.ts +39 -0
- package/dist/engine/nodes/remote/imageSelect.d.ts.map +1 -0
- package/dist/engine/nodes/remote/imageSelect.js +45 -0
- package/dist/engine/nodes/remote/imageSelect.js.map +1 -0
- package/dist/engine/nodes/remote/music.d.ts +45 -0
- package/dist/engine/nodes/remote/music.d.ts.map +1 -0
- package/dist/engine/nodes/remote/music.js +73 -0
- package/dist/engine/nodes/remote/music.js.map +1 -0
- package/dist/engine/nodes/remote/soundEffect.d.ts +21 -0
- package/dist/engine/nodes/remote/soundEffect.d.ts.map +1 -0
- package/dist/engine/nodes/remote/soundEffect.js +41 -0
- package/dist/engine/nodes/remote/soundEffect.js.map +1 -0
- package/dist/engine/nodes/remote/textGenerate.d.ts +21 -0
- package/dist/engine/nodes/remote/textGenerate.d.ts.map +1 -0
- package/dist/engine/nodes/remote/textGenerate.js +27 -0
- package/dist/engine/nodes/remote/textGenerate.js.map +1 -0
- package/dist/engine/nodes/remote/tts.d.ts +45 -0
- package/dist/engine/nodes/remote/tts.d.ts.map +1 -0
- package/dist/engine/nodes/remote/tts.js +66 -0
- package/dist/engine/nodes/remote/tts.js.map +1 -0
- package/dist/engine/nodes/remote/video.d.ts +58 -0
- package/dist/engine/nodes/remote/video.d.ts.map +1 -0
- package/dist/engine/nodes/remote/video.js +44 -0
- package/dist/engine/nodes/remote/video.js.map +1 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts +30 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.js +29 -0
- package/dist/engine/nodes/remote/videoBackgroundRemove.js.map +1 -0
- package/dist/engine/nodes/remote/videoDeconstruct.d.ts +61 -0
- package/dist/engine/nodes/remote/videoDeconstruct.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoDeconstruct.js +40 -0
- package/dist/engine/nodes/remote/videoDeconstruct.js.map +1 -0
- package/dist/engine/nodes/remote/videoLipsync.d.ts +37 -0
- package/dist/engine/nodes/remote/videoLipsync.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoLipsync.js +26 -0
- package/dist/engine/nodes/remote/videoLipsync.js.map +1 -0
- package/dist/engine/nodes/remote/videoTranscribe.d.ts +116 -0
- package/dist/engine/nodes/remote/videoTranscribe.d.ts.map +1 -0
- package/dist/engine/nodes/remote/videoTranscribe.js +123 -0
- package/dist/engine/nodes/remote/videoTranscribe.js.map +1 -0
- package/dist/engine/nodes/remote/voiceSelect.d.ts +28 -0
- package/dist/engine/nodes/remote/voiceSelect.d.ts.map +1 -0
- package/dist/engine/nodes/remote/voiceSelect.js +25 -0
- package/dist/engine/nodes/remote/voiceSelect.js.map +1 -0
- package/dist/engine/scaffold/staticAd.d.ts +44 -0
- package/dist/engine/scaffold/staticAd.d.ts.map +1 -0
- package/dist/engine/scaffold/staticAd.js +243 -0
- package/dist/engine/scaffold/staticAd.js.map +1 -0
- package/dist/engine/scaffold/video.d.ts +56 -0
- package/dist/engine/scaffold/video.d.ts.map +1 -0
- package/dist/engine/scaffold/video.js +709 -0
- package/dist/engine/scaffold/video.js.map +1 -0
- package/dist/engine/schema/canvas.d.ts +41 -0
- package/dist/engine/schema/canvas.d.ts.map +1 -0
- package/dist/engine/schema/canvas.js +67 -0
- package/dist/engine/schema/canvas.js.map +1 -0
- package/dist/engine/schema/catalog.d.ts +25 -0
- package/dist/engine/schema/catalog.d.ts.map +1 -0
- package/dist/engine/schema/catalog.js +48 -0
- package/dist/engine/schema/catalog.js.map +1 -0
- package/dist/engine/schema/primitives.d.ts +6 -0
- package/dist/engine/schema/primitives.d.ts.map +1 -0
- package/dist/engine/schema/primitives.js +4 -0
- package/dist/engine/schema/primitives.js.map +1 -0
- package/dist/engine/schema/prompts.d.ts +4 -0
- package/dist/engine/schema/prompts.d.ts.map +1 -0
- package/dist/engine/schema/prompts.js +23 -0
- package/dist/engine/schema/prompts.js.map +1 -0
- package/dist/engine/schema/refs.d.ts +113 -0
- package/dist/engine/schema/refs.d.ts.map +1 -0
- package/dist/engine/schema/refs.js +35 -0
- package/dist/engine/schema/refs.js.map +1 -0
- package/dist/engine/storage/asset-store.d.ts +48 -0
- package/dist/engine/storage/asset-store.d.ts.map +1 -0
- package/dist/engine/storage/asset-store.js +166 -0
- package/dist/engine/storage/asset-store.js.map +1 -0
- package/dist/engine/storage/cache-store.d.ts +21 -0
- package/dist/engine/storage/cache-store.d.ts.map +1 -0
- package/dist/engine/storage/cache-store.js +31 -0
- package/dist/engine/storage/cache-store.js.map +1 -0
- package/dist/engine/storage/output-writer.d.ts +18 -0
- package/dist/engine/storage/output-writer.d.ts.map +1 -0
- package/dist/engine/storage/output-writer.js +52 -0
- package/dist/engine/storage/output-writer.js.map +1 -0
- package/dist/engine/storage/sha256.d.ts +2 -0
- package/dist/engine/storage/sha256.d.ts.map +1 -0
- package/dist/engine/storage/sha256.js +7 -0
- package/dist/engine/storage/sha256.js.map +1 -0
- package/package.json +15 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const scaffoldStaticAdCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly file: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly required: true;
|
|
5
|
+
readonly description: "Path to the source/inspiration image";
|
|
6
|
+
};
|
|
7
|
+
readonly context: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly description: "Known provenance (advertiser, category, market) to ground the describe";
|
|
10
|
+
};
|
|
11
|
+
readonly out: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly description: "Output canvas path (default <image-dir>/static-ad.canvas.json)";
|
|
14
|
+
};
|
|
15
|
+
readonly "describe-model": {
|
|
16
|
+
readonly type: "string";
|
|
17
|
+
readonly description: "Override the image_describe model id";
|
|
18
|
+
};
|
|
19
|
+
readonly "select-model": {
|
|
20
|
+
readonly type: "string";
|
|
21
|
+
readonly description: "Override the text_generate model id for element selection";
|
|
22
|
+
};
|
|
23
|
+
readonly "layout-model": {
|
|
24
|
+
readonly type: "string";
|
|
25
|
+
readonly description: "Override the text_generate model id for the layout pass";
|
|
26
|
+
};
|
|
27
|
+
readonly "gen-model": {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly description: "Override the image_generate model id";
|
|
30
|
+
};
|
|
31
|
+
readonly aspect: {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
readonly description: "Force the output aspect ratio (else inferred from the image)";
|
|
34
|
+
};
|
|
35
|
+
readonly "skip-font": {
|
|
36
|
+
readonly type: "boolean";
|
|
37
|
+
readonly description: "Skip the brand-font → type-specimen slot";
|
|
38
|
+
};
|
|
39
|
+
}>;
|
|
40
|
+
//# sourceMappingURL=scaffold-static-ad.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-static-ad.d.ts","sourceRoot":"","sources":["../../../src/commands/canvas/scaffold-static-ad.ts"],"names":[],"mappings":"AAoNA,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0GlC,CAAC"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { defineCommand } from "citty";
|
|
4
|
+
import { createEngineFromEnv, defaultRegistry, ValidationError, validateCanvasDeep } from "../../engine/index.js";
|
|
5
|
+
import { MODEL_REGISTRY } from "../../engine/models/registry.js";
|
|
6
|
+
import { annotateBlueprintWithLabels, scaffoldStaticAd, staticAdReport, } from "../../engine/scaffold/staticAd.js";
|
|
7
|
+
/** Pick a sensible default model id for a node kind, preferring `preferred` when the registry still has it. */
|
|
8
|
+
function resolveModel(kind, preferred) {
|
|
9
|
+
const ids = Object.keys(MODEL_REGISTRY[kind]);
|
|
10
|
+
return ids.includes(preferred) ? preferred : (ids[0] ?? preferred);
|
|
11
|
+
}
|
|
12
|
+
const DESCRIBE_FOCUS = "the GLOBAL LAYOUT GEOMETRY above all — the column/row grid, each region's approximate bounds as a percentage of " +
|
|
13
|
+
"frame width and height, any panel SPLITS and their proportions (e.g. a left column split into a ~60% top photo and " +
|
|
14
|
+
"a ~20% bottom price box), what occupies every region, and for EVERY text block its string verbatim, relative size " +
|
|
15
|
+
"(x_large | large | medium | small), weight, case, color, and alignment — including small bottom-corner fine print. " +
|
|
16
|
+
"Also: the EXPRESSION and emotion of every person/animal (capture exaggerated or AI-edited faces), the ad_intent " +
|
|
17
|
+
"(what feeling it engineers and how), per-color brand_ownership (which colors are the advertiser's brand vs " +
|
|
18
|
+
"borrowed-functional like a red comparison column), logos by brand, and all visible text verbatim";
|
|
19
|
+
const LAYOUT_SYSTEM = "You convert an advertisement's JSON blueprint into a precise, structured LAYOUT MAP of the frame — the spatial grid " +
|
|
20
|
+
"a designer would rebuild it from. Be exhaustive and quantitative: every region, its bounds as a percentage of the " +
|
|
21
|
+
"frame, and every text block with its relative size. Output ONLY a JSON object, no prose.";
|
|
22
|
+
const LAYOUT_PROMPT = "AD BLUEPRINT (from image_describe):\n{{blueprint}}\n\n" +
|
|
23
|
+
"Return a JSON object describing the GLOBAL LAYOUT of the frame precisely enough to rebuild it:\n" +
|
|
24
|
+
'{ "grid": short summary (e.g. "3 equal vertical columns; left column split top/bottom"),\n' +
|
|
25
|
+
' "columns": <int>, "rows": <int or null>,\n' +
|
|
26
|
+
' "regions": [ {\n' +
|
|
27
|
+
' "id": short slug (e.g. "col1-top"),\n' +
|
|
28
|
+
' "x_pct": [left, right], // 0-100 of frame width\n' +
|
|
29
|
+
' "y_pct": [top, bottom], // 0-100 of frame height\n' +
|
|
30
|
+
' "kind": "image" | "text_block" | "badge" | "logo" | "shape" | "background",\n' +
|
|
31
|
+
' "content": what is here (name the subject/badge; reuse its description),\n' +
|
|
32
|
+
' "background_color": hex or null,\n' +
|
|
33
|
+
' "shape": e.g. "rounded-rectangle" | "pill" | null,\n' +
|
|
34
|
+
' "text": [ { "string": verbatim, "size": "x_large"|"large"|"medium"|"small", "weight": "bold"|"semibold"|"regular", "case": "upper"|"title"|"sentence", "color": hex, "align": "left"|"center"|"right" } ],\n' +
|
|
35
|
+
' "notes": splits / overlaps / margins worth rebuilding\n' +
|
|
36
|
+
" } ] }\n\n" +
|
|
37
|
+
"Use the blueprint's positions, sizes, text_content, and colors. Estimate the percentages and split proportions as " +
|
|
38
|
+
"accurately as you can (e.g. a column split 60/20 with a 20% gap). Cover EVERY visible element — photos, text boxes, " +
|
|
39
|
+
"badges, background shapes, and small corner text — top-to-bottom, left-to-right. Output ONLY the JSON object.";
|
|
40
|
+
const SELECT_SYSTEM = "You identify the MAIN, identity-critical visual elements of an advertisement from its JSON blueprint — the things " +
|
|
41
|
+
"a faithful reproduction must supply as REAL reference images instead of letting a model invent them. Output ONLY a " +
|
|
42
|
+
'JSON object of the form { "elements": [ ... ] }, no prose.';
|
|
43
|
+
const SELECT_PROMPT = "AD BLUEPRINT (from image_describe):\n{{blueprint}}\n\n" +
|
|
44
|
+
"From this blueprint, list ONLY the elements that are prominent, important, and identity-bearing — the ones a " +
|
|
45
|
+
"reproduction must ground in a real asset:\n" +
|
|
46
|
+
'- the brand logo/wordmark (from brands_logos with function_in_image = advertiser_brand) -> type "logo"\n' +
|
|
47
|
+
"- trust/rating/certification/app-store/review badges (brands_logos with function_in_image = trust_badge | " +
|
|
48
|
+
'review_platform | certification_or_seal | app_store_badge | payment_method) -> type "badge"\n' +
|
|
49
|
+
'- a showcased/hero product or package (a foreground entry in subjects that the ad is selling) -> type "product"\n' +
|
|
50
|
+
'- a foreground person whose identity matters (from people) -> type "person"\n' +
|
|
51
|
+
'- a foreground animal/character with a specific expression (from subjects) -> type "animal"\n\n' +
|
|
52
|
+
"DROP background extras, decorative props, generic scenery, and anything small or incidental. Keep at most ~6. " +
|
|
53
|
+
"If there are none, return an empty list.\n\n" +
|
|
54
|
+
'For each kept element return: { "type": one of logo|product|person|animal|badge, "label": a short ' +
|
|
55
|
+
'UPPER_SNAKE_CASE name (e.g. LOGO, PRODUCT, HERO_DOG, TRUSTPILOT), "description": a concrete reusable description ' +
|
|
56
|
+
'to source/shoot the real asset (include the exact expression for a living subject), "expression": the facial ' +
|
|
57
|
+
'expression for a living subject or null, "reason": why it is identity-critical, "locator": the blueprint entry ' +
|
|
58
|
+
'this element came from as { "collection": one of "subjects" | "people" | "brands_logos", "index": its 0-based ' +
|
|
59
|
+
"position in that array } (people -> people; logos/badges -> brands_logos; products/animals/objects -> subjects). " +
|
|
60
|
+
"Output ONLY the JSON object.";
|
|
61
|
+
/** Read an asset's content as text — prefer the locally-ingested file, fall back to its URL. */
|
|
62
|
+
async function loadAssetText(ref, label) {
|
|
63
|
+
const r = ref;
|
|
64
|
+
if (typeof r?.path === "string")
|
|
65
|
+
return readFile(r.path, "utf8");
|
|
66
|
+
if (typeof r?.url === "string") {
|
|
67
|
+
const res = await fetch(r.url);
|
|
68
|
+
if (!res.ok)
|
|
69
|
+
throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
70
|
+
return res.text();
|
|
71
|
+
}
|
|
72
|
+
throw new Error(`${label}: output had no readable path or url`);
|
|
73
|
+
}
|
|
74
|
+
/** Parse the selection pass output into the elements array ({elements:[...]} or a bare array). */
|
|
75
|
+
function parseElements(raw) {
|
|
76
|
+
const parsed = JSON.parse(raw);
|
|
77
|
+
if (Array.isArray(parsed))
|
|
78
|
+
return parsed;
|
|
79
|
+
if (parsed && typeof parsed === "object" && Array.isArray(parsed.elements)) {
|
|
80
|
+
return parsed.elements;
|
|
81
|
+
}
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
/** Parse the layout pass output into a layout object ({layout:{...}} or a bare object), or null. */
|
|
85
|
+
function parseLayout(raw) {
|
|
86
|
+
const parsed = JSON.parse(raw);
|
|
87
|
+
if (parsed && typeof parsed === "object") {
|
|
88
|
+
const inner = parsed.layout;
|
|
89
|
+
return inner && typeof inner === "object" ? inner : parsed;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
function fail(code, message) {
|
|
94
|
+
process.stderr.write(`${JSON.stringify({ ok: false, error: { code, message } }, null, 2)}\n`);
|
|
95
|
+
process.exit(2);
|
|
96
|
+
}
|
|
97
|
+
/** Resolve every model id, honoring overrides; passes default to Gemini latest aliases. */
|
|
98
|
+
function resolveModels(args) {
|
|
99
|
+
const pick = (flag, kind, fallback) => args[flag] ? String(args[flag]) : resolveModel(kind, fallback);
|
|
100
|
+
return {
|
|
101
|
+
describeModel: pick("describe-model", "image_describe", "~google/gemini-pro-latest"),
|
|
102
|
+
selectModel: pick("select-model", "text_generate", "~google/gemini-flash-latest"),
|
|
103
|
+
layoutModel: pick("layout-model", "text_generate", "~google/gemini-flash-latest"),
|
|
104
|
+
genModel: pick("gen-model", "image_generate", "openai/gpt-5.4-image-2"),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Number of regions in the layout block, for the stdout summary. */
|
|
108
|
+
function regionCount(layout) {
|
|
109
|
+
const regions = layout?.regions;
|
|
110
|
+
return Array.isArray(regions) ? regions.length : 0;
|
|
111
|
+
}
|
|
112
|
+
/** The describe + element-selection + layout canvas, run once up front; we read all three node outputs after. */
|
|
113
|
+
function buildDescribeCanvas(imagePath, describeModel, selectModel, layoutModel, context) {
|
|
114
|
+
return {
|
|
115
|
+
schema: "baker-canvas/1",
|
|
116
|
+
metadata: { name: "static-ad describe pass" },
|
|
117
|
+
nodes: [
|
|
118
|
+
{ id: "original", type: "ingest", params: { source: "path", path: imagePath, expect: "image" } },
|
|
119
|
+
{
|
|
120
|
+
id: "describe",
|
|
121
|
+
type: "image_describe",
|
|
122
|
+
inputs: { image: "$ref:original.asset" },
|
|
123
|
+
params: { model: describeModel, max_tokens: 9000, ...(context ? { context } : {}), focus: DESCRIBE_FOCUS },
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "select",
|
|
127
|
+
type: "text_generate",
|
|
128
|
+
inputs: { blueprint: "$ref:describe.description" },
|
|
129
|
+
params: {
|
|
130
|
+
model: selectModel,
|
|
131
|
+
max_tokens: 4000,
|
|
132
|
+
temperature: 0,
|
|
133
|
+
response_format: "json_object",
|
|
134
|
+
system: SELECT_SYSTEM,
|
|
135
|
+
prompt: SELECT_PROMPT,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
id: "layout",
|
|
140
|
+
type: "text_generate",
|
|
141
|
+
inputs: { blueprint: "$ref:describe.description" },
|
|
142
|
+
params: {
|
|
143
|
+
model: layoutModel,
|
|
144
|
+
max_tokens: 6000,
|
|
145
|
+
temperature: 0,
|
|
146
|
+
response_format: "json_object",
|
|
147
|
+
system: LAYOUT_SYSTEM,
|
|
148
|
+
prompt: LAYOUT_PROMPT,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
output: { node: "select", output: "text" },
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/** Run the vision passes and read back the blueprint, selected elements, and the structured layout. */
|
|
156
|
+
async function runVisionPasses(canvas) {
|
|
157
|
+
const engine = createEngineFromEnv({ log: (line) => process.stderr.write(`${line}\n`) });
|
|
158
|
+
let outputsByNode;
|
|
159
|
+
let creditsSpent;
|
|
160
|
+
try {
|
|
161
|
+
const result = await engine.run(canvas, {});
|
|
162
|
+
outputsByNode = result.outputs_by_node;
|
|
163
|
+
creditsSpent = result.stats?.total_credits;
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
if (e instanceof ValidationError)
|
|
167
|
+
return fail("validation", JSON.stringify(e.issues));
|
|
168
|
+
return fail("describe", e instanceof Error ? e.message : String(e));
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const blueprint = JSON.parse(await loadAssetText(outputsByNode.describe?.description, "describe output"));
|
|
172
|
+
const elements = parseElements(await loadAssetText(outputsByNode.select?.text, "selection output"));
|
|
173
|
+
const layout = parseLayout(await loadAssetText(outputsByNode.layout?.text, "layout output"));
|
|
174
|
+
return { blueprint, elements, layout, creditsSpent };
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
export const scaffoldStaticAdCommand = defineCommand({
|
|
181
|
+
meta: {
|
|
182
|
+
name: "scaffold-static-ad",
|
|
183
|
+
description: "Turn a source/inspiration image into a runnable static-ad canvas. Runs billed passes — image_describe (the " +
|
|
184
|
+
"blueprint, baked to prompt.json as the editable 'prompt'), an AI selection of the image's MAIN identity " +
|
|
185
|
+
"elements, and a structured global-layout pass (the column/row grid with per-region bounds and text sizes) — " +
|
|
186
|
+
"then scaffolds a canvas that wires one [TODO] ingest slot per element (logo/product/subject/badge + brand font) " +
|
|
187
|
+
"into image_generate. Edit prompt.json and drop the real assets, then `baker canvas run` it.",
|
|
188
|
+
},
|
|
189
|
+
args: {
|
|
190
|
+
file: { type: "positional", required: true, description: "Path to the source/inspiration image" },
|
|
191
|
+
context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
|
|
192
|
+
out: { type: "string", description: "Output canvas path (default <image-dir>/static-ad.canvas.json)" },
|
|
193
|
+
"describe-model": { type: "string", description: "Override the image_describe model id" },
|
|
194
|
+
"select-model": { type: "string", description: "Override the text_generate model id for element selection" },
|
|
195
|
+
"layout-model": { type: "string", description: "Override the text_generate model id for the layout pass" },
|
|
196
|
+
"gen-model": { type: "string", description: "Override the image_generate model id" },
|
|
197
|
+
aspect: { type: "string", description: "Force the output aspect ratio (else inferred from the image)" },
|
|
198
|
+
"skip-font": { type: "boolean", description: "Skip the brand-font → type-specimen slot" },
|
|
199
|
+
},
|
|
200
|
+
async run({ args }) {
|
|
201
|
+
const imagePath = path.resolve(String(args.file));
|
|
202
|
+
const outPath = args.out
|
|
203
|
+
? path.resolve(String(args.out))
|
|
204
|
+
: path.join(path.dirname(imagePath), "static-ad.canvas.json");
|
|
205
|
+
const outDir = path.dirname(outPath);
|
|
206
|
+
const blueprintPath = path.join(outDir, "prompt.json");
|
|
207
|
+
const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
|
|
208
|
+
// One run: ingest → describe → (select ∥ layout). We read all three node outputs after.
|
|
209
|
+
const describeCanvas = buildDescribeCanvas(imagePath, describeModel, selectModel, layoutModel, args.context ? String(args.context) : undefined);
|
|
210
|
+
const { blueprint, elements, layout, creditsSpent } = await runVisionPasses(describeCanvas);
|
|
211
|
+
// Stamp each element's reference label onto the blueprint entry it came from, attach the
|
|
212
|
+
// structured global layout, then bake that as the editable prompt the canvas ingests — so
|
|
213
|
+
// editing prompt.json shows the full layout grid and which wired slot grounds which subject.
|
|
214
|
+
const annotated = annotateBlueprintWithLabels(blueprint, elements);
|
|
215
|
+
if (layout && annotated && typeof annotated === "object") {
|
|
216
|
+
annotated.layout = layout;
|
|
217
|
+
}
|
|
218
|
+
await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}\n`, "utf8");
|
|
219
|
+
const opts = {
|
|
220
|
+
genModel,
|
|
221
|
+
imagePath,
|
|
222
|
+
blueprintPath,
|
|
223
|
+
aspectRatio: args.aspect ? String(args.aspect) : undefined,
|
|
224
|
+
includeFont: !args["skip-font"],
|
|
225
|
+
};
|
|
226
|
+
let canvas;
|
|
227
|
+
let report;
|
|
228
|
+
try {
|
|
229
|
+
canvas = scaffoldStaticAd(blueprint, elements, opts);
|
|
230
|
+
report = staticAdReport(blueprint, elements, opts);
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
return fail("scaffold", e instanceof Error ? e.message : String(e));
|
|
234
|
+
}
|
|
235
|
+
const validation = await validateCanvasDeep(canvas, defaultRegistry());
|
|
236
|
+
if (!validation.ok) {
|
|
237
|
+
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}\n`);
|
|
238
|
+
process.exit(2);
|
|
239
|
+
}
|
|
240
|
+
await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}\n`, "utf8");
|
|
241
|
+
process.stdout.write(`${JSON.stringify({
|
|
242
|
+
ok: true,
|
|
243
|
+
canvas_path: outPath,
|
|
244
|
+
prompt_path: blueprintPath,
|
|
245
|
+
output: canvas.output,
|
|
246
|
+
models: { describe: describeModel, select: selectModel, layout: layoutModel, gen: opts.genModel },
|
|
247
|
+
aspect_ratio: report.aspect_ratio,
|
|
248
|
+
layout_regions: regionCount(layout),
|
|
249
|
+
stats: {
|
|
250
|
+
total_nodes: canvas.nodes.length,
|
|
251
|
+
describe_credits_spent: creditsSpent,
|
|
252
|
+
run_estimated_credits: validation.estimatedCredits,
|
|
253
|
+
},
|
|
254
|
+
checklist: {
|
|
255
|
+
edit_prompt: `Edit ${path.basename(blueprintPath)} — it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
|
|
256
|
+
assets_to_supply: report.elements,
|
|
257
|
+
font_slot: report.includes_font
|
|
258
|
+
? "Drop a brand font at the [TODO] brandfont path, or delete the brandfont + type_ref nodes to skip it."
|
|
259
|
+
: "skipped (--skip-font)",
|
|
260
|
+
note: "Replace every [TODO] ingest path with a real file, then `baker canvas validate` and `baker canvas run`. Running generates a billed image — it is not free.",
|
|
261
|
+
},
|
|
262
|
+
}, null, 2)}\n`);
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
//# sourceMappingURL=scaffold-static-ad.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-static-ad.js","sourceRoot":"","sources":["../../../src/commands/canvas/scaffold-static-ad.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const scaffoldVideoCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly file: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly required: true;
|
|
5
|
+
readonly description: "Path to the reference video";
|
|
6
|
+
};
|
|
7
|
+
readonly out: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly description: "Output canvas path (default <video-dir>/<name>.video.canvas.json)";
|
|
10
|
+
};
|
|
11
|
+
readonly frames: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly description: "\"generate\" (default, anchored regen) or \"reuse\" (wire real frames in)";
|
|
14
|
+
};
|
|
15
|
+
readonly "max-scenes": {
|
|
16
|
+
readonly type: "string";
|
|
17
|
+
readonly description: "Cap the number of scenes the deconstruct emits";
|
|
18
|
+
};
|
|
19
|
+
readonly language: {
|
|
20
|
+
readonly type: "string";
|
|
21
|
+
readonly description: "Transcript/dialogue language hint (e.g. fr, en)";
|
|
22
|
+
};
|
|
23
|
+
readonly focus: {
|
|
24
|
+
readonly type: "string";
|
|
25
|
+
readonly description: "Known provenance/emphasis to ground the deconstruct";
|
|
26
|
+
};
|
|
27
|
+
readonly "deconstruct-model": {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly description: "Override the video_deconstruct model id";
|
|
30
|
+
};
|
|
31
|
+
readonly "select-model": {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
readonly description: "Override the text_generate model id for element selection";
|
|
34
|
+
};
|
|
35
|
+
readonly "image-model": {
|
|
36
|
+
readonly type: "string";
|
|
37
|
+
readonly description: "Override the image_generate model id for frames";
|
|
38
|
+
};
|
|
39
|
+
readonly "video-model": {
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
readonly description: "Override the video_generate model id for clips";
|
|
42
|
+
};
|
|
43
|
+
}>;
|
|
44
|
+
//# sourceMappingURL=scaffold-video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-video.d.ts","sourceRoot":"","sources":["../../../src/commands/canvas/scaffold-video.ts"],"names":[],"mappings":"AAuJA,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwH/B,CAAC"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { cp, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { defineCommand } from "citty";
|
|
4
|
+
import { createEngineFromEnv, defaultRegistry, ValidationError, validateCanvasDeep } from "../../engine/index.js";
|
|
5
|
+
import { MODEL_REGISTRY } from "../../engine/models/registry.js";
|
|
6
|
+
import { annotateBlueprintWithElements, scaffoldVideoCanvas, videoReport, } from "../../engine/scaffold/video.js";
|
|
7
|
+
// Resolves to <package root>/canvas/... from both src/ (dev via tsx) and dist/
|
|
8
|
+
// (published build); `canvas` must stay in package.json `files` for the latter.
|
|
9
|
+
const SHIPPED_COMPOSITION_DIR = path.resolve(import.meta.dirname, "../../../canvas/video-overlay-composition");
|
|
10
|
+
/** Pick a sensible default model id for a node kind, preferring `preferred` when the registry still has it. */
|
|
11
|
+
function resolveModel(kind, preferred) {
|
|
12
|
+
const ids = Object.keys(MODEL_REGISTRY[kind]);
|
|
13
|
+
return ids.includes(preferred) ? preferred : (ids[0] ?? preferred);
|
|
14
|
+
}
|
|
15
|
+
const SELECT_SYSTEM = "You identify the RECURRING, identity-critical visual elements of a video ad from its deconstruction blueprint — " +
|
|
16
|
+
"the people, animals, products, and logos that must stay consistent every time they appear, so a faithful " +
|
|
17
|
+
"reproduction grounds each in ONE real reference image reused across every frame it appears in. Output ONLY a JSON " +
|
|
18
|
+
'object of the form { "elements": [ ... ] }, no prose.';
|
|
19
|
+
const SELECT_PROMPT = "VIDEO DECONSTRUCTION BLUEPRINT (video-deconstruct/1):\n{{blueprint}}\n\n" +
|
|
20
|
+
"List ONLY the elements worth keeping consistent across frames — the ones a reproduction must ground in a real asset:\n" +
|
|
21
|
+
'- each recurring person from global.cast (a presenter/actor/persona) -> type "person"\n' +
|
|
22
|
+
'- a recurring animal/pet/character with a stable identity -> type "animal"\n' +
|
|
23
|
+
'- a showcased product, package, card, or device the ad sells or demonstrates -> type "product"\n' +
|
|
24
|
+
'- the advertiser brand logo/wordmark (from global.branding) -> type "logo"\n' +
|
|
25
|
+
'- a recurring trust/rating/certification badge -> type "badge"\n\n' +
|
|
26
|
+
"DROP one-off background extras, incidental props, and generic scenery. A person in global.cast is almost always " +
|
|
27
|
+
"recurring. Keep at most ~8.\n\n" +
|
|
28
|
+
'For each kept element return: { "type": one of person|animal|product|logo|badge, "label": a short ' +
|
|
29
|
+
'UPPER_SNAKE_CASE name (e.g. HERO, CREATOR_SKEPTIC, INSURANCE_CARD, LOGO), "description": a concrete reusable ' +
|
|
30
|
+
"description to source/shoot the real asset (for a person/animal repeat the exact look from global.cast verbatim), " +
|
|
31
|
+
'"expression": a living subject\'s typical expression or null, "cast_id": the global.cast id if it maps to one else ' +
|
|
32
|
+
'null, "scenes": the 0-based indices of EVERY scene the element is visually present in — read each scene\'s ' +
|
|
33
|
+
"action_detail, its start_frame/end_frame subjects, its dialogue speaker, and its floating_elements. Be generous: " +
|
|
34
|
+
"if the same person narrates throughout, list every scene index. Output ONLY the JSON object.";
|
|
35
|
+
/** Read an asset's content as text — prefer the locally-ingested file, fall back to its URL. */
|
|
36
|
+
async function loadAssetText(ref, label) {
|
|
37
|
+
const r = ref;
|
|
38
|
+
if (typeof r?.path === "string")
|
|
39
|
+
return readFile(r.path, "utf8");
|
|
40
|
+
if (typeof r?.url === "string") {
|
|
41
|
+
const res = await fetch(r.url);
|
|
42
|
+
if (!res.ok)
|
|
43
|
+
throw new Error(`failed to fetch ${label} (${res.status})`);
|
|
44
|
+
return res.text();
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`${label}: output had no readable path or url`);
|
|
47
|
+
}
|
|
48
|
+
/** Parse the selection pass output into the elements array ({elements:[...]} or a bare array). */
|
|
49
|
+
function parseElements(raw) {
|
|
50
|
+
const parsed = JSON.parse(raw);
|
|
51
|
+
if (Array.isArray(parsed))
|
|
52
|
+
return parsed;
|
|
53
|
+
if (parsed && typeof parsed === "object" && Array.isArray(parsed.elements)) {
|
|
54
|
+
return parsed.elements;
|
|
55
|
+
}
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
function fail(code, message) {
|
|
59
|
+
process.stderr.write(`${JSON.stringify({ ok: false, error: { code, message } }, null, 2)}\n`);
|
|
60
|
+
process.exit(2);
|
|
61
|
+
}
|
|
62
|
+
/** Resolve every model id, honoring overrides; passes default to the Gemini latest aliases / Seedance. */
|
|
63
|
+
function resolveModels(args) {
|
|
64
|
+
const pick = (flag, kind, fallback) => args[flag] ? String(args[flag]) : resolveModel(kind, fallback);
|
|
65
|
+
return {
|
|
66
|
+
deconstructModel: pick("deconstruct-model", "video_deconstruct", "~google/gemini-pro-latest"),
|
|
67
|
+
selectModel: pick("select-model", "text_generate", "~google/gemini-flash-latest"),
|
|
68
|
+
// Default to the strongest image model (matches the static-ad scaffold); the
|
|
69
|
+
// frame generators need the most faithful text/identity reproduction. Override
|
|
70
|
+
// with --image-model for a cheaper/faster pass.
|
|
71
|
+
imageModel: pick("image-model", "image_generate", "openai/gpt-5.4-image-2"),
|
|
72
|
+
videoModel: pick("video-model", "video_generate", "bytedance/seedance-2.0"),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** The deconstruct → element-selection canvas, run once up front; we read both node outputs after. */
|
|
76
|
+
function buildAnalysisCanvas(videoPath, deconstructModel, selectModel, opts) {
|
|
77
|
+
const deconstructParams = { model: deconstructModel, mode: "full" };
|
|
78
|
+
if (typeof opts.maxScenes === "number")
|
|
79
|
+
deconstructParams.max_scenes = opts.maxScenes;
|
|
80
|
+
if (opts.language)
|
|
81
|
+
deconstructParams.language = opts.language;
|
|
82
|
+
if (opts.focus)
|
|
83
|
+
deconstructParams.focus = opts.focus;
|
|
84
|
+
return {
|
|
85
|
+
schema: "baker-canvas/1",
|
|
86
|
+
metadata: { name: "video deconstruct pass" },
|
|
87
|
+
nodes: [
|
|
88
|
+
{ id: "src", type: "ingest", params: { source: "path", path: videoPath, expect: "video" } },
|
|
89
|
+
{ id: "deconstruct", type: "video_deconstruct", inputs: { video: "$ref:src.asset" }, params: deconstructParams },
|
|
90
|
+
{
|
|
91
|
+
id: "select",
|
|
92
|
+
type: "text_generate",
|
|
93
|
+
inputs: { blueprint: "$ref:deconstruct.analysis" },
|
|
94
|
+
params: {
|
|
95
|
+
model: selectModel,
|
|
96
|
+
max_tokens: 6000,
|
|
97
|
+
temperature: 0,
|
|
98
|
+
response_format: "json_object",
|
|
99
|
+
system: SELECT_SYSTEM,
|
|
100
|
+
prompt: SELECT_PROMPT,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
output: { node: "select", output: "text" },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Run the deconstruct + selection passes and read back the blueprint and the recurring elements. */
|
|
108
|
+
async function runAnalysisPasses(canvas) {
|
|
109
|
+
const engine = createEngineFromEnv({ log: (line) => process.stderr.write(`${line}\n`) });
|
|
110
|
+
let outputsByNode;
|
|
111
|
+
let creditsSpent;
|
|
112
|
+
try {
|
|
113
|
+
const result = await engine.run(canvas, {});
|
|
114
|
+
outputsByNode = result.outputs_by_node;
|
|
115
|
+
creditsSpent = result.stats?.total_credits;
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
if (e instanceof ValidationError)
|
|
119
|
+
return fail("validation", JSON.stringify(e.issues));
|
|
120
|
+
return fail("deconstruct", e instanceof Error ? e.message : String(e));
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const blueprint = JSON.parse(await loadAssetText(outputsByNode.deconstruct?.analysis, "deconstruct output"));
|
|
124
|
+
const elements = parseElements(await loadAssetText(outputsByNode.select?.text, "selection output"));
|
|
125
|
+
return { blueprint, elements, creditsSpent };
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
return fail("read_outputs", e instanceof Error ? e.message : String(e));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export const scaffoldVideoCommand = defineCommand({
|
|
132
|
+
meta: {
|
|
133
|
+
name: "scaffold-video",
|
|
134
|
+
description: "Turn a reference video into a runnable reproduction canvas in one command. Runs billed passes — video_deconstruct " +
|
|
135
|
+
"(the full scene-by-scene blueprint + transcript, baked to prompt.json as the editable 'prompt') and an AI selection " +
|
|
136
|
+
"of the video's RECURRING identity elements (person/animal/product/logo) — then scaffolds a pipeline where every " +
|
|
137
|
+
"scene boundary is a static-ad-grade frame (the blueprint as target_blueprint, a reference legend, the real frame as " +
|
|
138
|
+
"anchor) and each recurring element gets ONE shared [TODO] ingest slot wired into every frame it appears in. The " +
|
|
139
|
+
"clips feed Seedance an ultra-detailed motion brief (action, camera, dialogue, transcript). Edit prompt.json, drop " +
|
|
140
|
+
"the real source images, then `baker canvas run`.",
|
|
141
|
+
},
|
|
142
|
+
args: {
|
|
143
|
+
file: { type: "positional", required: true, description: "Path to the reference video" },
|
|
144
|
+
out: { type: "string", description: "Output canvas path (default <video-dir>/<name>.video.canvas.json)" },
|
|
145
|
+
frames: { type: "string", description: '"generate" (default, anchored regen) or "reuse" (wire real frames in)' },
|
|
146
|
+
"max-scenes": { type: "string", description: "Cap the number of scenes the deconstruct emits" },
|
|
147
|
+
language: { type: "string", description: "Transcript/dialogue language hint (e.g. fr, en)" },
|
|
148
|
+
focus: { type: "string", description: "Known provenance/emphasis to ground the deconstruct" },
|
|
149
|
+
"deconstruct-model": { type: "string", description: "Override the video_deconstruct model id" },
|
|
150
|
+
"select-model": { type: "string", description: "Override the text_generate model id for element selection" },
|
|
151
|
+
"image-model": { type: "string", description: "Override the image_generate model id for frames" },
|
|
152
|
+
"video-model": { type: "string", description: "Override the video_generate model id for clips" },
|
|
153
|
+
},
|
|
154
|
+
async run({ args }) {
|
|
155
|
+
const videoPath = path.resolve(String(args.file));
|
|
156
|
+
const base = path.basename(videoPath, path.extname(videoPath));
|
|
157
|
+
const outPath = args.out
|
|
158
|
+
? path.resolve(String(args.out))
|
|
159
|
+
: path.join(path.dirname(videoPath), `${base}.video.canvas.json`);
|
|
160
|
+
const outDir = path.dirname(outPath);
|
|
161
|
+
const blueprintPath = path.join(outDir, "prompt.json");
|
|
162
|
+
const frames = args.frames === "reuse" ? "reuse" : "generate";
|
|
163
|
+
const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : undefined;
|
|
164
|
+
const { deconstructModel, selectModel, imageModel, videoModel } = resolveModels(args);
|
|
165
|
+
// One run: ingest → video_deconstruct → element selection. We read both outputs after.
|
|
166
|
+
const analysisCanvas = buildAnalysisCanvas(videoPath, deconstructModel, selectModel, {
|
|
167
|
+
maxScenes: Number.isFinite(maxScenes) ? maxScenes : undefined,
|
|
168
|
+
language: args.language ? String(args.language) : undefined,
|
|
169
|
+
focus: args.focus ? String(args.focus) : undefined,
|
|
170
|
+
});
|
|
171
|
+
const { blueprint, elements, creditsSpent } = await runAnalysisPasses(analysisCanvas);
|
|
172
|
+
// Bake the deconstruct blueprint as the editable prompt, annotated so the human
|
|
173
|
+
// editing it sees which wired slot grounds which recurring element.
|
|
174
|
+
await mkdir(outDir, { recursive: true });
|
|
175
|
+
const annotated = annotateBlueprintWithElements(blueprint, elements);
|
|
176
|
+
await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}\n`, "utf8");
|
|
177
|
+
// Copy the overlay composition next to the canvas so the emitted canvas
|
|
178
|
+
// references a concrete, validatable, editable path.
|
|
179
|
+
const compositionDest = path.join(outDir, "video-overlay-composition");
|
|
180
|
+
await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
|
|
181
|
+
const opts = {
|
|
182
|
+
imageModel,
|
|
183
|
+
videoModel,
|
|
184
|
+
overlayCompositionPath: compositionDest,
|
|
185
|
+
blueprintPath,
|
|
186
|
+
frames,
|
|
187
|
+
};
|
|
188
|
+
let canvas;
|
|
189
|
+
let report;
|
|
190
|
+
try {
|
|
191
|
+
canvas = scaffoldVideoCanvas(blueprint, elements, opts);
|
|
192
|
+
report = videoReport(blueprint, elements);
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
return fail("scaffold", e instanceof Error ? e.message : String(e));
|
|
196
|
+
}
|
|
197
|
+
const validation = await validateCanvasDeep(canvas, defaultRegistry());
|
|
198
|
+
if (!validation.ok) {
|
|
199
|
+
process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}\n`);
|
|
200
|
+
process.exit(2);
|
|
201
|
+
}
|
|
202
|
+
await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}\n`, "utf8");
|
|
203
|
+
process.stdout.write(`${JSON.stringify({
|
|
204
|
+
ok: true,
|
|
205
|
+
canvas_path: outPath,
|
|
206
|
+
prompt_path: blueprintPath,
|
|
207
|
+
composition_dir: compositionDest,
|
|
208
|
+
output: canvas.output,
|
|
209
|
+
frames_mode: frames,
|
|
210
|
+
models: { deconstruct: deconstructModel, select: selectModel, image: imageModel, video: videoModel },
|
|
211
|
+
stats: {
|
|
212
|
+
scene_count: report.scene_count,
|
|
213
|
+
total_nodes: canvas.nodes.length,
|
|
214
|
+
deconstruct_credits_spent: creditsSpent,
|
|
215
|
+
run_estimated_credits: validation.estimatedCredits,
|
|
216
|
+
},
|
|
217
|
+
checklist: {
|
|
218
|
+
edit_prompt: `Edit ${path.basename(blueprintPath)} — the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
|
|
219
|
+
recurring_elements_to_supply: report.elements,
|
|
220
|
+
voices_to_confirm: report.dialogue.map((d) => ({
|
|
221
|
+
scene: d.scene,
|
|
222
|
+
speaker: d.speaker,
|
|
223
|
+
voice_description: d.voice_description,
|
|
224
|
+
line: d.line,
|
|
225
|
+
})),
|
|
226
|
+
sfx_count: report.sfx_count,
|
|
227
|
+
overlay_count: report.overlay_count,
|
|
228
|
+
has_music: report.has_music,
|
|
229
|
+
scenes_clamped_to_15s: report.clamped_scenes,
|
|
230
|
+
note: "Drop ONE real source image at each el_* [TODO] (reused across every frame that element appears in), confirm each voice_select casting, then `baker canvas validate` and `baker canvas run`. Running generates many billed image/video/audio assets — it is not free.",
|
|
231
|
+
},
|
|
232
|
+
}, null, 2)}\n`);
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
//# sourceMappingURL=scaffold-video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-video.js","sourceRoot":"","sources":["../../../src/commands/canvas/scaffold-video.ts"],"names":[],"mappings":"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"}
|