videodraft 0.5.0 → 0.6.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/client.d.ts CHANGED
@@ -217,6 +217,12 @@ interface DownloadedFile {
217
217
  url: string;
218
218
  path: string;
219
219
  bytes: number;
220
+ /** Downscaled view copy in <dir>/previews/ (images over the size threshold
221
+ * only). Agents should inspect this instead of the full-res original —
222
+ * every full-res image an agent views is re-sent with each later message
223
+ * of its chat. Best-effort: absent when preview generation failed or was
224
+ * skipped. The original at `path` is always the deliverable. */
225
+ preview?: string;
220
226
  }
221
227
  declare function extFromUrl(url: string, fallback?: string): string;
222
228
  declare function renderTemplate(template: string, vars: {
package/dist/client.js CHANGED
@@ -818,10 +818,136 @@ async function pollGenerations(client, jobIds, options = {}) {
818
818
  }
819
819
 
820
820
  // src/core/download.ts
821
+ import { execFile } from "child_process";
821
822
  import fs2 from "fs";
822
823
  import path2 from "path";
823
824
  import { pipeline } from "stream/promises";
825
+ import { promisify } from "util";
824
826
  import { Readable } from "stream";
827
+ var execFileAsync = promisify(execFile);
828
+ var PREVIEW_SOURCE_RE = /\.(png|jpe?g|webp|tiff?)$/i;
829
+ var PREVIEW_SKIP_BYTES = 500 * 1024;
830
+ var PREVIEW_MAX_DIM = 1536;
831
+ var PREVIEW_JPEG_QUALITY = 85;
832
+ var PREVIEW_CDN_WIDTH = 1080;
833
+ var PREVIEW_EXTS = ["jpg", "webp", "png"];
834
+ function previewPathFor(originalPath, ext = "jpg") {
835
+ return path2.join(
836
+ path2.dirname(originalPath),
837
+ "previews",
838
+ `${path2.basename(originalPath)}.${ext}`
839
+ );
840
+ }
841
+ function invalidatePreviews(originalPath) {
842
+ for (const ext of PREVIEW_EXTS) {
843
+ try {
844
+ fs2.rmSync(previewPathFor(originalPath, ext), { force: true });
845
+ } catch {
846
+ }
847
+ }
848
+ }
849
+ function shouldWritePreview(originalPath, bytes) {
850
+ return PREVIEW_SOURCE_RE.test(originalPath) && bytes >= PREVIEW_SKIP_BYTES;
851
+ }
852
+ function tempPreviewPath(previewPath) {
853
+ return `${previewPath}.tmp-${process.pid}`;
854
+ }
855
+ function commitPreview(tmpPath, previewPath) {
856
+ try {
857
+ if (fs2.existsSync(tmpPath) && fs2.statSync(tmpPath).size > 0) {
858
+ fs2.renameSync(tmpPath, previewPath);
859
+ return true;
860
+ }
861
+ } catch {
862
+ }
863
+ fs2.rmSync(tmpPath, { force: true });
864
+ return false;
865
+ }
866
+ async function writePreviewWithSips(originalPath, previewPath) {
867
+ if (process.platform !== "darwin") return false;
868
+ const tmp = tempPreviewPath(previewPath);
869
+ try {
870
+ await execFileAsync(
871
+ "sips",
872
+ [
873
+ "-Z",
874
+ String(PREVIEW_MAX_DIM),
875
+ "-s",
876
+ "format",
877
+ "jpeg",
878
+ "-s",
879
+ "formatOptions",
880
+ String(PREVIEW_JPEG_QUALITY),
881
+ originalPath,
882
+ "--out",
883
+ tmp
884
+ ],
885
+ { timeout: 1e4 }
886
+ );
887
+ } catch {
888
+ fs2.rmSync(tmp, { force: true });
889
+ return false;
890
+ }
891
+ return commitPreview(tmp, previewPath);
892
+ }
893
+ var cdnPreviewConsecutiveFailures = 0;
894
+ var PREVIEW_CDN_MAX_CONSECUTIVE_FAILURES = 2;
895
+ var PREVIEW_CDN_TIMEOUT_MS = 1e4;
896
+ async function writePreviewFromCdn(sourceUrl, originalPath, fetchImpl) {
897
+ let host;
898
+ try {
899
+ host = new URL(sourceUrl).hostname;
900
+ } catch {
901
+ return void 0;
902
+ }
903
+ if (host !== "cdn.videodraft.ai") return void 0;
904
+ if (cdnPreviewConsecutiveFailures >= PREVIEW_CDN_MAX_CONSECUTIVE_FAILURES) return void 0;
905
+ const variant = `${DEFAULT_BASE_URL}/_next/image?url=${encodeURIComponent(sourceUrl)}&w=${PREVIEW_CDN_WIDTH}&q=75`;
906
+ let res;
907
+ try {
908
+ res = await fetchImpl(variant, {
909
+ headers: { Accept: "image/webp,image/jpeg,image/*" },
910
+ signal: AbortSignal.timeout(PREVIEW_CDN_TIMEOUT_MS)
911
+ });
912
+ } catch (err) {
913
+ cdnPreviewConsecutiveFailures++;
914
+ throw err;
915
+ }
916
+ if (!res.ok || !res.body) {
917
+ cdnPreviewConsecutiveFailures++;
918
+ return void 0;
919
+ }
920
+ cdnPreviewConsecutiveFailures = 0;
921
+ const contentType = res.headers.get("content-type") ?? "";
922
+ const ext = contentType.includes("webp") ? "webp" : contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("png") ? "png" : "webp";
923
+ const previewPath = previewPathFor(originalPath, ext);
924
+ const tmp = tempPreviewPath(previewPath);
925
+ try {
926
+ await pipeline(Readable.fromWeb(res.body), fs2.createWriteStream(tmp));
927
+ } catch {
928
+ fs2.rmSync(tmp, { force: true });
929
+ return void 0;
930
+ }
931
+ return commitPreview(tmp, previewPath) ? previewPath : void 0;
932
+ }
933
+ async function writePreview(originalPath, sourceUrl, bytes, fetchImpl = fetch) {
934
+ if (!PREVIEW_SOURCE_RE.test(originalPath)) return void 0;
935
+ invalidatePreviews(originalPath);
936
+ if (!shouldWritePreview(originalPath, bytes)) return void 0;
937
+ try {
938
+ const jpgPath = previewPathFor(originalPath, "jpg");
939
+ fs2.mkdirSync(path2.dirname(jpgPath), { recursive: true });
940
+ if (await writePreviewWithSips(originalPath, jpgPath).catch(() => false)) {
941
+ return jpgPath;
942
+ }
943
+ const cdnPath = await writePreviewFromCdn(sourceUrl, originalPath, fetchImpl).catch(
944
+ () => void 0
945
+ );
946
+ if (cdnPath) return cdnPath;
947
+ } catch {
948
+ }
949
+ return void 0;
950
+ }
825
951
  function extFromUrl(url, fallback = "bin") {
826
952
  try {
827
953
  const pathname = new URL(url).pathname;
@@ -866,7 +992,10 @@ async function downloadOutputs(urls, template, vars, fetchImpl = fetch) {
866
992
  index: i,
867
993
  ext: extFromUrl(url)
868
994
  });
869
- files.push(await downloadUrl(url, dest, fetchImpl));
995
+ const file = await downloadUrl(url, dest, fetchImpl);
996
+ const preview = await writePreview(file.path, url, file.bytes, fetchImpl);
997
+ if (preview) file.preview = preview;
998
+ files.push(file);
870
999
  }
871
1000
  return files;
872
1001
  }
package/dist/index.js CHANGED
@@ -24,8 +24,8 @@ function readVersionFromDisk() {
24
24
  }
25
25
  }
26
26
  function resolveVersion() {
27
- if ("0.5.0") {
28
- return "0.5.0";
27
+ if ("0.6.0") {
28
+ return "0.6.0";
29
29
  }
30
30
  return readVersionFromDisk();
31
31
  }
@@ -1713,10 +1713,136 @@ function buildMediaDescriptors(urls, typeHint) {
1713
1713
  }
1714
1714
 
1715
1715
  // src/core/download.ts
1716
+ import { execFile } from "child_process";
1716
1717
  import fs3 from "fs";
1717
1718
  import path2 from "path";
1718
1719
  import { pipeline } from "stream/promises";
1720
+ import { promisify } from "util";
1719
1721
  import { Readable } from "stream";
1722
+ var execFileAsync = promisify(execFile);
1723
+ var PREVIEW_SOURCE_RE = /\.(png|jpe?g|webp|tiff?)$/i;
1724
+ var PREVIEW_SKIP_BYTES = 500 * 1024;
1725
+ var PREVIEW_MAX_DIM = 1536;
1726
+ var PREVIEW_JPEG_QUALITY = 85;
1727
+ var PREVIEW_CDN_WIDTH = 1080;
1728
+ var PREVIEW_EXTS = ["jpg", "webp", "png"];
1729
+ function previewPathFor(originalPath, ext = "jpg") {
1730
+ return path2.join(
1731
+ path2.dirname(originalPath),
1732
+ "previews",
1733
+ `${path2.basename(originalPath)}.${ext}`
1734
+ );
1735
+ }
1736
+ function invalidatePreviews(originalPath) {
1737
+ for (const ext of PREVIEW_EXTS) {
1738
+ try {
1739
+ fs3.rmSync(previewPathFor(originalPath, ext), { force: true });
1740
+ } catch {
1741
+ }
1742
+ }
1743
+ }
1744
+ function shouldWritePreview(originalPath, bytes) {
1745
+ return PREVIEW_SOURCE_RE.test(originalPath) && bytes >= PREVIEW_SKIP_BYTES;
1746
+ }
1747
+ function tempPreviewPath(previewPath) {
1748
+ return `${previewPath}.tmp-${process.pid}`;
1749
+ }
1750
+ function commitPreview(tmpPath, previewPath) {
1751
+ try {
1752
+ if (fs3.existsSync(tmpPath) && fs3.statSync(tmpPath).size > 0) {
1753
+ fs3.renameSync(tmpPath, previewPath);
1754
+ return true;
1755
+ }
1756
+ } catch {
1757
+ }
1758
+ fs3.rmSync(tmpPath, { force: true });
1759
+ return false;
1760
+ }
1761
+ async function writePreviewWithSips(originalPath, previewPath) {
1762
+ if (process.platform !== "darwin") return false;
1763
+ const tmp = tempPreviewPath(previewPath);
1764
+ try {
1765
+ await execFileAsync(
1766
+ "sips",
1767
+ [
1768
+ "-Z",
1769
+ String(PREVIEW_MAX_DIM),
1770
+ "-s",
1771
+ "format",
1772
+ "jpeg",
1773
+ "-s",
1774
+ "formatOptions",
1775
+ String(PREVIEW_JPEG_QUALITY),
1776
+ originalPath,
1777
+ "--out",
1778
+ tmp
1779
+ ],
1780
+ { timeout: 1e4 }
1781
+ );
1782
+ } catch {
1783
+ fs3.rmSync(tmp, { force: true });
1784
+ return false;
1785
+ }
1786
+ return commitPreview(tmp, previewPath);
1787
+ }
1788
+ var cdnPreviewConsecutiveFailures = 0;
1789
+ var PREVIEW_CDN_MAX_CONSECUTIVE_FAILURES = 2;
1790
+ var PREVIEW_CDN_TIMEOUT_MS = 1e4;
1791
+ async function writePreviewFromCdn(sourceUrl, originalPath, fetchImpl) {
1792
+ let host;
1793
+ try {
1794
+ host = new URL(sourceUrl).hostname;
1795
+ } catch {
1796
+ return void 0;
1797
+ }
1798
+ if (host !== "cdn.videodraft.ai") return void 0;
1799
+ if (cdnPreviewConsecutiveFailures >= PREVIEW_CDN_MAX_CONSECUTIVE_FAILURES) return void 0;
1800
+ const variant = `${DEFAULT_BASE_URL}/_next/image?url=${encodeURIComponent(sourceUrl)}&w=${PREVIEW_CDN_WIDTH}&q=75`;
1801
+ let res;
1802
+ try {
1803
+ res = await fetchImpl(variant, {
1804
+ headers: { Accept: "image/webp,image/jpeg,image/*" },
1805
+ signal: AbortSignal.timeout(PREVIEW_CDN_TIMEOUT_MS)
1806
+ });
1807
+ } catch (err) {
1808
+ cdnPreviewConsecutiveFailures++;
1809
+ throw err;
1810
+ }
1811
+ if (!res.ok || !res.body) {
1812
+ cdnPreviewConsecutiveFailures++;
1813
+ return void 0;
1814
+ }
1815
+ cdnPreviewConsecutiveFailures = 0;
1816
+ const contentType = res.headers.get("content-type") ?? "";
1817
+ const ext = contentType.includes("webp") ? "webp" : contentType.includes("jpeg") || contentType.includes("jpg") ? "jpg" : contentType.includes("png") ? "png" : "webp";
1818
+ const previewPath = previewPathFor(originalPath, ext);
1819
+ const tmp = tempPreviewPath(previewPath);
1820
+ try {
1821
+ await pipeline(Readable.fromWeb(res.body), fs3.createWriteStream(tmp));
1822
+ } catch {
1823
+ fs3.rmSync(tmp, { force: true });
1824
+ return void 0;
1825
+ }
1826
+ return commitPreview(tmp, previewPath) ? previewPath : void 0;
1827
+ }
1828
+ async function writePreview(originalPath, sourceUrl, bytes, fetchImpl = fetch) {
1829
+ if (!PREVIEW_SOURCE_RE.test(originalPath)) return void 0;
1830
+ invalidatePreviews(originalPath);
1831
+ if (!shouldWritePreview(originalPath, bytes)) return void 0;
1832
+ try {
1833
+ const jpgPath = previewPathFor(originalPath, "jpg");
1834
+ fs3.mkdirSync(path2.dirname(jpgPath), { recursive: true });
1835
+ if (await writePreviewWithSips(originalPath, jpgPath).catch(() => false)) {
1836
+ return jpgPath;
1837
+ }
1838
+ const cdnPath = await writePreviewFromCdn(sourceUrl, originalPath, fetchImpl).catch(
1839
+ () => void 0
1840
+ );
1841
+ if (cdnPath) return cdnPath;
1842
+ } catch {
1843
+ }
1844
+ return void 0;
1845
+ }
1720
1846
  function extFromUrl(url, fallback = "bin") {
1721
1847
  try {
1722
1848
  const pathname = new URL(url).pathname;
@@ -1751,6 +1877,9 @@ async function downloadUrl(url, destPath, fetchImpl = fetch) {
1751
1877
  const bytes = fs3.statSync(destPath).size;
1752
1878
  return { url, path: destPath, bytes };
1753
1879
  }
1880
+ function savedLine(file) {
1881
+ return file.preview ? `saved ${file.path} (inspect via preview: ${file.preview})` : `saved ${file.path}`;
1882
+ }
1754
1883
  async function downloadOutputs(urls, template, vars, fetchImpl = fetch) {
1755
1884
  const files = [];
1756
1885
  for (let i = 0; i < urls.length; i++) {
@@ -1761,7 +1890,10 @@ async function downloadOutputs(urls, template, vars, fetchImpl = fetch) {
1761
1890
  index: i,
1762
1891
  ext: extFromUrl(url)
1763
1892
  });
1764
- files.push(await downloadUrl(url, dest, fetchImpl));
1893
+ const file = await downloadUrl(url, dest, fetchImpl);
1894
+ const preview = await writePreview(file.path, url, file.bytes, fetchImpl);
1895
+ if (preview) file.preview = preview;
1896
+ files.push(file);
1765
1897
  }
1766
1898
  return files;
1767
1899
  }
@@ -2047,7 +2179,7 @@ async function handleAsyncJob(ctx, submitted, options) {
2047
2179
  for (const url of result.outputUrls) process.stdout.write(`${url}
2048
2180
  `);
2049
2181
  for (const file of downloaded ?? [])
2050
- note(o, fmt.dim(o, `saved ${file.path}`));
2182
+ note(o, fmt.dim(o, savedLine(file)));
2051
2183
  }
2052
2184
  );
2053
2185
  } catch (err) {
@@ -2425,7 +2557,7 @@ function registerGenerateCommands(program) {
2425
2557
  for (const url of urls) process.stdout.write(`${url}
2426
2558
  `);
2427
2559
  for (const file of downloaded ?? []) {
2428
- note(o, fmt.dim(o, `saved ${file.path}`));
2560
+ note(o, fmt.dim(o, savedLine(file)));
2429
2561
  }
2430
2562
  }
2431
2563
  );
@@ -2463,7 +2595,7 @@ function registerGenerateCommands(program) {
2463
2595
  for (const url of urls) process.stdout.write(`${url}
2464
2596
  `);
2465
2597
  for (const f of downloaded ?? [])
2466
- note(o, fmt.dim(o, `saved ${f.path}`));
2598
+ note(o, fmt.dim(o, savedLine(f)));
2467
2599
  }
2468
2600
  );
2469
2601
  });
@@ -2526,7 +2658,7 @@ function registerGenerateCommands(program) {
2526
2658
  for (const url of urls) process.stdout.write(`${url}
2527
2659
  `);
2528
2660
  for (const f of downloaded ?? [])
2529
- note(o, fmt.dim(o, `saved ${f.path}`));
2661
+ note(o, fmt.dim(o, savedLine(f)));
2530
2662
  }
2531
2663
  );
2532
2664
  });
@@ -2559,7 +2691,7 @@ function registerGenerateCommands(program) {
2559
2691
  for (const url of urls) process.stdout.write(`${url}
2560
2692
  `);
2561
2693
  for (const f of downloaded ?? [])
2562
- note(o, fmt.dim(o, `saved ${f.path}`));
2694
+ note(o, fmt.dim(o, savedLine(f)));
2563
2695
  }
2564
2696
  );
2565
2697
  });
@@ -2611,7 +2743,7 @@ function registerGenerateCommands(program) {
2611
2743
  for (const url of urls) process.stdout.write(`${url}
2612
2744
  `);
2613
2745
  for (const f of downloaded ?? [])
2614
- note(o, fmt.dim(o, `saved ${f.path}`));
2746
+ note(o, fmt.dim(o, savedLine(f)));
2615
2747
  }
2616
2748
  );
2617
2749
  });
@@ -2654,7 +2786,7 @@ function registerGenerateCommands(program) {
2654
2786
  for (const url of urls) process.stdout.write(`${url}
2655
2787
  `);
2656
2788
  for (const f of downloaded ?? [])
2657
- note(o, fmt.dim(o, `saved ${f.path}`));
2789
+ note(o, fmt.dim(o, savedLine(f)));
2658
2790
  }
2659
2791
  );
2660
2792
  });
@@ -2709,7 +2841,7 @@ function registerGenerateCommands(program) {
2709
2841
  for (const url of urls) process.stdout.write(`${url}
2710
2842
  `);
2711
2843
  for (const f of downloaded ?? [])
2712
- note(o, fmt.dim(o, `saved ${f.path}`));
2844
+ note(o, fmt.dim(o, savedLine(f)));
2713
2845
  }
2714
2846
  );
2715
2847
  });
@@ -2744,7 +2876,7 @@ function registerGenerateCommands(program) {
2744
2876
  for (const u of urls) process.stdout.write(`${u}
2745
2877
  `);
2746
2878
  for (const f of downloaded ?? [])
2747
- note(o, fmt.dim(o, `saved ${f.path}`));
2879
+ note(o, fmt.dim(o, savedLine(f)));
2748
2880
  }
2749
2881
  );
2750
2882
  });
@@ -3047,7 +3179,7 @@ function registerPipelineCommands(program) {
3047
3179
  note(o, fmt.green(o, "Export finished."));
3048
3180
  process.stdout.write(`${result.videoUrl}
3049
3181
  `);
3050
- for (const f of downloaded ?? []) note(o, fmt.dim(o, `saved ${f.path}`));
3182
+ for (const f of downloaded ?? []) note(o, fmt.dim(o, savedLine(f)));
3051
3183
  }
3052
3184
  );
3053
3185
  } catch (err) {
@@ -3151,7 +3283,7 @@ function registerJobCommands(program) {
3151
3283
  }
3152
3284
  for (const url of row.outputs) process.stdout.write(`${url}
3153
3285
  `);
3154
- for (const f of row.downloaded_files ?? []) note(o, fmt.dim(o, `saved ${f.path}`));
3286
+ for (const f of row.downloaded_files ?? []) note(o, fmt.dim(o, savedLine(f)));
3155
3287
  }
3156
3288
  });
3157
3289
  if (failures > 0) process.exitCode = 1;
@@ -3251,7 +3383,12 @@ function registerMediaCommands(program) {
3251
3383
  name: new URL(url).pathname.split("/").pop()?.replace(/\.[^.]+$/, "") ?? "download"
3252
3384
  });
3253
3385
  const file = await downloadUrl(url, dest);
3254
- emit(ctx.out, file, (o) => note(o, fmt.green(o, `saved ${file.path} (${file.bytes} bytes)`)));
3386
+ const preview = await writePreview(file.path, url, file.bytes);
3387
+ if (preview) file.preview = preview;
3388
+ emit(ctx.out, file, (o) => {
3389
+ note(o, fmt.green(o, `saved ${file.path} (${file.bytes} bytes)`));
3390
+ if (file.preview) note(o, fmt.dim(o, `inspect via preview: ${file.preview}`));
3391
+ });
3255
3392
  });
3256
3393
  }
3257
3394
 
@@ -3734,8 +3871,8 @@ function bundledSkillDir() {
3734
3871
  throw new CliError("Bundled skill not found (package is missing skills/videodraft).");
3735
3872
  }
3736
3873
  function bundledSkillFiles() {
3737
- if ('{"SKILL.md":"---\\nname: videodraft\\ndescription: Create AI videos, images, Seed Audio, voiceovers, music, sound effects, dialogue, dubbing, storyboards, avatar videos, media upscales and product/ad videos with VideoDraft. Use when the user mentions VideoDraft, or asks to generate/make a video, video ad, explainer, storyboard, talking-head/avatar video, AI image, prompt-driven or reference-driven audio, voiceover/TTS, background music, sound effects, dialogue audio, voice changing, dubbing, or image/video enhancement and upscaling, including batch/programmatic video generation in scripts or CI. Works via the `videodraft` CLI (preferred in terminals) or the VideoDraft MCP connector.\\n---\\n\\n# VideoDraft\\n\\nVideoDraft is an AI video creation platform where asset generation is the priority lane:\\n\\n- **Asset generation**: standalone images, video clips, Seed Audio, voiceovers, music, sound effects, dialogue, voice-changed audio, dubbed media, upscales, and image descriptions. This is the fastest and most important lane. Treat these as complete deliverables when the user asks for assets.\\n- **Asset I/O**: upload local files, download outputs, auto-upload local references, and save generated media where the user can see it.\\n- **Project production**: idea \u2192 script \u2192 storyboard (scenes + shot images) \u2192 project data \u2192 production timeline \u2192 exported MP4. Use it for a multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export, even when the user does not say \\"project.\\" A script-only request also creates a script-stage project but stops at the script.\\n\\n## How to connect\\n\\nTwo equivalent surfaces (same backend, same credits, same projects):\\n\\n1. **CLI** (preferred when you have a shell): run `videodraft` if it\'s on PATH; otherwise `npx -y videodraft@latest` runs it with no install (needs Node \u226520; the `-y` skips npx\'s install prompt so it runs non-interactively; the package is fetched on first use and cached). For heavy use, `npm install -g videodraft`. If there\'s no Node/shell here but the MCP connector below is available, use that instead; if neither works, tell the user how to install (https://videodraft.ai/cli).\\n - Auth \u2014 pick by context, don\'t guess:\\n \u2022 INTERACTIVE (a human is in the session, e.g. Claude Code / Codex): on exit code 3 (\\"not authenticated\\"), tell the user to run `videodraft login` in their terminal \u2014 it opens their browser for a one-click VideoDraft sign-in (OAuth), no key to copy. Wait for them to confirm it succeeded, then retry the command. This is the preferred path when the user is present.\\n \u2022 HEADLESS / CI (no browser): set `VIDEODRAFT_API_KEY=vd_mcp_...` (a token the user mints at https://app.videodraft.ai/mcp-keys).\\n \u2022 SECURITY: never ask the user to paste a `vd_mcp_...` token into the chat \u2014 use browser `login` or the env var so the token never lands in the transcript.\\n - Every command accepts `--json` (parse this, don\'t scrape text). Exit codes: 0 ok, 1 error, 2 usage, 3 auth (see Auth above), 4 insufficient credits (\u2192 tell the user, don\'t retry).\\n - Tool discovery: start with `videodraft tools list` for the grouped catalog, then narrow with `videodraft tools list --lane assets`, `--lane asset_io`, `--lane project_data`, or `--lane production`.\\n - Asset lane: `videodraft generate ...`, `videodraft edit video|motion`, `videodraft avatar ...`, `videodraft upscale ...`, `videodraft upload`, and `videodraft download`.\\n - Full API access: `videodraft tools schema <name>`, `videodraft call <tool> --args \'<json>\'`.\\n2. **MCP connector**: if VideoDraft MCP tools (e.g. `generate_storyboard_from_idea`) are available, call them directly \u2014 the CLI\'s curated commands map 1:1 onto these tools.\\n\\n## First decision: asset or project?\\n\\n- **One standalone asset** (image, clip, voiceover, music track, sound effect, dialogue track, voice-changed file, dubbed media file, upscale, or description): generate it directly. Do NOT create a project.\\n - `videodraft generate image \\"a red fox in snow, cinematic\\" --ar 16:9 --download ./out/`\\n - `videodraft generate video \\"slow dolly over a misty lake\\" --model gemini-omni-flash --duration 6 --download ./out/`\\n- **A small set of related assets**: still stay in the asset lane. Use an AI Studio session if you need to group related generations. Switch to a project only when the deliverable matches the project criteria below or the user asks to attach the assets to one.\\n- **A multi-scene video / ad / explainer, storyboard, timeline, or final exported video**: create a project so the work stays organized, editable in the web app, and exportable.\\n - `videodraft create \\"30s launch video for our espresso machine\\" --ar 9:16`\\n- **Just a script** (no video asked for): `videodraft create \\"...\\" --script-only`. Stop at the script \u2014 do not build a storyboard the user didn\'t ask for.\\n- **Iterating on existing work**: find it first (`videodraft projects list`) and reuse that project. Never create a new project to change an existing one.\\n\\n## Choose the model from the task\\n\\nIf the user names a model, use it when compatible. If it cannot handle the request, explain why and recommend alternatives instead of silently switching. Otherwise inspect the inputs, duration, audio, quality, speed, and cost, check the live catalog, and pass an explicit model.\\n\\n**Images:**\\n\\n- `nano-banana-2`: general default, editing, consistency, and references.\\n- `nano-banana-pro`: maximum quality. `nano-banana-2-lite`: fast, inexpensive drafts.\\n- `gpt-image-2`: posters, logos, signs, title cards, readable text, or precise composition/editing.\\n\\n**Videos:**\\n\\n- `gemini-omni-flash`: general default up to 10s, first frame/image references, or editing one source video without extra media references. Fixed 720p with audio.\\n- `seedance-2`: 11-15s, video/audio/mixed references, wider ratios, selectable audio, or first/last frames. Use `mini` for cost, `fast` for speed, `standard` for quality or 1080p/4K.\\n- `kling-v3-turbo`: fast polished 3-15s with first frame, multi-prompt, and audio. `kling-o3`: image references, first/last frames, multi-prompt, audio control, or 4K. `kling-3.0`: similar without reference-image mode.\\n- Existing-video edits use `videodraft edit video`, not generic generation. Choose from the `video_edit` catalog category: Grok for simple prompt edits, Wan 2.7 for one style reference or source-matching duration, Happy Horse for up to 5 references, and Kling O3 for controlled reference-image edits.\\n- Kling O3 and Wan 2.7 Ref/Edit also have reference-generation modes. Use `videodraft generate video --model <ref-edit-id>` with `--ref-video`/`--ref` to generate a new guided clip; use `videodraft edit video` when changing the source itself.\\n- Motion transfer uses `videodraft edit motion` with Kling V3 by default, or Kling 2.6 when explicitly requested or lower cost matters. It requires a subject image and a motion-reference video.\\n- Use Veo 3.1 when explicitly requested or as a fallback.\\n\\n**Audio and utilities:**\\n\\n- Use Seed Audio 1.0 for open-ended text-to-audio, speech/music/sound synthesis, voice conditioning, or prompt-driven editing with up to three audio references or one image. Use `videodraft generate audio`. Reference clips are `@Audio1`, `@Audio2`, and `@Audio3` in array order. There is no duration input. Output is up to two minutes and settles at 19 credits per actual minute, with up to 38 credits reserved during generation. The CLI automatically retries transient responses with one operation key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- Prefer ElevenLabs for voiceover, dialogue, voice changing, dubbing, and sound effects. Honor an explicitly selected supported TTS voice/provider. Use Lyria for instrumental music and ElevenLabs Music for vocals, lyrics, or exact timing.\\n- Talking head/presenter: choose by source. Use managed `avatar create` then `avatar render` when the user wants a reusable avatar record and bundled speech. Use `avatar fabric` for a one-off portrait plus text or existing audio. Use `avatar lipsync` when both the source video and replacement audio already exist.\\n- Enhancement: use Topaz image/video upscaling only when the content is already correct. Use image 1x for cleanup, 2x by default, 4x when justified; use video 2x by default. Edit or regenerate creative errors.\\n\\nSee [references/models.md](references/models.md) for the detailed routing table and exact capability limits.\\n\\n## Prefer references when continuity matters\\n\\nPure text-to-image or text-to-video is fine for a generic one-off asset. When a specific character, product, location, style, composition, or brand identity must survive generation, use references instead of hoping the prompt recreates it.\\n\\n- If the user supplies reference media, preserve and pass it. Never reduce the request to text alone.\\n- When continuity matters, generate/select a strong still first with the selected image model (`nano-banana-2` by default), wait for its URL, then animate it as a start frame/reference. Confirm the combined image and video cost.\\n- For multiple shots, use `videodraft shots <project_id> --model <selected-image-model> --grid`, then animate the decoded shots. Preserve explicit models. A requested non-Seedance video model must use manual per-shot generation instead of Seedance full-video mode.\\n\\n## Cost and credits\\n\\nDo not call `videodraft credits` before routine generations. Paid endpoints validate and deduct atomically; if the balance is insufficient, the request is rejected before the provider job starts (CLI exit code 4). Check the balance only when the user asks, gives a credit budget, or a large workflow needs budget planning.\\n\\nFor expensive work, estimate with `--estimate` or `videodraft costs`, state the selected model/settings/cost, and get a go-ahead. This matters most for shot-image batches, long or high-resolution video, AI Production, and paid audio batches. Honor the user\'s confirmation preference for the session.\\n\\n`videodraft models image|video` lists the live image and video catalogs with supported inputs. Video entries are grouped as `generation`, `video_edit`, `motion_control`, `avatar_lipsync`, and `upscale`, and each reports the exact tool. Use `videodraft models video --category video_edit` to narrow the list. `videodraft models audio` lists Seed Audio, Google Lyria, and ElevenLabs audio/media tools, while `videodraft models voices` lists TTS voices. Consult them instead of guessing capabilities.\\n\\n## Async jobs\\n\\nImage/video generation is asynchronous: commands submit a job and **wait by default**, printing output URLs (and saving files with `--download`). In scripts/CI prefer explicit control:\\n\\n```bash\\nJOB=$(videodraft generate image \\"...\\" --no-wait --json | jq -r .job_id)\\nvideodraft wait \\"$JOB\\" --download \\"./outputs/{job_id}_{index}.{ext}\\" --json\\n```\\n\\nFor MANY jobs: submit each with `--no-wait`, collect ALL with one command \u2014 `videodraft wait <id1> <id2> ...` polls every job from one process with one batched request per tick. Do NOT spawn parallel `wait`/`generate --wait` processes for a batch.\\n\\nIf a wait times out, the job is still running server-side \u2014 `videodraft status <job_id>` later. Never re-submit just because a wait timed out (that double-spends credits).\\n\\n## Local files and reference images\\n\\nReference inputs must be public URLs. The CLI uploads local files automatically wherever a URL is expected (`--ref photo.jpg`, `--start-image frame.png`), or explicitly:\\n\\n```bash\\nURL=$(videodraft upload ./product.png --json | jq -r .url)\\n```\\n\\nNever silently drop a reference you couldn\'t upload \u2014 stop and tell the user. Never upload a user\'s file to a third-party host.\\n\\nWhen the user attaches media, classify each item before acting: a recurring **visual asset** (character/product/location/style), actual **footage to place as shots**, or **inspiration only**. See [references/pipeline.md](references/pipeline.md) for how each role flows into a project.\\n\\n## Showing media to the user\\n\\nGenerated media is **not** displayed in the chat automatically \u2014 you decide what to show. To preview an asset inline, save it locally (use `--download` so it lands under `media/`) and reference its **local path** as a Markdown link with a **leading `./`**:\\n\\n```\\n[ferrari shot](./media/ferrari_01.png) \u2190 image card\\n[the clip](./media/clip.mp4) \u2190 video player\\n[voiceover](./media/vo.mp3) \u2190 audio player\\n```\\n\\nPut the Markdown link **in your message text** \u2014 video and audio embed exactly like images. Do **not** use `SendUserFile` (or other file-send tools) to display media: that renders inside a collapsible tool card and gets buried in the tool list. The Markdown link in your prose is what produces the inline card.\\n\\nUse the path you saved to: a **workspace-relative** path (`./media/clip.mp4`, or `./<any-folder>/clip.mp4` \u2014 any folder in the workspace works), or the **absolute** path for a file outside the workspace (e.g. `/Users/you/Desktop/clip.mp4` or another workspace\'s path). Both render. Show the finished results worth showing (and only those \u2014 not every intermediate job). A bare CDN URL or a JSON dump of output URLs does **not** render; the local-path Markdown link is what produces an inline card.\\n\\n## The full pipeline (idea \u2192 MP4)\\n\\n```bash\\nvideodraft create \\"<idea>\\" --ar 9:16 # project: script \u2192 visual assets \u2192 storyboard\\nvideodraft shots <project_id> --grid --estimate # cost preview, confirm with user\\nvideodraft shots <project_id> --grid # batch shot images (waits, writes onto shot cards)\\nvideodraft produce <project_id> # voiceovers + captions + production timeline\\nvideodraft export <project_id> --download final.mp4\\n```\\n\\nOptional between produce and export: per-shot motion clips (`videodraft generate video ... --project <id>` then place it with `videodraft attach <project> --scene N --shot M --media <url|file> --type video --duration <s>`), music (`videodraft generate music \\"...\\" --attach <project_id>`), and standalone audio assets (`generate audio`, `generate sound-effect`, `generate dialogue`, `generate voice-changer`, `generate dub`). Details, per-step tools and editing rules: [references/pipeline.md](references/pipeline.md).\\n\\nAvatar/talking-head videos use dedicated commands. For a reusable managed avatar, obtain or generate a clear portrait \u2192 `videodraft avatar script` when needed \u2192 `videodraft avatar create` \u2192 `videodraft avatar render --resolution 720p`. For a one-off portrait, use `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>`. For an existing video plus replacement audio, use `videodraft avatar lipsync <video> --audio <file>`. Managed script/creation is bundled/free; direct Fabric, Sync, the managed Fabric render, and optional portrait generation/upscaling are paid. Confirm expensive steps first.\\n\\n## Working with project data\\n\\nA project is one JSON blob (script, storyboard scenes, shot cards, visual assets, production timeline). To inspect: `videodraft projects get <id>`. To edit: fetch `--raw`, modify, then `videodraft call update_project` \u2014 objects deep-merge, **arrays replace wholesale** (send the complete `storyboard.scenes` array to change one scene). Snapshot first with `videodraft checkpoint create <id>` before risky edits. Schema reference: `videodraft call get_project_schema`.\\n\\n## More\\n\\n- [references/pipeline.md](references/pipeline.md) \u2014 project data model, step-by-step tools, attaching media, editing safely\\n- [references/models.md](references/models.md) \u2014 choosing image/video models, pricing patterns, voices and styles\\n- [references/examples.md](references/examples.md) \u2014 recipes: batch product videos from a CSV, talking-head from a script, changelog video in CI\\n","references/examples.md":"# Recipes\\n\\nWorking patterns for common asks. All assume auth (`videodraft login` once, or `VIDEODRAFT_API_KEY` in the environment) and use `--json` for parsing.\\n\\n## 1. Batch product videos from a CSV\\n\\nOne 9:16 product clip per row of `products.csv` (`name,image_url,tagline`):\\n\\n```bash\\n#!/usr/bin/env bash\\nset -euo pipefail\\nmkdir -p outputs\\n\\nwhile IFS=, read -r name image tagline; do\\n job=$(videodraft generate video \\\\\\n \\"Premium product shot of ${name}: ${tagline}. Slow orbit, studio lighting.\\" \\\\\\n --model gemini-omni-flash --ar 9:16 --duration 6 \\\\\\n --start-image \\"$image\\" \\\\\\n --no-wait --json | jq -r .job_id)\\n echo \\"$name,$job\\" >> outputs/jobs.csv\\ndone < <(tail -n +2 products.csv)\\n\\n# Collect ALL results with ONE process (batched polling \u2014 one request per tick)\\nvideodraft wait $(cut -d, -f2 outputs/jobs.csv) \\\\\\n --download \\"outputs/{job_id}_{index}.{ext}\\" --json > outputs/results.json\\n# map job ids back to product names via outputs/jobs.csv\\n```\\n\\nSubmit-then-collect parallelizes server-side generation; the single multi-id `wait` keeps it to one local process and one batched poll request per tick no matter how many jobs. Gemini Omni Flash is selected because these are six-second first-frame product clips. Estimate first: `videodraft costs gemini-omni-flash --type video --duration 6 --resolution 720p --audio` \xD7 rows, and confirm with the user.\\n\\n## 2. Full marketing video from one idea\\n\\n```bash\\nvideodraft create \\"30-second launch video for Solace, a sleep-tracking ring. Calm, premium, dark palette.\\" \\\\\\n --ar 9:16 --style cinematic --json > project.json\\nPROJECT=$(jq -r .project_id project.json)\\n\\nvideodraft shots \\"$PROJECT\\" --grid --estimate # show the user the cost; get a go-ahead\\nvideodraft shots \\"$PROJECT\\" --grid\\nvideodraft produce \\"$PROJECT\\"\\nvideodraft generate music \\"minimal ambient, warm pads, 60 BPM\\" --attach \\"$PROJECT\\"\\nvideodraft generate audio \\"Extend @Audio1 into a 20-second transition\\" --ref-audio ./intro.wav --format wav --download ./transition.wav\\nvideodraft export \\"$PROJECT\\" --download solace-launch.mp4\\n```\\n\\nThe project stays editable at the URL in `project.json` (`.urls`) \u2014 hand it to the user for tweaks.\\n\\n## 3. Talking-head (avatar) video\\n\\nWhen the user has no portrait, generate a clear front-facing avatar image first. Skip this step when they supplied one or an existing character should be reused.\\n\\n```bash\\nvideodraft generate image \\\\\\n \\"Front-facing head-and-shoulders portrait of a friendly coffee expert, direct eye contact, natural expression, clean studio background\\" \\\\\\n --model nano-banana-2 --ar 9:16 --download ./media/avatar.png\\n\\nSCRIPT=$(videodraft avatar script \\"why our espresso subscription saves you money\\" --style ad-style --json | jq -r .script)\\nAVATAR=$(videodraft avatar create ./media/avatar.png --script \\"$SCRIPT\\" --voice elevenlabs-kPzsL2i3teMYv0FxEYQ6 --ar 9:16 --json | jq -r .avatar_video_id)\\nvideodraft avatar render \\"$AVATAR\\" --resolution 720p # VEED Fabric paid step; confirm cost first (~20 credits/sec)\\n```\\n\\n`avatar script` and `avatar create` (including speech) are bundled/free. In this example only the optional portrait generation and Fabric render spend credits.\\n\\nIf the portrait is low resolution, enhance it before `avatar create`:\\n\\n```bash\\nvideodraft upscale image ./founder-small.jpg --scale 2x --download ./media/founder-upscaled.png\\n```\\n\\nFor a one-off portrait animation without creating a managed avatar record:\\n\\n```bash\\nvideodraft avatar fabric ./founder.jpg \\\\\\n --text \\"Welcome to the weekly product update.\\" \\\\\\n --voice-description \\"warm, confident American presenter\\" \\\\\\n --resolution 720p --download ./media/presenter.mp4\\n```\\n\\nWhen the user already has both the video and replacement speech:\\n\\n```bash\\nvideodraft avatar lipsync ./presenter.mp4 \\\\\\n --audio ./localized-voiceover.mp3 \\\\\\n --sync-mode loop --download ./media/presenter-localized.mp4\\n```\\n\\nEdit an existing video with a dedicated edit model:\\n\\n```bash\\nvideodraft models video --category video_edit\\nvideodraft edit video ./product-demo.mp4 \\\\\\n \\"Turn the room into a warm evening scene while preserving the product and camera motion\\" \\\\\\n --model wan-2.7-ref-edit --ref ./evening-style.jpg \\\\\\n --preserve-audio --download ./media/product-demo-evening.mp4\\n```\\n\\nTransfer motion from a reference clip onto a character image:\\n\\n```bash\\nvideodraft edit motion ./character.png \\\\\\n \\"Apply the dancer\'s movement to this character while preserving identity\\" \\\\\\n --motion-video ./dance-reference.mp4 \\\\\\n --model kling-v3-motion-control --quality pro \\\\\\n --download ./media/character-dance.mp4\\n```\\n\\n## 4. Changelog video in CI\\n\\nIn a GitHub Action with `VIDEODRAFT_API_KEY` set as a secret:\\n\\n```bash\\nNOTES=$(git log --oneline v1.2.0..HEAD | head -20)\\nvideodraft create \\"Weekly product update video. Energetic, 20 seconds. Changes: ${NOTES}\\" --ar 16:9 --json > p.json\\nPROJECT=$(jq -r .project_id p.json)\\nvideodraft shots \\"$PROJECT\\" && videodraft produce \\"$PROJECT\\"\\nvideodraft export \\"$PROJECT\\" --download changelog.mp4 --wait-timeout 30m\\n```\\n\\n## 5. Variations and picking a winner\\n\\n```bash\\nvideodraft generate image \\"logo concept: minimalist fox, geometric\\" --num 4 --download \\"./concepts/{job_id}_{index}.{ext}\\" --json\\n# Show all 4 to the user; regenerate the chosen one at higher res:\\nvideodraft generate image \\"<same prompt>\\" --model nano-banana-pro --resolution 4K\\n```\\n\\n## 6. Reaching tools without a curated command\\n\\n```bash\\nvideodraft tools list --json | jq -r \'.[].name\'\\nvideodraft tools schema attach_media_to_shot --json\\nvideodraft call attach_media_to_shot --args \'{\\"project_id\\":\\"...\\",\\"scene_index\\":0,\\"shot_index\\":1,\\"media_url\\":\\"https://...\\",\\"media_type\\":\\"video\\",\\"duration_seconds\\":6}\'\\n```\\n\\nAnything the VideoDraft MCP exposes \u2014 character studio, product studio, timeline editing \u2014 is reachable this way even before it gets a curated command.\\n\\n## 7. Enhance an existing asset without changing it\\n\\n```bash\\n# Light image cleanup, no enlargement\\nvideodraft upscale image ./poster.png --scale 1x --download ./media/poster-enhanced.png\\n\\n# General image and video enlargement\\nvideodraft upscale image ./frame.png --scale 2x --download ./media/frame-2x.png\\nvideodraft upscale video ./clip.mp4 --scale 2x --download ./media/clip-2x.mp4\\n```\\n\\nUse these when the content is correct and only quality or resolution needs improvement. If the poster text, composition, subject, or motion is wrong, edit or regenerate instead.\\n","references/models.md":"# Choosing models (and predicting cost)\\n\\nAlways consult the live catalog instead of memorizing this page \u2014 models change weekly:\\n\\n```bash\\nvideodraft models image --json # every image model + inputs (aspect ratios, resolutions, max refs)\\nvideodraft models video --json # every video model + inputs + per-second pricing metadata\\nvideodraft models audio --json # standalone audio/media models + pricing inputs\\nvideodraft models voices --json # TTS voices\\nvideodraft models styles --json # visual style presets\\n```\\n\\n## Task-based model selection\\n\\nHonor an explicitly named model when it supports the request. Otherwise choose from the task\'s inputs, duration, audio, quality, speed, and cost. Pass the chosen model explicitly instead of relying on a blind platform fallback.\\n\\n### Images\\n\\n| Need | Choose | Why |\\n| -------------------------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------- |\\n| Most generation, editing, character consistency, or reference work | `nano-banana-2` | Best general default; 1K/2K/4K and up to 14 reference images |\\n| Highest-quality complex generation or reasoning | `nano-banana-pro` | Premium Nano Banana quality and reasoning |\\n| Fast, inexpensive drafts and iteration | `nano-banana-2-lite` | Fastest/cheapest Nano Banana option; 1K only, up to 14 references |\\n| Posters, title cards, signs, logos, or any image with important readable text | `gpt-image-2` | Strong text rendering; up to 16 image inputs and 1K/2K/4K output |\\n| Complex multi-image composition, precise editing, or a strong alternate interpretation | `gpt-image-2` | Strong non-Nano alternative with multi-image input |\\n\\nUse `--num 1..4` for variations of one prompt in a single call. Never loop separate paid calls for variations that fit in one request.\\n\\n### Videos\\n\\n| Need | Choose | Important limits |\\n| ---------------------------------------------------------------------------------------------------------- | ------------------- | --------------------------------------------------------------------------------------------------- |\\n| Most text, first-frame, image-reference, or source-video-edit requests up to 10s | `gemini-omni-flash` | 720p, 3-10s or auto, audio always on, up to 10 total image inputs, one source video |\\n| Video/audio references, mixed reference media, broad aspect ratios, frame-mode first+last frame, or 11-15s | `seedance-2` | 4-15s or auto; up to 9 image, 3 video, and 3 audio refs; audio toggle; Mini/Fast are 480p/720p only |\\n| Fast polished 3-15s video with first frame, multi-prompt, and native audio | `kling-v3-turbo` | Audio always on; Pro default; no end frame or reference-media mode |\\n| Cinematic 3-15s with image references, first+last frame, multi-prompt, audio control, or 4K | `kling-o3` | Up to 7 image refs; Standard/Pro/4K; audio toggle |\\n| Kling 3-15s with first+last frame, multi-prompt, optional audio, or 4K, without reference-image mode | `kling-3.0` | Standard/Pro/4K; audio toggle |\\n| User explicitly requests Veo, or the selected workflow specifically needs Veo | `google-veo3.1` | Good fallback, but not the preferred general model |\\n\\nRouting rules:\\n\\n- Around 11-15 seconds with native audio: use Kling or Seedance, not Gemini.\\n- One existing source video that should be edited, with an output up to 10 seconds and no additional media references to preserve: use Gemini Omni Flash.\\n- Video or audio supplied as creative reference: use Seedance 2.0.\\n- A video plus any image/audio references that must all be preserved: use Seedance 2.0. Do not promise that Gemini will preserve mixed source media; its Fal BYOK edit mode accepts only the source video and prompt.\\n- First and last frame control: use Seedance, Kling O3, or Kling 3.0. Gemini supports a first frame but not a last frame.\\n- Seedance reference mode and first-plus-last-frame mode are separate. Do not promise reference video/audio plus a last frame in one generation.\\n- Multi-prompt sequencing: use Kling 3.0 Turbo, Kling O3, or Kling 3.0.\\n- Seedance quality: `mini` for the lowest cost, `fast` for speed, `standard` for maximum quality and for 1080p/4K.\\n\\n### Video edit and motion-control categories\\n\\nUse `videodraft models video --category video_edit` for existing-video transforms and `--category motion_control` for motion transfer.\\n\\n| Need | Command/model | Important limits |\\n| ------------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\\n| Simple prompt edit of one video | `videodraft edit video <video> \\"...\\" --model grok-imagine-video-edit` | No image refs; source truncated to 8s; auto/480p/720p |\\n| Edit with one style/reference image | `--model wan-2.7-ref-edit --ref <image>` | One image ref; 2-10s or match source |\\n| Edit with several image references | `--model happy-horse-video-edit --ref ...` | Up to 5 refs; 720p/1080p; source capped at 15s |\\n| Controlled Kling edit | `--model kling-o3-video-ref-edit --ref ...` | Up to 4 refs; Standard/Pro; source clamped to 3-10s |\\n| Transfer reference motion to an image | `videodraft edit motion <image> \\"...\\" --motion-video <video>` | Kling V3 default; image orientation caps motion at 10s, video orientation at 30s |\\n\\nIf the user explicitly names one of these models, preserve it. The CLI uploads local source videos and reference images automatically. Editing returns an async job and waits by default.\\n\\nKling O3 and Wan 2.7 Ref/Edit are dual-mode cards. `videodraft edit video` uses edit mode. `videodraft generate video --model kling-o3-video-ref-edit` requires exactly one `--ref-video` and generates a new reference-guided clip. `--model wan-2.7-ref-edit` generates a new clip from one or more `--ref`/`--ref-video` inputs.\\n\\n### Reference-first video workflow\\n\\n- Prefer a start frame or reference image whenever a specific character, product, location, style, composition, or brand identity must stay recognizable.\\n- If the user gives a reference, pass it. Never silently replace it with a text description.\\n- If no reference exists and continuity matters, generate a still first with the user\'s explicitly requested compatible image model, otherwise use Nano Banana 2. Wait for the image URL, then animate it with the selected video model. Confirm the combined image plus video cost before starting.\\n- For multi-shot scenes, generate shot images with `videodraft shots <project_id> --model <selected-image-model> --grid`. Preserve an explicitly requested compatible image model; otherwise use `nano-banana-2`. The grid establishes the scene and characters together, then decodes into individual shot images.\\n- Animate the decoded shot images as per-shot start frames or references. Do not independently text-generate each video clip when the shots need to match.\\n- Pure text-to-video remains appropriate for generic one-off footage where no subject, composition, or continuity needs to be preserved.\\n\\n### Audio\\n\\n- **Seed Audio 1.0**: use `videodraft generate audio` for open-ended speech, sound, music, or prompt-driven audio editing. It accepts up to three audio references or one image. Address audio references as `@Audio1`, `@Audio2`, and `@Audio3`. Preset and custom cloned voice IDs are supported. Output is up to 120 seconds. There is no requested-duration input. The CLI automatically retries transient responses with one idempotency key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- **Voiceover/TTS**: prefer ElevenLabs. Brittney is the platform default voice; under ElevenLabs BYOK, use a compatible voice from the user\'s account. Honor another supported voice/provider when the user explicitly selects it.\\n- **Dialogue, voice changing, and dubbing**: ElevenLabs only.\\n- **Sound effects**: ElevenLabs Sound Effects only.\\n- **Music**: use `lyria-3-clip-preview` for a short instrumental/background score, `lyria-3-pro-preview` for a longer or higher-quality instrumental score, and `elevenlabs-music` when vocals/lyrics or a specified 10-120 second length matter.\\n- Voice Changer and Dubbing require the source media duration and currently accept source media up to 300 seconds.\\n\\n### Avatar / talking head\\n\\nChoose the dedicated path from the media the user already has:\\n\\n| Starting media | Command | Use |\\n| ----------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------- |\\n| Portrait + script, reusable avatar record | `videodraft avatar create <portrait> --script \\"...\\"` then `avatar render` | Managed avatar flow with bundled speech preparation |\\n| Portrait + text | `videodraft avatar fabric <portrait> --text \\"...\\"` | One-off direct VEED Fabric text mode |\\n| Portrait + existing audio | `videodraft avatar fabric <portrait> --audio <audio>` | One-off direct VEED Fabric audio lip sync |\\n| Existing video + existing audio | `videodraft avatar lipsync <video> --audio <audio>` | Sync Labs Lipsync 2 |\\n\\nThe managed renderer is VEED Fabric Fast (`veed/fabric-1.0/fast`). Direct Fabric and Sync Labs are paid AI Studio generations and return async job IDs.\\n\\n1. Obtain the avatar image. Prefer the user\'s supplied portrait or an existing character. If none exists, use the user\'s explicitly requested compatible image model, otherwise generate a front-facing head-and-shoulders portrait with `nano-banana-2`, direct eye contact, a natural expression, and a clean background. Match the intended video aspect ratio when practical.\\n2. If the portrait is visibly soft or too small, run Topaz image enhancement/upscaling before animation.\\n3. Generate a script only if needed: `videodraft avatar script \\"<idea>\\"`.\\n4. Create the avatar record and speech: `videodraft avatar create <portrait-url-or-file> --script \\"...\\" --voice <id> --ar 9:16`. Prefer ElevenLabs when unspecified, but honor another explicitly selected supported voice/provider.\\n5. Render with VEED Fabric: `videodraft avatar render <avatar_video_id> --resolution 720p`.\\n\\nThe portrait is passed as the avatar\'s character image, not as a generic video\'s start frame. Prefer rendering directly at 720p. Use 480p only when the user prioritizes lower cost. Avatar script generation and `avatar create` (including speech) are bundled/free. Confirm the Fabric render cost, plus portrait generation or upscaling when needed.\\n\\nDirect Fabric text/audio and Sync Labs do not use the managed avatar record. The CLI uploads local portrait, video, and audio files automatically. `avatar fabric --speed fast` applies only to audio mode. Sync costs 5 credits per verified audio second; under Fal BYOK, `sync_mode` remains available but `temperature` and `active_speaker` are ignored by the provider.\\n\\n### Upscaling / enhancement\\n\\n- **Images**: Topaz via `videodraft upscale image <url-or-file> --scale 1x|2x|4x`. Use 1x for light enhancement without enlargement, 2x as the general default, and 4x only when the source quality and target size justify it. The result is synchronous.\\n- **Videos**: Topaz via `videodraft upscale video <url-or-file> --scale 2x`. Use 2x by default. The job is asynchronous; the CLI waits by default, while MCP callers poll `check_generation_status`. MCP video input must be VideoDraft-hosted, so upload local or external sources first.\\n- Use upscaling to preserve the image/video while improving detail, resolution, or cleanup. It cannot fix the wrong subject, misspelled text, bad framing, unwanted objects, broken continuity, or incorrect motion. Use an edit or regeneration for those problems.\\n- For a new Fabric avatar, render directly at 720p instead of rendering at 480p and then upscaling. Upscale the source portrait first only when the portrait itself is low quality.\\n\\n## Capability gotchas\\n\\n- Each model\'s `inputs` block is authoritative: supported `aspect_ratios`, `resolutions`, `quality_options`, `start_frame`/`end_frame`, `max_reference_images/videos/audio`, `multi_prompt`, `audio_toggle`. Passing an unsupported input fails with a clear error \u2014 check first, don\'t trial-and-error paid calls.\\n- Most video models support only 16:9 / 9:16 / 1:1. A 3:4 request hard-fails on most.\\n- `--seed` reproduces a specific output on models that support it (e.g. Flux, Ideogram V4); everything else ignores it. You do not need a seed for variation \u2014 `--num` already varies.\\n- `--rendering-speed` applies to Ideogram (V3: `Default`/`Turbo`/`Quality`; V4: `Turbo`/`Balanced`/`Quality`) and affects image cost \u2014 pass it to `videodraft costs ... --rendering-speed <tier>` for an accurate estimate. Always trust `videodraft models image --json` over this list; new models and tiers appear there the moment the platform ships them, with no CLI update.\\n- `seedream-v5-pro` supports unified text-to-image and reference-image editing with up to 10 image references. Use `--resolution 1K` for 7 credits/image or `--resolution 2K` for 14 credits/image.\\n- Reference inputs: `--ref <img>` (images), `--ref-video <v>` (Gemini Omni Flash, Seedance 2, Wan 2.7), `--ref-audio <a>` (Seedance 2). The CLI uploads local files for all of these, so you can pass a path or a URL. `--segment \\"<prompt>:<seconds>\\"` (repeatable) drives multi-prompt models (Kling 3.0 / 3.0 Turbo / O3); total 3-15s. `generate image --video-ref` is the nano-banana-2 video reference.\\n- The top-level prompt is OPTIONAL for `generate video` with multi-prompt models and for Kling 3.0 Turbo (`--model kling-v3-turbo`) image-to-video \u2014 a `--segment`-only or `--start-image`-only call is valid. Every other model still needs a prompt; the server enforces per-model rules.\\n- AI Production: `videodraft produce <project> --mode full_video` generates one Seedance 2 video per scene; poll with `videodraft generations`, then `videodraft finalize <project>` swaps them into the timeline before `export`. If the user explicitly requests another compatible video model, do not use this fixed Seedance path. Generate the project shots manually with the requested model and attach them to the timeline.\\n\\n## Cost model\\n\\n- Images: per image (\xD7 `--num`). Matrix-priced models (GPT-Image, Nano Banana Pro, Seedream v5 Pro) vary by resolution/quality.\\n- Video: usually credits/second \xD7 duration; rate depends on model + resolution + quality + native audio on/off.\\n- Shot-image batches: one image per shot (+1 grid image per scene in `--grid` mode) \u2014 the largest single spend in the pipeline.\\n- VEED Fabric avatar renders: ~10 credits/sec at 480p, ~20/sec at 720p. Avatar creation and its speech are bundled/free; only optional portrait generation/upscaling adds cost before the render.\\n- Direct VEED Fabric: text or normal audio is 8 credits/sec at 480p and 15/sec at 720p; fast audio is 10/sec at 480p and 20/sec at 720p.\\n- Sync Labs Lipsync 2: 5 credits per verified audio second.\\n- Voiceover TTS: 10 credits per 1000 characters for standard voices, 30 per 1000 for cloned `custom-*` voices (min 1, pro-rated); applies to standalone voiceovers AND per-scene narration during `produce`. Silent tracks are free. Voice cloning itself is a flat 150 credits per clone.\\n- Lyria music: flat per track, 10 credits (clip) / 15 credits (pro).\\n- Seed Audio 1.0: 19 credits per actual output minute, prorated and rounded up to a whole credit. VideoDraft reserves the 120-second maximum of 38 credits and refunds the unused portion after generation. Fal BYOK is free.\\n- ElevenLabs audio: sound effects are per second, dialogue is per character, music/voice-changer/dubbing are per started minute. Voice changer and dubbing reject source media above 300s in the current synchronous flow.\\n- Upscales: priced by scale and source size.\\n\\nQuote before spending:\\n\\n```bash\\nvideodraft costs gemini-omni-flash --type video --duration 8 --resolution 720p --audio\\nvideodraft costs seedance-2 --type video --duration 15 --resolution 720p --quality standard --audio\\nvideodraft costs elevenlabs-dubbing --type audio --duration 60\\nvideodraft costs seed-audio-1.0 --type audio --duration 60 # scenario only; model controls actual length\\nvideodraft costs elevenlabs-dialogue --type audio --chars 350\\nvideodraft costs voiceover --type audio --chars 800 # TTS: 10 cr / 1000 chars\\nvideodraft generate video \\"...\\" --model gemini-omni-flash --estimate # same quote, inline\\n```\\n","references/pipeline.md":"# VideoDraft pipeline reference\\n\\nEverything here works through the CLI (`videodraft <command>` / `videodraft call <tool>`) or the MCP connector (tool names in backticks). One backend; pick the surface you have.\\n\\nUse direct asset tools for standalone images, clips, audio, upscales, and descriptions. Use a project for any multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export even when the request does not use the word \\"project.\\" Script-only uses a script-stage project and stops at the script.\\n\\n## Stages and their tools\\n\\n| Stage | CLI | Underlying tool |\\n| --------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------ |\\n| Idea \u2192 full storyboard project | `videodraft create \\"<idea>\\"` | `generate_storyboard_from_idea` |\\n| Idea \u2192 script only (stop there) | `videodraft create \\"<idea>\\" --script-only` | `generate_script_from_idea` |\\n| Footage IS the video | `videodraft call generate_storyboard_from_media` | `generate_storyboard_from_media` |\\n| Batch shot images | `videodraft shots <project>` | `generate_shot_images` |\\n| One shot image | `videodraft generate image --project <id> --scene N --shot M` | `generate_image` |\\n| Produce (voiceover, captions, timeline) | `videodraft produce <project>` | `produce_project` |\\n| Per-shot motion prompts | `videodraft video-prompts <project>` | `generate_video_prompts` |\\n| Motion clip for a shot | `videodraft generate video --project <id>` | `generate_video` |\\n| Attach a finished clip to the timeline | `videodraft attach <project> --scene N --shot M --media <url> --type video` | `attach_media_to_shot` |\\n| Background music | `videodraft generate music --attach <project>` | `generate_music` / `set_background_music` |\\n| General or reference-driven audio | `videodraft generate audio \\"...\\"` | `generate_audio` |\\n| Sound effect | `videodraft generate sound-effect \\"...\\"` | `generate_sound_effect` |\\n| Dialogue audio | `videodraft generate dialogue --line \\"voice:text\\"` | `generate_dialogue` |\\n| Voice changer | `videodraft generate voice-changer <audio>` | `change_voice` |\\n| Dubbing | `videodraft generate dub <audio_or_video>` | `dub_media` |\\n| Scene voiceover | `videodraft generate voiceover --project <id> --scene N` | `generate_voiceover` |\\n| Avatar script | `videodraft avatar script \\"<idea>\\"` | `generate_avatar_script` |\\n| Avatar + speech | `videodraft avatar create <portrait> --script \\"...\\"` | `create_avatar_video` |\\n| Talking-head render | `videodraft avatar render <avatar_video_id>` | `render_avatar_video` + `get_avatar_video` |\\n| Direct portrait + text/audio | `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>` | `generate_veed_fabric_video` |\\n| Existing video + replacement audio | `videodraft avatar lipsync <video> --audio <file>` | `generate_sync_lipsync_video` |\\n| Existing-video AI edit | `videodraft edit video <video> \\"<change>\\" --model <video-edit-model>` | `edit_video` |\\n| Motion transfer | `videodraft edit motion <image> \\"<direction>\\" --motion-video <video>` | `generate_motion_control_video` |\\n| Image enhancement/upscale | `videodraft upscale image <image>` | `upscale_image` |\\n| Video enhancement/upscale | `videodraft upscale video <video>` | `upscale_video` |\\n| Final MP4 | `videodraft export <project>` | `export_video` + `check_export_status` |\\n\\n## Rules that prevent broken results\\n\\n- **The storyboard is generated FROM the script**, never from the raw idea. `videodraft create` runs the whole chain correctly. Don\'t call `generate_storyboard_scenes` with a raw idea as the \\"script\\".\\n- **Visual consistency**: never generate a storyboard shot in isolation. Shot prompts carry `[[asset:Name]]` / `[[shot:X-Y]]` tags that `generate_shot_images` resolves against the project\'s visual assets and prior shots. When generating a single shot whose prompt has no tags, pass `--ref` images yourself (the project\'s visual assets and/or the previous shot\'s image; `projects get` exposes both). For scenes with multiple shots or recurring characters, prefer `videodraft shots <project> --model <selected-image-model> --grid`: preserve an explicitly requested compatible image model, otherwise use `nano-banana-2`. It creates one coherent scene grid, then decodes it into individual shot images.\\n- **Reference-first video**: when identity, styling, or composition matters, do not generate each motion clip from text alone. Generate or select the shot still first, then pass the decoded shot image as `--start-image` or `--ref` to the selected video model. AI Production already composes scene grids and sends them to Seedance as references. If the user explicitly requests another compatible video model, bypass fixed Seedance full-video mode and generate the per-shot clips with the requested model, using the individual decoded shot images as anchors.\\n- **Hold off generating shot images while the user is still iterating** on storyboard structure.\\n- **produce \u2192 export ordering**: `export` requires a produced project where every production scene has timeline media. If `produce` returns `generating_shot_images`, poll the job ids it returns, then re-run produce.\\n- **Generated motion clips do not auto-attach**: after `generate video` completes, attach the clip with `attach_media_to_shot` (`media_type:\\"video\\"`, include `duration_seconds`) \u2014 it replaces the production timeline clip while keeping the storyboard still.\\n- **Talking heads use dedicated avatar tools**: do not use `generate video`. Use managed `avatar create` and `avatar render` for reusable avatars, direct `avatar fabric` for a portrait plus text/audio, and `avatar lipsync` for an existing video plus replacement audio. Reuse a supplied person image or generate a clear front-facing portrait with the explicitly requested compatible image model, otherwise Nano Banana 2. Managed avatar creation and speech are bundled/free; direct Fabric, Sync, and render are paid.\\n- **Existing-video edits use their own category**: call `edit_video` or `videodraft edit video` with a `video_edit` model when transforming the source itself. Kling O3 and Wan 2.7 Ref/Edit are dual-mode: their reference-generation modes may use generic `generate_video` to create a new guided clip. Motion transfer similarly uses `generate_motion_control_video` or `videodraft edit motion` with a `motion_control` model.\\n- **Upscaling preserves rather than redesigns**: use Topaz when resolution, detail, or cleanup is the problem. Regenerate or edit when the subject, text, framing, continuity, or motion is wrong. Upscale a low-quality avatar portrait before Fabric; do not render a new avatar at 480p just to upscale the result.\\n- **Timeouts on the one-shot create**: if `create` times out at the transport layer, the project was still created server-side \u2014 `videodraft projects list`, take the most recent, and resume with its id. Don\'t start a duplicate.\\n\\n## User-attached media: classify roles first\\n\\nFor EACH attached file decide:\\n\\n- **visual_asset** \u2014 recurring reference (character / product / location / style). Upload, then pass in `visual_assets` of `generate_storyboard_from_idea` (via `videodraft call`), or add to an existing project with `add_visual_assets`. Type must be one of `character | object | location | style | custom` with a short name + concrete description.\\n- **shot** \u2014 the media IS footage for the video. Whole video = footage \u2192 `generate_storyboard_from_media`. Idea + footage \u2192 `generate_storyboard_from_idea` with `shot_media`. Existing storyboard \u2192 `attach_media_to_shots`.\\n- **reference** \u2014 inspiration only \u2192 fold a description into the idea/instructions; don\'t place it as a shot or asset.\\n\\nAmbiguous (e.g. a person holding a product)? Ask the user.\\n\\nUploads persist in the media library \u2014 recall later with `videodraft media list`.\\n\\n## Editing project data safely\\n\\n1. `videodraft call get_project_schema` \u2014 read the structure once per session.\\n2. `videodraft projects get <id> --raw` \u2014 the exact editable blob.\\n3. Modify; then `videodraft call update_project --stdin` with `{\\"project_id\\": \\"...\\", \\"data\\": {...}}`.\\n - Objects deep-merge key-by-key; **arrays replace wholesale** \u2014 send the complete array you\'re changing (e.g. all of `storyboard.scenes`).\\n - Scene shot arrays (`image_prompt` / `shot_types` / `shot_actions` / `search_prompt` / `preview_media`) are auto-aligned; fix-ups come back as warnings.\\n4. Snapshot before risky edits: `videodraft checkpoint create <id> --name \\"before re-script\\"`. Restore with `videodraft checkpoint restore <id> <version>`.\\n\\n## AI Studio sessions (standalone generations)\\n\\nProject generations group automatically. For standalone work in a long conversation, create one session up front and reuse it:\\n\\n```bash\\nSESSION=$(videodraft call create_ai_studio_session --arg name=\\"Fox brand explorations\\" --json | jq -r .session_id)\\nvideodraft generate image \\"...\\" --session \\"$SESSION\\"\\n```\\n"}') {
3738
- return JSON.parse('{"SKILL.md":"---\\nname: videodraft\\ndescription: Create AI videos, images, Seed Audio, voiceovers, music, sound effects, dialogue, dubbing, storyboards, avatar videos, media upscales and product/ad videos with VideoDraft. Use when the user mentions VideoDraft, or asks to generate/make a video, video ad, explainer, storyboard, talking-head/avatar video, AI image, prompt-driven or reference-driven audio, voiceover/TTS, background music, sound effects, dialogue audio, voice changing, dubbing, or image/video enhancement and upscaling, including batch/programmatic video generation in scripts or CI. Works via the `videodraft` CLI (preferred in terminals) or the VideoDraft MCP connector.\\n---\\n\\n# VideoDraft\\n\\nVideoDraft is an AI video creation platform where asset generation is the priority lane:\\n\\n- **Asset generation**: standalone images, video clips, Seed Audio, voiceovers, music, sound effects, dialogue, voice-changed audio, dubbed media, upscales, and image descriptions. This is the fastest and most important lane. Treat these as complete deliverables when the user asks for assets.\\n- **Asset I/O**: upload local files, download outputs, auto-upload local references, and save generated media where the user can see it.\\n- **Project production**: idea \u2192 script \u2192 storyboard (scenes + shot images) \u2192 project data \u2192 production timeline \u2192 exported MP4. Use it for a multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export, even when the user does not say \\"project.\\" A script-only request also creates a script-stage project but stops at the script.\\n\\n## How to connect\\n\\nTwo equivalent surfaces (same backend, same credits, same projects):\\n\\n1. **CLI** (preferred when you have a shell): run `videodraft` if it\'s on PATH; otherwise `npx -y videodraft@latest` runs it with no install (needs Node \u226520; the `-y` skips npx\'s install prompt so it runs non-interactively; the package is fetched on first use and cached). For heavy use, `npm install -g videodraft`. If there\'s no Node/shell here but the MCP connector below is available, use that instead; if neither works, tell the user how to install (https://videodraft.ai/cli).\\n - Auth \u2014 pick by context, don\'t guess:\\n \u2022 INTERACTIVE (a human is in the session, e.g. Claude Code / Codex): on exit code 3 (\\"not authenticated\\"), tell the user to run `videodraft login` in their terminal \u2014 it opens their browser for a one-click VideoDraft sign-in (OAuth), no key to copy. Wait for them to confirm it succeeded, then retry the command. This is the preferred path when the user is present.\\n \u2022 HEADLESS / CI (no browser): set `VIDEODRAFT_API_KEY=vd_mcp_...` (a token the user mints at https://app.videodraft.ai/mcp-keys).\\n \u2022 SECURITY: never ask the user to paste a `vd_mcp_...` token into the chat \u2014 use browser `login` or the env var so the token never lands in the transcript.\\n - Every command accepts `--json` (parse this, don\'t scrape text). Exit codes: 0 ok, 1 error, 2 usage, 3 auth (see Auth above), 4 insufficient credits (\u2192 tell the user, don\'t retry).\\n - Tool discovery: start with `videodraft tools list` for the grouped catalog, then narrow with `videodraft tools list --lane assets`, `--lane asset_io`, `--lane project_data`, or `--lane production`.\\n - Asset lane: `videodraft generate ...`, `videodraft edit video|motion`, `videodraft avatar ...`, `videodraft upscale ...`, `videodraft upload`, and `videodraft download`.\\n - Full API access: `videodraft tools schema <name>`, `videodraft call <tool> --args \'<json>\'`.\\n2. **MCP connector**: if VideoDraft MCP tools (e.g. `generate_storyboard_from_idea`) are available, call them directly \u2014 the CLI\'s curated commands map 1:1 onto these tools.\\n\\n## First decision: asset or project?\\n\\n- **One standalone asset** (image, clip, voiceover, music track, sound effect, dialogue track, voice-changed file, dubbed media file, upscale, or description): generate it directly. Do NOT create a project.\\n - `videodraft generate image \\"a red fox in snow, cinematic\\" --ar 16:9 --download ./out/`\\n - `videodraft generate video \\"slow dolly over a misty lake\\" --model gemini-omni-flash --duration 6 --download ./out/`\\n- **A small set of related assets**: still stay in the asset lane. Use an AI Studio session if you need to group related generations. Switch to a project only when the deliverable matches the project criteria below or the user asks to attach the assets to one.\\n- **A multi-scene video / ad / explainer, storyboard, timeline, or final exported video**: create a project so the work stays organized, editable in the web app, and exportable.\\n - `videodraft create \\"30s launch video for our espresso machine\\" --ar 9:16`\\n- **Just a script** (no video asked for): `videodraft create \\"...\\" --script-only`. Stop at the script \u2014 do not build a storyboard the user didn\'t ask for.\\n- **Iterating on existing work**: find it first (`videodraft projects list`) and reuse that project. Never create a new project to change an existing one.\\n\\n## Choose the model from the task\\n\\nIf the user names a model, use it when compatible. If it cannot handle the request, explain why and recommend alternatives instead of silently switching. Otherwise inspect the inputs, duration, audio, quality, speed, and cost, check the live catalog, and pass an explicit model.\\n\\n**Images:**\\n\\n- `nano-banana-2`: general default, editing, consistency, and references.\\n- `nano-banana-pro`: maximum quality. `nano-banana-2-lite`: fast, inexpensive drafts.\\n- `gpt-image-2`: posters, logos, signs, title cards, readable text, or precise composition/editing.\\n\\n**Videos:**\\n\\n- `gemini-omni-flash`: general default up to 10s, first frame/image references, or editing one source video without extra media references. Fixed 720p with audio.\\n- `seedance-2`: 11-15s, video/audio/mixed references, wider ratios, selectable audio, or first/last frames. Use `mini` for cost, `fast` for speed, `standard` for quality or 1080p/4K.\\n- `kling-v3-turbo`: fast polished 3-15s with first frame, multi-prompt, and audio. `kling-o3`: image references, first/last frames, multi-prompt, audio control, or 4K. `kling-3.0`: similar without reference-image mode.\\n- Existing-video edits use `videodraft edit video`, not generic generation. Choose from the `video_edit` catalog category: Grok for simple prompt edits, Wan 2.7 for one style reference or source-matching duration, Happy Horse for up to 5 references, and Kling O3 for controlled reference-image edits.\\n- Kling O3 and Wan 2.7 Ref/Edit also have reference-generation modes. Use `videodraft generate video --model <ref-edit-id>` with `--ref-video`/`--ref` to generate a new guided clip; use `videodraft edit video` when changing the source itself.\\n- Motion transfer uses `videodraft edit motion` with Kling V3 by default, or Kling 2.6 when explicitly requested or lower cost matters. It requires a subject image and a motion-reference video.\\n- Use Veo 3.1 when explicitly requested or as a fallback.\\n\\n**Audio and utilities:**\\n\\n- Use Seed Audio 1.0 for open-ended text-to-audio, speech/music/sound synthesis, voice conditioning, or prompt-driven editing with up to three audio references or one image. Use `videodraft generate audio`. Reference clips are `@Audio1`, `@Audio2`, and `@Audio3` in array order. There is no duration input. Output is up to two minutes and settles at 19 credits per actual minute, with up to 38 credits reserved during generation. The CLI automatically retries transient responses with one operation key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- Prefer ElevenLabs for voiceover, dialogue, voice changing, dubbing, and sound effects. Honor an explicitly selected supported TTS voice/provider. Use Lyria for instrumental music and ElevenLabs Music for vocals, lyrics, or exact timing.\\n- Talking head/presenter: choose by source. Use managed `avatar create` then `avatar render` when the user wants a reusable avatar record and bundled speech. Use `avatar fabric` for a one-off portrait plus text or existing audio. Use `avatar lipsync` when both the source video and replacement audio already exist.\\n- Enhancement: use Topaz image/video upscaling only when the content is already correct. Use image 1x for cleanup, 2x by default, 4x when justified; use video 2x by default. Edit or regenerate creative errors.\\n\\nSee [references/models.md](references/models.md) for the detailed routing table and exact capability limits.\\n\\n## Prefer references when continuity matters\\n\\nPure text-to-image or text-to-video is fine for a generic one-off asset. When a specific character, product, location, style, composition, or brand identity must survive generation, use references instead of hoping the prompt recreates it.\\n\\n- If the user supplies reference media, preserve and pass it. Never reduce the request to text alone.\\n- When continuity matters, generate/select a strong still first with the selected image model (`nano-banana-2` by default), wait for its URL, then animate it as a start frame/reference. Confirm the combined image and video cost.\\n- For multiple shots, use `videodraft shots <project_id> --model <selected-image-model> --grid`, then animate the decoded shots. Preserve explicit models. A requested non-Seedance video model must use manual per-shot generation instead of Seedance full-video mode.\\n\\n## Cost and credits\\n\\nDo not call `videodraft credits` before routine generations. Paid endpoints validate and deduct atomically; if the balance is insufficient, the request is rejected before the provider job starts (CLI exit code 4). Check the balance only when the user asks, gives a credit budget, or a large workflow needs budget planning.\\n\\nFor expensive work, estimate with `--estimate` or `videodraft costs`, state the selected model/settings/cost, and get a go-ahead. This matters most for shot-image batches, long or high-resolution video, AI Production, and paid audio batches. Honor the user\'s confirmation preference for the session.\\n\\n`videodraft models image|video` lists the live image and video catalogs with supported inputs. Video entries are grouped as `generation`, `video_edit`, `motion_control`, `avatar_lipsync`, and `upscale`, and each reports the exact tool. Use `videodraft models video --category video_edit` to narrow the list. `videodraft models audio` lists Seed Audio, Google Lyria, and ElevenLabs audio/media tools, while `videodraft models voices` lists TTS voices. Consult them instead of guessing capabilities.\\n\\n## Async jobs\\n\\nImage/video generation is asynchronous: commands submit a job and **wait by default**, printing output URLs (and saving files with `--download`). In scripts/CI prefer explicit control:\\n\\n```bash\\nJOB=$(videodraft generate image \\"...\\" --no-wait --json | jq -r .job_id)\\nvideodraft wait \\"$JOB\\" --download \\"./outputs/{job_id}_{index}.{ext}\\" --json\\n```\\n\\nFor MANY jobs: submit each with `--no-wait`, collect ALL with one command \u2014 `videodraft wait <id1> <id2> ...` polls every job from one process with one batched request per tick. Do NOT spawn parallel `wait`/`generate --wait` processes for a batch.\\n\\nIf a wait times out, the job is still running server-side \u2014 `videodraft status <job_id>` later. Never re-submit just because a wait timed out (that double-spends credits).\\n\\n## Local files and reference images\\n\\nReference inputs must be public URLs. The CLI uploads local files automatically wherever a URL is expected (`--ref photo.jpg`, `--start-image frame.png`), or explicitly:\\n\\n```bash\\nURL=$(videodraft upload ./product.png --json | jq -r .url)\\n```\\n\\nNever silently drop a reference you couldn\'t upload \u2014 stop and tell the user. Never upload a user\'s file to a third-party host.\\n\\nWhen the user attaches media, classify each item before acting: a recurring **visual asset** (character/product/location/style), actual **footage to place as shots**, or **inspiration only**. See [references/pipeline.md](references/pipeline.md) for how each role flows into a project.\\n\\n## Showing media to the user\\n\\nGenerated media is **not** displayed in the chat automatically \u2014 you decide what to show. To preview an asset inline, save it locally (use `--download` so it lands under `media/`) and reference its **local path** as a Markdown link with a **leading `./`**:\\n\\n```\\n[ferrari shot](./media/ferrari_01.png) \u2190 image card\\n[the clip](./media/clip.mp4) \u2190 video player\\n[voiceover](./media/vo.mp3) \u2190 audio player\\n```\\n\\nPut the Markdown link **in your message text** \u2014 video and audio embed exactly like images. Do **not** use `SendUserFile` (or other file-send tools) to display media: that renders inside a collapsible tool card and gets buried in the tool list. The Markdown link in your prose is what produces the inline card.\\n\\nUse the path you saved to: a **workspace-relative** path (`./media/clip.mp4`, or `./<any-folder>/clip.mp4` \u2014 any folder in the workspace works), or the **absolute** path for a file outside the workspace (e.g. `/Users/you/Desktop/clip.mp4` or another workspace\'s path). Both render. Show the finished results worth showing (and only those \u2014 not every intermediate job). A bare CDN URL or a JSON dump of output URLs does **not** render; the local-path Markdown link is what produces an inline card.\\n\\n## The full pipeline (idea \u2192 MP4)\\n\\n```bash\\nvideodraft create \\"<idea>\\" --ar 9:16 # project: script \u2192 visual assets \u2192 storyboard\\nvideodraft shots <project_id> --grid --estimate # cost preview, confirm with user\\nvideodraft shots <project_id> --grid # batch shot images (waits, writes onto shot cards)\\nvideodraft produce <project_id> # voiceovers + captions + production timeline\\nvideodraft export <project_id> --download final.mp4\\n```\\n\\nOptional between produce and export: per-shot motion clips (`videodraft generate video ... --project <id>` then place it with `videodraft attach <project> --scene N --shot M --media <url|file> --type video --duration <s>`), music (`videodraft generate music \\"...\\" --attach <project_id>`), and standalone audio assets (`generate audio`, `generate sound-effect`, `generate dialogue`, `generate voice-changer`, `generate dub`). Details, per-step tools and editing rules: [references/pipeline.md](references/pipeline.md).\\n\\nAvatar/talking-head videos use dedicated commands. For a reusable managed avatar, obtain or generate a clear portrait \u2192 `videodraft avatar script` when needed \u2192 `videodraft avatar create` \u2192 `videodraft avatar render --resolution 720p`. For a one-off portrait, use `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>`. For an existing video plus replacement audio, use `videodraft avatar lipsync <video> --audio <file>`. Managed script/creation is bundled/free; direct Fabric, Sync, the managed Fabric render, and optional portrait generation/upscaling are paid. Confirm expensive steps first.\\n\\n## Working with project data\\n\\nA project is one JSON blob (script, storyboard scenes, shot cards, visual assets, production timeline). To inspect: `videodraft projects get <id>`. To edit: fetch `--raw`, modify, then `videodraft call update_project` \u2014 objects deep-merge, **arrays replace wholesale** (send the complete `storyboard.scenes` array to change one scene). Snapshot first with `videodraft checkpoint create <id>` before risky edits. Schema reference: `videodraft call get_project_schema`.\\n\\n## More\\n\\n- [references/pipeline.md](references/pipeline.md) \u2014 project data model, step-by-step tools, attaching media, editing safely\\n- [references/models.md](references/models.md) \u2014 choosing image/video models, pricing patterns, voices and styles\\n- [references/examples.md](references/examples.md) \u2014 recipes: batch product videos from a CSV, talking-head from a script, changelog video in CI\\n","references/examples.md":"# Recipes\\n\\nWorking patterns for common asks. All assume auth (`videodraft login` once, or `VIDEODRAFT_API_KEY` in the environment) and use `--json` for parsing.\\n\\n## 1. Batch product videos from a CSV\\n\\nOne 9:16 product clip per row of `products.csv` (`name,image_url,tagline`):\\n\\n```bash\\n#!/usr/bin/env bash\\nset -euo pipefail\\nmkdir -p outputs\\n\\nwhile IFS=, read -r name image tagline; do\\n job=$(videodraft generate video \\\\\\n \\"Premium product shot of ${name}: ${tagline}. Slow orbit, studio lighting.\\" \\\\\\n --model gemini-omni-flash --ar 9:16 --duration 6 \\\\\\n --start-image \\"$image\\" \\\\\\n --no-wait --json | jq -r .job_id)\\n echo \\"$name,$job\\" >> outputs/jobs.csv\\ndone < <(tail -n +2 products.csv)\\n\\n# Collect ALL results with ONE process (batched polling \u2014 one request per tick)\\nvideodraft wait $(cut -d, -f2 outputs/jobs.csv) \\\\\\n --download \\"outputs/{job_id}_{index}.{ext}\\" --json > outputs/results.json\\n# map job ids back to product names via outputs/jobs.csv\\n```\\n\\nSubmit-then-collect parallelizes server-side generation; the single multi-id `wait` keeps it to one local process and one batched poll request per tick no matter how many jobs. Gemini Omni Flash is selected because these are six-second first-frame product clips. Estimate first: `videodraft costs gemini-omni-flash --type video --duration 6 --resolution 720p --audio` \xD7 rows, and confirm with the user.\\n\\n## 2. Full marketing video from one idea\\n\\n```bash\\nvideodraft create \\"30-second launch video for Solace, a sleep-tracking ring. Calm, premium, dark palette.\\" \\\\\\n --ar 9:16 --style cinematic --json > project.json\\nPROJECT=$(jq -r .project_id project.json)\\n\\nvideodraft shots \\"$PROJECT\\" --grid --estimate # show the user the cost; get a go-ahead\\nvideodraft shots \\"$PROJECT\\" --grid\\nvideodraft produce \\"$PROJECT\\"\\nvideodraft generate music \\"minimal ambient, warm pads, 60 BPM\\" --attach \\"$PROJECT\\"\\nvideodraft generate audio \\"Extend @Audio1 into a 20-second transition\\" --ref-audio ./intro.wav --format wav --download ./transition.wav\\nvideodraft export \\"$PROJECT\\" --download solace-launch.mp4\\n```\\n\\nThe project stays editable at the URL in `project.json` (`.urls`) \u2014 hand it to the user for tweaks.\\n\\n## 3. Talking-head (avatar) video\\n\\nWhen the user has no portrait, generate a clear front-facing avatar image first. Skip this step when they supplied one or an existing character should be reused.\\n\\n```bash\\nvideodraft generate image \\\\\\n \\"Front-facing head-and-shoulders portrait of a friendly coffee expert, direct eye contact, natural expression, clean studio background\\" \\\\\\n --model nano-banana-2 --ar 9:16 --download ./media/avatar.png\\n\\nSCRIPT=$(videodraft avatar script \\"why our espresso subscription saves you money\\" --style ad-style --json | jq -r .script)\\nAVATAR=$(videodraft avatar create ./media/avatar.png --script \\"$SCRIPT\\" --voice elevenlabs-kPzsL2i3teMYv0FxEYQ6 --ar 9:16 --json | jq -r .avatar_video_id)\\nvideodraft avatar render \\"$AVATAR\\" --resolution 720p # VEED Fabric paid step; confirm cost first (~20 credits/sec)\\n```\\n\\n`avatar script` and `avatar create` (including speech) are bundled/free. In this example only the optional portrait generation and Fabric render spend credits.\\n\\nIf the portrait is low resolution, enhance it before `avatar create`:\\n\\n```bash\\nvideodraft upscale image ./founder-small.jpg --scale 2x --download ./media/founder-upscaled.png\\n```\\n\\nFor a one-off portrait animation without creating a managed avatar record:\\n\\n```bash\\nvideodraft avatar fabric ./founder.jpg \\\\\\n --text \\"Welcome to the weekly product update.\\" \\\\\\n --voice-description \\"warm, confident American presenter\\" \\\\\\n --resolution 720p --download ./media/presenter.mp4\\n```\\n\\nWhen the user already has both the video and replacement speech:\\n\\n```bash\\nvideodraft avatar lipsync ./presenter.mp4 \\\\\\n --audio ./localized-voiceover.mp3 \\\\\\n --sync-mode loop --download ./media/presenter-localized.mp4\\n```\\n\\nEdit an existing video with a dedicated edit model:\\n\\n```bash\\nvideodraft models video --category video_edit\\nvideodraft edit video ./product-demo.mp4 \\\\\\n \\"Turn the room into a warm evening scene while preserving the product and camera motion\\" \\\\\\n --model wan-2.7-ref-edit --ref ./evening-style.jpg \\\\\\n --preserve-audio --download ./media/product-demo-evening.mp4\\n```\\n\\nTransfer motion from a reference clip onto a character image:\\n\\n```bash\\nvideodraft edit motion ./character.png \\\\\\n \\"Apply the dancer\'s movement to this character while preserving identity\\" \\\\\\n --motion-video ./dance-reference.mp4 \\\\\\n --model kling-v3-motion-control --quality pro \\\\\\n --download ./media/character-dance.mp4\\n```\\n\\n## 4. Changelog video in CI\\n\\nIn a GitHub Action with `VIDEODRAFT_API_KEY` set as a secret:\\n\\n```bash\\nNOTES=$(git log --oneline v1.2.0..HEAD | head -20)\\nvideodraft create \\"Weekly product update video. Energetic, 20 seconds. Changes: ${NOTES}\\" --ar 16:9 --json > p.json\\nPROJECT=$(jq -r .project_id p.json)\\nvideodraft shots \\"$PROJECT\\" && videodraft produce \\"$PROJECT\\"\\nvideodraft export \\"$PROJECT\\" --download changelog.mp4 --wait-timeout 30m\\n```\\n\\n## 5. Variations and picking a winner\\n\\n```bash\\nvideodraft generate image \\"logo concept: minimalist fox, geometric\\" --num 4 --download \\"./concepts/{job_id}_{index}.{ext}\\" --json\\n# Show all 4 to the user; regenerate the chosen one at higher res:\\nvideodraft generate image \\"<same prompt>\\" --model nano-banana-pro --resolution 4K\\n```\\n\\n## 6. Reaching tools without a curated command\\n\\n```bash\\nvideodraft tools list --json | jq -r \'.[].name\'\\nvideodraft tools schema attach_media_to_shot --json\\nvideodraft call attach_media_to_shot --args \'{\\"project_id\\":\\"...\\",\\"scene_index\\":0,\\"shot_index\\":1,\\"media_url\\":\\"https://...\\",\\"media_type\\":\\"video\\",\\"duration_seconds\\":6}\'\\n```\\n\\nAnything the VideoDraft MCP exposes \u2014 character studio, product studio, timeline editing \u2014 is reachable this way even before it gets a curated command.\\n\\n## 7. Enhance an existing asset without changing it\\n\\n```bash\\n# Light image cleanup, no enlargement\\nvideodraft upscale image ./poster.png --scale 1x --download ./media/poster-enhanced.png\\n\\n# General image and video enlargement\\nvideodraft upscale image ./frame.png --scale 2x --download ./media/frame-2x.png\\nvideodraft upscale video ./clip.mp4 --scale 2x --download ./media/clip-2x.mp4\\n```\\n\\nUse these when the content is correct and only quality or resolution needs improvement. If the poster text, composition, subject, or motion is wrong, edit or regenerate instead.\\n","references/models.md":"# Choosing models (and predicting cost)\\n\\nAlways consult the live catalog instead of memorizing this page \u2014 models change weekly:\\n\\n```bash\\nvideodraft models image --json # every image model + inputs (aspect ratios, resolutions, max refs)\\nvideodraft models video --json # every video model + inputs + per-second pricing metadata\\nvideodraft models audio --json # standalone audio/media models + pricing inputs\\nvideodraft models voices --json # TTS voices\\nvideodraft models styles --json # visual style presets\\n```\\n\\n## Task-based model selection\\n\\nHonor an explicitly named model when it supports the request. Otherwise choose from the task\'s inputs, duration, audio, quality, speed, and cost. Pass the chosen model explicitly instead of relying on a blind platform fallback.\\n\\n### Images\\n\\n| Need | Choose | Why |\\n| -------------------------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------- |\\n| Most generation, editing, character consistency, or reference work | `nano-banana-2` | Best general default; 1K/2K/4K and up to 14 reference images |\\n| Highest-quality complex generation or reasoning | `nano-banana-pro` | Premium Nano Banana quality and reasoning |\\n| Fast, inexpensive drafts and iteration | `nano-banana-2-lite` | Fastest/cheapest Nano Banana option; 1K only, up to 14 references |\\n| Posters, title cards, signs, logos, or any image with important readable text | `gpt-image-2` | Strong text rendering; up to 16 image inputs and 1K/2K/4K output |\\n| Complex multi-image composition, precise editing, or a strong alternate interpretation | `gpt-image-2` | Strong non-Nano alternative with multi-image input |\\n\\nUse `--num 1..4` for variations of one prompt in a single call. Never loop separate paid calls for variations that fit in one request.\\n\\n### Videos\\n\\n| Need | Choose | Important limits |\\n| ---------------------------------------------------------------------------------------------------------- | ------------------- | --------------------------------------------------------------------------------------------------- |\\n| Most text, first-frame, image-reference, or source-video-edit requests up to 10s | `gemini-omni-flash` | 720p, 3-10s or auto, audio always on, up to 10 total image inputs, one source video |\\n| Video/audio references, mixed reference media, broad aspect ratios, frame-mode first+last frame, or 11-15s | `seedance-2` | 4-15s or auto; up to 9 image, 3 video, and 3 audio refs; audio toggle; Mini/Fast are 480p/720p only |\\n| Fast polished 3-15s video with first frame, multi-prompt, and native audio | `kling-v3-turbo` | Audio always on; Pro default; no end frame or reference-media mode |\\n| Cinematic 3-15s with image references, first+last frame, multi-prompt, audio control, or 4K | `kling-o3` | Up to 7 image refs; Standard/Pro/4K; audio toggle |\\n| Kling 3-15s with first+last frame, multi-prompt, optional audio, or 4K, without reference-image mode | `kling-3.0` | Standard/Pro/4K; audio toggle |\\n| User explicitly requests Veo, or the selected workflow specifically needs Veo | `google-veo3.1` | Good fallback, but not the preferred general model |\\n\\nRouting rules:\\n\\n- Around 11-15 seconds with native audio: use Kling or Seedance, not Gemini.\\n- One existing source video that should be edited, with an output up to 10 seconds and no additional media references to preserve: use Gemini Omni Flash.\\n- Video or audio supplied as creative reference: use Seedance 2.0.\\n- A video plus any image/audio references that must all be preserved: use Seedance 2.0. Do not promise that Gemini will preserve mixed source media; its Fal BYOK edit mode accepts only the source video and prompt.\\n- First and last frame control: use Seedance, Kling O3, or Kling 3.0. Gemini supports a first frame but not a last frame.\\n- Seedance reference mode and first-plus-last-frame mode are separate. Do not promise reference video/audio plus a last frame in one generation.\\n- Multi-prompt sequencing: use Kling 3.0 Turbo, Kling O3, or Kling 3.0.\\n- Seedance quality: `mini` for the lowest cost, `fast` for speed, `standard` for maximum quality and for 1080p/4K.\\n\\n### Video edit and motion-control categories\\n\\nUse `videodraft models video --category video_edit` for existing-video transforms and `--category motion_control` for motion transfer.\\n\\n| Need | Command/model | Important limits |\\n| ------------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\\n| Simple prompt edit of one video | `videodraft edit video <video> \\"...\\" --model grok-imagine-video-edit` | No image refs; source truncated to 8s; auto/480p/720p |\\n| Edit with one style/reference image | `--model wan-2.7-ref-edit --ref <image>` | One image ref; 2-10s or match source |\\n| Edit with several image references | `--model happy-horse-video-edit --ref ...` | Up to 5 refs; 720p/1080p; source capped at 15s |\\n| Controlled Kling edit | `--model kling-o3-video-ref-edit --ref ...` | Up to 4 refs; Standard/Pro; source clamped to 3-10s |\\n| Transfer reference motion to an image | `videodraft edit motion <image> \\"...\\" --motion-video <video>` | Kling V3 default; image orientation caps motion at 10s, video orientation at 30s |\\n\\nIf the user explicitly names one of these models, preserve it. The CLI uploads local source videos and reference images automatically. Editing returns an async job and waits by default.\\n\\nKling O3 and Wan 2.7 Ref/Edit are dual-mode cards. `videodraft edit video` uses edit mode. `videodraft generate video --model kling-o3-video-ref-edit` requires exactly one `--ref-video` and generates a new reference-guided clip. `--model wan-2.7-ref-edit` generates a new clip from one or more `--ref`/`--ref-video` inputs.\\n\\n### Reference-first video workflow\\n\\n- Prefer a start frame or reference image whenever a specific character, product, location, style, composition, or brand identity must stay recognizable.\\n- If the user gives a reference, pass it. Never silently replace it with a text description.\\n- If no reference exists and continuity matters, generate a still first with the user\'s explicitly requested compatible image model, otherwise use Nano Banana 2. Wait for the image URL, then animate it with the selected video model. Confirm the combined image plus video cost before starting.\\n- For multi-shot scenes, generate shot images with `videodraft shots <project_id> --model <selected-image-model> --grid`. Preserve an explicitly requested compatible image model; otherwise use `nano-banana-2`. The grid establishes the scene and characters together, then decodes into individual shot images.\\n- Animate the decoded shot images as per-shot start frames or references. Do not independently text-generate each video clip when the shots need to match.\\n- Pure text-to-video remains appropriate for generic one-off footage where no subject, composition, or continuity needs to be preserved.\\n\\n### Audio\\n\\n- **Seed Audio 1.0**: use `videodraft generate audio` for open-ended speech, sound, music, or prompt-driven audio editing. It accepts up to three audio references or one image. Address audio references as `@Audio1`, `@Audio2`, and `@Audio3`. Preset and custom cloned voice IDs are supported. Output is up to 120 seconds. There is no requested-duration input. The CLI automatically retries transient responses with one idempotency key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- **Voiceover/TTS**: prefer ElevenLabs. Brittney is the platform default voice; under ElevenLabs BYOK, use a compatible voice from the user\'s account. Honor another supported voice/provider when the user explicitly selects it.\\n- **Dialogue, voice changing, and dubbing**: ElevenLabs only.\\n- **Sound effects**: ElevenLabs Sound Effects only.\\n- **Music**: use `lyria-3-clip-preview` for a short instrumental/background score, `lyria-3-pro-preview` for a longer or higher-quality instrumental score, and `elevenlabs-music` when vocals/lyrics or a specified 10-120 second length matter.\\n- Voice Changer and Dubbing require the source media duration and currently accept source media up to 300 seconds.\\n\\n### Avatar / talking head\\n\\nChoose the dedicated path from the media the user already has:\\n\\n| Starting media | Command | Use |\\n| ----------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------- |\\n| Portrait + script, reusable avatar record | `videodraft avatar create <portrait> --script \\"...\\"` then `avatar render` | Managed avatar flow with bundled speech preparation |\\n| Portrait + text | `videodraft avatar fabric <portrait> --text \\"...\\"` | One-off direct VEED Fabric text mode |\\n| Portrait + existing audio | `videodraft avatar fabric <portrait> --audio <audio>` | One-off direct VEED Fabric audio lip sync |\\n| Existing video + existing audio | `videodraft avatar lipsync <video> --audio <audio>` | Sync Labs Lipsync 2 |\\n\\nThe managed renderer is VEED Fabric Fast (`veed/fabric-1.0/fast`). Direct Fabric and Sync Labs are paid AI Studio generations and return async job IDs.\\n\\n1. Obtain the avatar image. Prefer the user\'s supplied portrait or an existing character. If none exists, use the user\'s explicitly requested compatible image model, otherwise generate a front-facing head-and-shoulders portrait with `nano-banana-2`, direct eye contact, a natural expression, and a clean background. Match the intended video aspect ratio when practical.\\n2. If the portrait is visibly soft or too small, run Topaz image enhancement/upscaling before animation.\\n3. Generate a script only if needed: `videodraft avatar script \\"<idea>\\"`.\\n4. Create the avatar record and speech: `videodraft avatar create <portrait-url-or-file> --script \\"...\\" --voice <id> --ar 9:16`. Prefer ElevenLabs when unspecified, but honor another explicitly selected supported voice/provider.\\n5. Render with VEED Fabric: `videodraft avatar render <avatar_video_id> --resolution 720p`.\\n\\nThe portrait is passed as the avatar\'s character image, not as a generic video\'s start frame. Prefer rendering directly at 720p. Use 480p only when the user prioritizes lower cost. Avatar script generation and `avatar create` (including speech) are bundled/free. Confirm the Fabric render cost, plus portrait generation or upscaling when needed.\\n\\nDirect Fabric text/audio and Sync Labs do not use the managed avatar record. The CLI uploads local portrait, video, and audio files automatically. `avatar fabric --speed fast` applies only to audio mode. Sync costs 5 credits per verified audio second; under Fal BYOK, `sync_mode` remains available but `temperature` and `active_speaker` are ignored by the provider.\\n\\n### Upscaling / enhancement\\n\\n- **Images**: Topaz via `videodraft upscale image <url-or-file> --scale 1x|2x|4x`. Use 1x for light enhancement without enlargement, 2x as the general default, and 4x only when the source quality and target size justify it. The result is synchronous.\\n- **Videos**: Topaz via `videodraft upscale video <url-or-file> --scale 2x`. Use 2x by default. The job is asynchronous; the CLI waits by default, while MCP callers poll `check_generation_status`. MCP video input must be VideoDraft-hosted, so upload local or external sources first.\\n- Use upscaling to preserve the image/video while improving detail, resolution, or cleanup. It cannot fix the wrong subject, misspelled text, bad framing, unwanted objects, broken continuity, or incorrect motion. Use an edit or regeneration for those problems.\\n- For a new Fabric avatar, render directly at 720p instead of rendering at 480p and then upscaling. Upscale the source portrait first only when the portrait itself is low quality.\\n\\n## Capability gotchas\\n\\n- Each model\'s `inputs` block is authoritative: supported `aspect_ratios`, `resolutions`, `quality_options`, `start_frame`/`end_frame`, `max_reference_images/videos/audio`, `multi_prompt`, `audio_toggle`. Passing an unsupported input fails with a clear error \u2014 check first, don\'t trial-and-error paid calls.\\n- Most video models support only 16:9 / 9:16 / 1:1. A 3:4 request hard-fails on most.\\n- `--seed` reproduces a specific output on models that support it (e.g. Flux, Ideogram V4); everything else ignores it. You do not need a seed for variation \u2014 `--num` already varies.\\n- `--rendering-speed` applies to Ideogram (V3: `Default`/`Turbo`/`Quality`; V4: `Turbo`/`Balanced`/`Quality`) and affects image cost \u2014 pass it to `videodraft costs ... --rendering-speed <tier>` for an accurate estimate. Always trust `videodraft models image --json` over this list; new models and tiers appear there the moment the platform ships them, with no CLI update.\\n- `seedream-v5-pro` supports unified text-to-image and reference-image editing with up to 10 image references. Use `--resolution 1K` for 7 credits/image or `--resolution 2K` for 14 credits/image.\\n- Reference inputs: `--ref <img>` (images), `--ref-video <v>` (Gemini Omni Flash, Seedance 2, Wan 2.7), `--ref-audio <a>` (Seedance 2). The CLI uploads local files for all of these, so you can pass a path or a URL. `--segment \\"<prompt>:<seconds>\\"` (repeatable) drives multi-prompt models (Kling 3.0 / 3.0 Turbo / O3); total 3-15s. `generate image --video-ref` is the nano-banana-2 video reference.\\n- The top-level prompt is OPTIONAL for `generate video` with multi-prompt models and for Kling 3.0 Turbo (`--model kling-v3-turbo`) image-to-video \u2014 a `--segment`-only or `--start-image`-only call is valid. Every other model still needs a prompt; the server enforces per-model rules.\\n- AI Production: `videodraft produce <project> --mode full_video` generates one Seedance 2 video per scene; poll with `videodraft generations`, then `videodraft finalize <project>` swaps them into the timeline before `export`. If the user explicitly requests another compatible video model, do not use this fixed Seedance path. Generate the project shots manually with the requested model and attach them to the timeline.\\n\\n## Cost model\\n\\n- Images: per image (\xD7 `--num`). Matrix-priced models (GPT-Image, Nano Banana Pro, Seedream v5 Pro) vary by resolution/quality.\\n- Video: usually credits/second \xD7 duration; rate depends on model + resolution + quality + native audio on/off.\\n- Shot-image batches: one image per shot (+1 grid image per scene in `--grid` mode) \u2014 the largest single spend in the pipeline.\\n- VEED Fabric avatar renders: ~10 credits/sec at 480p, ~20/sec at 720p. Avatar creation and its speech are bundled/free; only optional portrait generation/upscaling adds cost before the render.\\n- Direct VEED Fabric: text or normal audio is 8 credits/sec at 480p and 15/sec at 720p; fast audio is 10/sec at 480p and 20/sec at 720p.\\n- Sync Labs Lipsync 2: 5 credits per verified audio second.\\n- Voiceover TTS: 10 credits per 1000 characters for standard voices, 30 per 1000 for cloned `custom-*` voices (min 1, pro-rated); applies to standalone voiceovers AND per-scene narration during `produce`. Silent tracks are free. Voice cloning itself is a flat 150 credits per clone.\\n- Lyria music: flat per track, 10 credits (clip) / 15 credits (pro).\\n- Seed Audio 1.0: 19 credits per actual output minute, prorated and rounded up to a whole credit. VideoDraft reserves the 120-second maximum of 38 credits and refunds the unused portion after generation. Fal BYOK is free.\\n- ElevenLabs audio: sound effects are per second, dialogue is per character, music/voice-changer/dubbing are per started minute. Voice changer and dubbing reject source media above 300s in the current synchronous flow.\\n- Upscales: priced by scale and source size.\\n\\nQuote before spending:\\n\\n```bash\\nvideodraft costs gemini-omni-flash --type video --duration 8 --resolution 720p --audio\\nvideodraft costs seedance-2 --type video --duration 15 --resolution 720p --quality standard --audio\\nvideodraft costs elevenlabs-dubbing --type audio --duration 60\\nvideodraft costs seed-audio-1.0 --type audio --duration 60 # scenario only; model controls actual length\\nvideodraft costs elevenlabs-dialogue --type audio --chars 350\\nvideodraft costs voiceover --type audio --chars 800 # TTS: 10 cr / 1000 chars\\nvideodraft generate video \\"...\\" --model gemini-omni-flash --estimate # same quote, inline\\n```\\n","references/pipeline.md":"# VideoDraft pipeline reference\\n\\nEverything here works through the CLI (`videodraft <command>` / `videodraft call <tool>`) or the MCP connector (tool names in backticks). One backend; pick the surface you have.\\n\\nUse direct asset tools for standalone images, clips, audio, upscales, and descriptions. Use a project for any multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export even when the request does not use the word \\"project.\\" Script-only uses a script-stage project and stops at the script.\\n\\n## Stages and their tools\\n\\n| Stage | CLI | Underlying tool |\\n| --------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------ |\\n| Idea \u2192 full storyboard project | `videodraft create \\"<idea>\\"` | `generate_storyboard_from_idea` |\\n| Idea \u2192 script only (stop there) | `videodraft create \\"<idea>\\" --script-only` | `generate_script_from_idea` |\\n| Footage IS the video | `videodraft call generate_storyboard_from_media` | `generate_storyboard_from_media` |\\n| Batch shot images | `videodraft shots <project>` | `generate_shot_images` |\\n| One shot image | `videodraft generate image --project <id> --scene N --shot M` | `generate_image` |\\n| Produce (voiceover, captions, timeline) | `videodraft produce <project>` | `produce_project` |\\n| Per-shot motion prompts | `videodraft video-prompts <project>` | `generate_video_prompts` |\\n| Motion clip for a shot | `videodraft generate video --project <id>` | `generate_video` |\\n| Attach a finished clip to the timeline | `videodraft attach <project> --scene N --shot M --media <url> --type video` | `attach_media_to_shot` |\\n| Background music | `videodraft generate music --attach <project>` | `generate_music` / `set_background_music` |\\n| General or reference-driven audio | `videodraft generate audio \\"...\\"` | `generate_audio` |\\n| Sound effect | `videodraft generate sound-effect \\"...\\"` | `generate_sound_effect` |\\n| Dialogue audio | `videodraft generate dialogue --line \\"voice:text\\"` | `generate_dialogue` |\\n| Voice changer | `videodraft generate voice-changer <audio>` | `change_voice` |\\n| Dubbing | `videodraft generate dub <audio_or_video>` | `dub_media` |\\n| Scene voiceover | `videodraft generate voiceover --project <id> --scene N` | `generate_voiceover` |\\n| Avatar script | `videodraft avatar script \\"<idea>\\"` | `generate_avatar_script` |\\n| Avatar + speech | `videodraft avatar create <portrait> --script \\"...\\"` | `create_avatar_video` |\\n| Talking-head render | `videodraft avatar render <avatar_video_id>` | `render_avatar_video` + `get_avatar_video` |\\n| Direct portrait + text/audio | `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>` | `generate_veed_fabric_video` |\\n| Existing video + replacement audio | `videodraft avatar lipsync <video> --audio <file>` | `generate_sync_lipsync_video` |\\n| Existing-video AI edit | `videodraft edit video <video> \\"<change>\\" --model <video-edit-model>` | `edit_video` |\\n| Motion transfer | `videodraft edit motion <image> \\"<direction>\\" --motion-video <video>` | `generate_motion_control_video` |\\n| Image enhancement/upscale | `videodraft upscale image <image>` | `upscale_image` |\\n| Video enhancement/upscale | `videodraft upscale video <video>` | `upscale_video` |\\n| Final MP4 | `videodraft export <project>` | `export_video` + `check_export_status` |\\n\\n## Rules that prevent broken results\\n\\n- **The storyboard is generated FROM the script**, never from the raw idea. `videodraft create` runs the whole chain correctly. Don\'t call `generate_storyboard_scenes` with a raw idea as the \\"script\\".\\n- **Visual consistency**: never generate a storyboard shot in isolation. Shot prompts carry `[[asset:Name]]` / `[[shot:X-Y]]` tags that `generate_shot_images` resolves against the project\'s visual assets and prior shots. When generating a single shot whose prompt has no tags, pass `--ref` images yourself (the project\'s visual assets and/or the previous shot\'s image; `projects get` exposes both). For scenes with multiple shots or recurring characters, prefer `videodraft shots <project> --model <selected-image-model> --grid`: preserve an explicitly requested compatible image model, otherwise use `nano-banana-2`. It creates one coherent scene grid, then decodes it into individual shot images.\\n- **Reference-first video**: when identity, styling, or composition matters, do not generate each motion clip from text alone. Generate or select the shot still first, then pass the decoded shot image as `--start-image` or `--ref` to the selected video model. AI Production already composes scene grids and sends them to Seedance as references. If the user explicitly requests another compatible video model, bypass fixed Seedance full-video mode and generate the per-shot clips with the requested model, using the individual decoded shot images as anchors.\\n- **Hold off generating shot images while the user is still iterating** on storyboard structure.\\n- **produce \u2192 export ordering**: `export` requires a produced project where every production scene has timeline media. If `produce` returns `generating_shot_images`, poll the job ids it returns, then re-run produce.\\n- **Generated motion clips do not auto-attach**: after `generate video` completes, attach the clip with `attach_media_to_shot` (`media_type:\\"video\\"`, include `duration_seconds`) \u2014 it replaces the production timeline clip while keeping the storyboard still.\\n- **Talking heads use dedicated avatar tools**: do not use `generate video`. Use managed `avatar create` and `avatar render` for reusable avatars, direct `avatar fabric` for a portrait plus text/audio, and `avatar lipsync` for an existing video plus replacement audio. Reuse a supplied person image or generate a clear front-facing portrait with the explicitly requested compatible image model, otherwise Nano Banana 2. Managed avatar creation and speech are bundled/free; direct Fabric, Sync, and render are paid.\\n- **Existing-video edits use their own category**: call `edit_video` or `videodraft edit video` with a `video_edit` model when transforming the source itself. Kling O3 and Wan 2.7 Ref/Edit are dual-mode: their reference-generation modes may use generic `generate_video` to create a new guided clip. Motion transfer similarly uses `generate_motion_control_video` or `videodraft edit motion` with a `motion_control` model.\\n- **Upscaling preserves rather than redesigns**: use Topaz when resolution, detail, or cleanup is the problem. Regenerate or edit when the subject, text, framing, continuity, or motion is wrong. Upscale a low-quality avatar portrait before Fabric; do not render a new avatar at 480p just to upscale the result.\\n- **Timeouts on the one-shot create**: if `create` times out at the transport layer, the project was still created server-side \u2014 `videodraft projects list`, take the most recent, and resume with its id. Don\'t start a duplicate.\\n\\n## User-attached media: classify roles first\\n\\nFor EACH attached file decide:\\n\\n- **visual_asset** \u2014 recurring reference (character / product / location / style). Upload, then pass in `visual_assets` of `generate_storyboard_from_idea` (via `videodraft call`), or add to an existing project with `add_visual_assets`. Type must be one of `character | object | location | style | custom` with a short name + concrete description.\\n- **shot** \u2014 the media IS footage for the video. Whole video = footage \u2192 `generate_storyboard_from_media`. Idea + footage \u2192 `generate_storyboard_from_idea` with `shot_media`. Existing storyboard \u2192 `attach_media_to_shots`.\\n- **reference** \u2014 inspiration only \u2192 fold a description into the idea/instructions; don\'t place it as a shot or asset.\\n\\nAmbiguous (e.g. a person holding a product)? Ask the user.\\n\\nUploads persist in the media library \u2014 recall later with `videodraft media list`.\\n\\n## Editing project data safely\\n\\n1. `videodraft call get_project_schema` \u2014 read the structure once per session.\\n2. `videodraft projects get <id> --raw` \u2014 the exact editable blob.\\n3. Modify; then `videodraft call update_project --stdin` with `{\\"project_id\\": \\"...\\", \\"data\\": {...}}`.\\n - Objects deep-merge key-by-key; **arrays replace wholesale** \u2014 send the complete array you\'re changing (e.g. all of `storyboard.scenes`).\\n - Scene shot arrays (`image_prompt` / `shot_types` / `shot_actions` / `search_prompt` / `preview_media`) are auto-aligned; fix-ups come back as warnings.\\n4. Snapshot before risky edits: `videodraft checkpoint create <id> --name \\"before re-script\\"`. Restore with `videodraft checkpoint restore <id> <version>`.\\n\\n## AI Studio sessions (standalone generations)\\n\\nProject generations group automatically. For standalone work in a long conversation, create one session up front and reuse it:\\n\\n```bash\\nSESSION=$(videodraft call create_ai_studio_session --arg name=\\"Fox brand explorations\\" --json | jq -r .session_id)\\nvideodraft generate image \\"...\\" --session \\"$SESSION\\"\\n```\\n"}');
3874
+ if ('{"SKILL.md":"---\\nname: videodraft\\ndescription: Create AI videos, images, Seed Audio, voiceovers, music, sound effects, dialogue, dubbing, storyboards, avatar videos, media upscales and product/ad videos with VideoDraft. Use when the user mentions VideoDraft, or asks to generate/make a video, video ad, explainer, storyboard, talking-head/avatar video, AI image, prompt-driven or reference-driven audio, voiceover/TTS, background music, sound effects, dialogue audio, voice changing, dubbing, or image/video enhancement and upscaling, including batch/programmatic video generation in scripts or CI. Works via the `videodraft` CLI (preferred in terminals) or the VideoDraft MCP connector.\\n---\\n\\n# VideoDraft\\n\\nVideoDraft is an AI video creation platform where asset generation is the priority lane:\\n\\n- **Asset generation**: standalone images, video clips, Seed Audio, voiceovers, music, sound effects, dialogue, voice-changed audio, dubbed media, upscales, and image descriptions. This is the fastest and most important lane. Treat these as complete deliverables when the user asks for assets.\\n- **Asset I/O**: upload local files, download outputs, auto-upload local references, and save generated media where the user can see it.\\n- **Project production**: idea \u2192 script \u2192 storyboard (scenes + shot images) \u2192 project data \u2192 production timeline \u2192 exported MP4. Use it for a multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export, even when the user does not say \\"project.\\" A script-only request also creates a script-stage project but stops at the script.\\n\\n## How to connect\\n\\nTwo equivalent surfaces (same backend, same credits, same projects):\\n\\n1. **CLI** (preferred when you have a shell): run `videodraft` if it\'s on PATH; otherwise `npx -y videodraft@latest` runs it with no install (needs Node \u226520; the `-y` skips npx\'s install prompt so it runs non-interactively; the package is fetched on first use and cached). For heavy use, `npm install -g videodraft`. If there\'s no Node/shell here but the MCP connector below is available, use that instead; if neither works, tell the user how to install (https://videodraft.ai/cli).\\n - Auth \u2014 pick by context, don\'t guess:\\n \u2022 INTERACTIVE (a human is in the session, e.g. Claude Code / Codex): on exit code 3 (\\"not authenticated\\"), tell the user to run `videodraft login` in their terminal \u2014 it opens their browser for a one-click VideoDraft sign-in (OAuth), no key to copy. Wait for them to confirm it succeeded, then retry the command. This is the preferred path when the user is present.\\n \u2022 HEADLESS / CI (no browser): set `VIDEODRAFT_API_KEY=vd_mcp_...` (a token the user mints at https://app.videodraft.ai/mcp-keys).\\n \u2022 SECURITY: never ask the user to paste a `vd_mcp_...` token into the chat \u2014 use browser `login` or the env var so the token never lands in the transcript.\\n - Every command accepts `--json` (parse this, don\'t scrape text). Exit codes: 0 ok, 1 error, 2 usage, 3 auth (see Auth above), 4 insufficient credits (\u2192 tell the user, don\'t retry).\\n - Tool discovery: start with `videodraft tools list` for the grouped catalog, then narrow with `videodraft tools list --lane assets`, `--lane asset_io`, `--lane project_data`, or `--lane production`.\\n - Asset lane: `videodraft generate ...`, `videodraft edit video|motion`, `videodraft avatar ...`, `videodraft upscale ...`, `videodraft upload`, and `videodraft download`.\\n - Full API access: `videodraft tools schema <name>`, `videodraft call <tool> --args \'<json>\'`.\\n2. **MCP connector**: if VideoDraft MCP tools (e.g. `generate_storyboard_from_idea`) are available, call them directly \u2014 the CLI\'s curated commands map 1:1 onto these tools.\\n\\n## First decision: asset or project?\\n\\n- **One standalone asset** (image, clip, voiceover, music track, sound effect, dialogue track, voice-changed file, dubbed media file, upscale, or description): generate it directly. Do NOT create a project.\\n - `videodraft generate image \\"a red fox in snow, cinematic\\" --ar 16:9 --download ./out/`\\n - `videodraft generate video \\"slow dolly over a misty lake\\" --model gemini-omni-flash --duration 6 --download ./out/`\\n- **A small set of related assets**: still stay in the asset lane. Use an AI Studio session if you need to group related generations. Switch to a project only when the deliverable matches the project criteria below or the user asks to attach the assets to one.\\n- **A multi-scene video / ad / explainer, storyboard, timeline, or final exported video**: create a project so the work stays organized, editable in the web app, and exportable.\\n - `videodraft create \\"30s launch video for our espresso machine\\" --ar 9:16`\\n- **Just a script** (no video asked for): `videodraft create \\"...\\" --script-only`. Stop at the script \u2014 do not build a storyboard the user didn\'t ask for.\\n- **Iterating on existing work**: find it first (`videodraft projects list`) and reuse that project. Never create a new project to change an existing one.\\n\\n## Choose the model from the task\\n\\nIf the user names a model, use it when compatible. If it cannot handle the request, explain why and recommend alternatives instead of silently switching. Otherwise inspect the inputs, duration, audio, quality, speed, and cost, check the live catalog, and pass an explicit model.\\n\\n**Images:**\\n\\n- `nano-banana-2`: general default, editing, consistency, and references.\\n- `nano-banana-pro`: maximum quality. `nano-banana-2-lite`: fast, inexpensive drafts.\\n- `gpt-image-2`: posters, logos, signs, title cards, readable text, or precise composition/editing.\\n\\n**Videos:**\\n\\n- `gemini-omni-flash`: general default up to 10s, first frame/image references, or editing one source video without extra media references. Fixed 720p with audio.\\n- `seedance-2`: 11-15s, video/audio/mixed references, wider ratios, selectable audio, or first/last frames. Use `mini` for cost, `fast` for speed, `standard` for quality or 1080p/4K.\\n- `kling-v3-turbo`: fast polished 3-15s with first frame, multi-prompt, and audio. `kling-o3`: image references, first/last frames, multi-prompt, audio control, or 4K. `kling-3.0`: similar without reference-image mode.\\n- Existing-video edits use `videodraft edit video`, not generic generation. Choose from the `video_edit` catalog category: Grok for simple prompt edits, Wan 2.7 for one style reference or source-matching duration, Happy Horse for up to 5 references, and Kling O3 for controlled reference-image edits.\\n- Kling O3 and Wan 2.7 Ref/Edit also have reference-generation modes. Use `videodraft generate video --model <ref-edit-id>` with `--ref-video`/`--ref` to generate a new guided clip; use `videodraft edit video` when changing the source itself.\\n- Motion transfer uses `videodraft edit motion` with Kling V3 by default, or Kling 2.6 when explicitly requested or lower cost matters. It requires a subject image and a motion-reference video.\\n- Use Veo 3.1 when explicitly requested or as a fallback.\\n\\n**Audio and utilities:**\\n\\n- Use Seed Audio 1.0 for open-ended text-to-audio, speech/music/sound synthesis, voice conditioning, or prompt-driven editing with up to three audio references or one image. Use `videodraft generate audio`. Reference clips are `@Audio1`, `@Audio2`, and `@Audio3` in array order. There is no duration input. Output is up to two minutes and settles at 19 credits per actual minute, with up to 38 credits reserved during generation. The CLI automatically retries transient responses with one operation key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- Prefer ElevenLabs for voiceover, dialogue, voice changing, dubbing, and sound effects. Honor an explicitly selected supported TTS voice/provider. Use Lyria for instrumental music and ElevenLabs Music for vocals, lyrics, or exact timing.\\n- Talking head/presenter: choose by source. Use managed `avatar create` then `avatar render` when the user wants a reusable avatar record and bundled speech. Use `avatar fabric` for a one-off portrait plus text or existing audio. Use `avatar lipsync` when both the source video and replacement audio already exist.\\n- Enhancement: use Topaz image/video upscaling only when the content is already correct. Use image 1x for cleanup, 2x by default, 4x when justified; use video 2x by default. Edit or regenerate creative errors.\\n\\nSee [references/models.md](references/models.md) for the detailed routing table and exact capability limits.\\n\\n## Prefer references when continuity matters\\n\\nPure text-to-image or text-to-video is fine for a generic one-off asset. When a specific character, product, location, style, composition, or brand identity must survive generation, use references instead of hoping the prompt recreates it.\\n\\n- If the user supplies reference media, preserve and pass it. Never reduce the request to text alone.\\n- When continuity matters, generate/select a strong still first with the selected image model (`nano-banana-2` by default), wait for its URL, then animate it as a start frame/reference. Confirm the combined image and video cost.\\n- For multiple shots, use `videodraft shots <project_id> --model <selected-image-model> --grid`, then animate the decoded shots. Preserve explicit models. A requested non-Seedance video model must use manual per-shot generation instead of Seedance full-video mode.\\n\\n## Cost and credits\\n\\nDo not call `videodraft credits` before routine generations. Paid endpoints validate and deduct atomically; if the balance is insufficient, the request is rejected before the provider job starts (CLI exit code 4). Check the balance only when the user asks, gives a credit budget, or a large workflow needs budget planning.\\n\\nFor expensive work, estimate with `--estimate` or `videodraft costs`, state the selected model/settings/cost, and get a go-ahead. This matters most for shot-image batches, long or high-resolution video, AI Production, and paid audio batches. Honor the user\'s confirmation preference for the session.\\n\\n`videodraft models image|video` lists the live image and video catalogs with supported inputs. Video entries are grouped as `generation`, `video_edit`, `motion_control`, `avatar_lipsync`, and `upscale`, and each reports the exact tool. Use `videodraft models video --category video_edit` to narrow the list. `videodraft models audio` lists Seed Audio, Google Lyria, and ElevenLabs audio/media tools, while `videodraft models voices` lists TTS voices. Consult them instead of guessing capabilities.\\n\\n## Async jobs\\n\\nImage/video generation is asynchronous: commands submit a job and **wait by default**, printing output URLs (and saving files with `--download`). Large downloaded images also get a downscaled copy in `previews/` next to them (the `preview` field / \\"inspect via preview\\" line in the output) \u2014 **look at the preview, deliver the original**; viewing full-resolution images bloats the chat permanently. In scripts/CI prefer explicit control:\\n\\n```bash\\nJOB=$(videodraft generate image \\"...\\" --no-wait --json | jq -r .job_id)\\nvideodraft wait \\"$JOB\\" --download \\"./outputs/{job_id}_{index}.{ext}\\" --json\\n```\\n\\nFor MANY jobs: submit each with `--no-wait`, collect ALL with one command \u2014 `videodraft wait <id1> <id2> ...` polls every job from one process with one batched request per tick. Do NOT spawn parallel `wait`/`generate --wait` processes for a batch.\\n\\nIf a wait times out, the job is still running server-side \u2014 `videodraft status <job_id>` later. Never re-submit just because a wait timed out (that double-spends credits).\\n\\n## Local files and reference images\\n\\nReference inputs must be public URLs. The CLI uploads local files automatically wherever a URL is expected (`--ref photo.jpg`, `--start-image frame.png`), or explicitly:\\n\\n```bash\\nURL=$(videodraft upload ./product.png --json | jq -r .url)\\n```\\n\\nNever silently drop a reference you couldn\'t upload \u2014 stop and tell the user. Never upload a user\'s file to a third-party host.\\n\\nWhen the user attaches media, classify each item before acting: a recurring **visual asset** (character/product/location/style), actual **footage to place as shots**, or **inspiration only**. See [references/pipeline.md](references/pipeline.md) for how each role flows into a project.\\n\\n## Showing media to the user\\n\\nGenerated media is **not** displayed in the chat automatically \u2014 you decide what to show. To preview an asset inline, save it locally (use `--download` so it lands under `media/`) and reference its **local path** as a Markdown link with a **leading `./`**:\\n\\n```\\n[ferrari shot](./media/ferrari_01.png) \u2190 image card\\n[the clip](./media/clip.mp4) \u2190 video player\\n[voiceover](./media/vo.mp3) \u2190 audio player\\n```\\n\\nPut the Markdown link **in your message text** \u2014 video and audio embed exactly like images. Do **not** use `SendUserFile` (or other file-send tools) to display media: that renders inside a collapsible tool card and gets buried in the tool list. The Markdown link in your prose is what produces the inline card.\\n\\nUse the path you saved to: a **workspace-relative** path (`./media/clip.mp4`, or `./<any-folder>/clip.mp4` \u2014 any folder in the workspace works), or the **absolute** path for a file outside the workspace (e.g. `/Users/you/Desktop/clip.mp4` or another workspace\'s path). Both render. Show the finished results worth showing (and only those \u2014 not every intermediate job). A bare CDN URL or a JSON dump of output URLs does **not** render; the local-path Markdown link is what produces an inline card.\\n\\n## The full pipeline (idea \u2192 MP4)\\n\\n```bash\\nvideodraft create \\"<idea>\\" --ar 9:16 # project: script \u2192 visual assets \u2192 storyboard\\nvideodraft shots <project_id> --grid --estimate # cost preview, confirm with user\\nvideodraft shots <project_id> --grid # batch shot images (waits, writes onto shot cards)\\nvideodraft produce <project_id> # voiceovers + captions + production timeline\\nvideodraft export <project_id> --download final.mp4\\n```\\n\\nOptional between produce and export: per-shot motion clips (`videodraft generate video ... --project <id>` then place it with `videodraft attach <project> --scene N --shot M --media <url|file> --type video --duration <s>`), music (`videodraft generate music \\"...\\" --attach <project_id>`), and standalone audio assets (`generate audio`, `generate sound-effect`, `generate dialogue`, `generate voice-changer`, `generate dub`). Details, per-step tools and editing rules: [references/pipeline.md](references/pipeline.md).\\n\\nAvatar/talking-head videos use dedicated commands. For a reusable managed avatar, obtain or generate a clear portrait \u2192 `videodraft avatar script` when needed \u2192 `videodraft avatar create` \u2192 `videodraft avatar render --resolution 720p`. For a one-off portrait, use `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>`. For an existing video plus replacement audio, use `videodraft avatar lipsync <video> --audio <file>`. Managed script/creation is bundled/free; direct Fabric, Sync, the managed Fabric render, and optional portrait generation/upscaling are paid. Confirm expensive steps first.\\n\\n## Working with project data\\n\\nA project is one JSON blob (script, storyboard scenes, shot cards, visual assets, production timeline). To inspect: `videodraft projects get <id>`. To edit: fetch `--raw`, modify, then `videodraft call update_project` \u2014 objects deep-merge, **arrays replace wholesale** (send the complete `storyboard.scenes` array to change one scene). Snapshot first with `videodraft checkpoint create <id>` before risky edits. Schema reference: `videodraft call get_project_schema`.\\n\\n## More\\n\\n- [references/pipeline.md](references/pipeline.md) \u2014 project data model, step-by-step tools, attaching media, editing safely\\n- [references/models.md](references/models.md) \u2014 choosing image/video models, pricing patterns, voices and styles\\n- [references/examples.md](references/examples.md) \u2014 recipes: batch product videos from a CSV, talking-head from a script, changelog video in CI\\n","references/examples.md":"# Recipes\\n\\nWorking patterns for common asks. All assume auth (`videodraft login` once, or `VIDEODRAFT_API_KEY` in the environment) and use `--json` for parsing.\\n\\n## 1. Batch product videos from a CSV\\n\\nOne 9:16 product clip per row of `products.csv` (`name,image_url,tagline`):\\n\\n```bash\\n#!/usr/bin/env bash\\nset -euo pipefail\\nmkdir -p outputs\\n\\nwhile IFS=, read -r name image tagline; do\\n job=$(videodraft generate video \\\\\\n \\"Premium product shot of ${name}: ${tagline}. Slow orbit, studio lighting.\\" \\\\\\n --model gemini-omni-flash --ar 9:16 --duration 6 \\\\\\n --start-image \\"$image\\" \\\\\\n --no-wait --json | jq -r .job_id)\\n echo \\"$name,$job\\" >> outputs/jobs.csv\\ndone < <(tail -n +2 products.csv)\\n\\n# Collect ALL results with ONE process (batched polling \u2014 one request per tick)\\nvideodraft wait $(cut -d, -f2 outputs/jobs.csv) \\\\\\n --download \\"outputs/{job_id}_{index}.{ext}\\" --json > outputs/results.json\\n# map job ids back to product names via outputs/jobs.csv\\n```\\n\\nSubmit-then-collect parallelizes server-side generation; the single multi-id `wait` keeps it to one local process and one batched poll request per tick no matter how many jobs. Gemini Omni Flash is selected because these are six-second first-frame product clips. Estimate first: `videodraft costs gemini-omni-flash --type video --duration 6 --resolution 720p --audio` \xD7 rows, and confirm with the user.\\n\\n## 2. Full marketing video from one idea\\n\\n```bash\\nvideodraft create \\"30-second launch video for Solace, a sleep-tracking ring. Calm, premium, dark palette.\\" \\\\\\n --ar 9:16 --style cinematic --json > project.json\\nPROJECT=$(jq -r .project_id project.json)\\n\\nvideodraft shots \\"$PROJECT\\" --grid --estimate # show the user the cost; get a go-ahead\\nvideodraft shots \\"$PROJECT\\" --grid\\nvideodraft produce \\"$PROJECT\\"\\nvideodraft generate music \\"minimal ambient, warm pads, 60 BPM\\" --attach \\"$PROJECT\\"\\nvideodraft generate audio \\"Extend @Audio1 into a 20-second transition\\" --ref-audio ./intro.wav --format wav --download ./transition.wav\\nvideodraft export \\"$PROJECT\\" --download solace-launch.mp4\\n```\\n\\nThe project stays editable at the URL in `project.json` (`.urls`) \u2014 hand it to the user for tweaks.\\n\\n## 3. Talking-head (avatar) video\\n\\nWhen the user has no portrait, generate a clear front-facing avatar image first. Skip this step when they supplied one or an existing character should be reused.\\n\\n```bash\\nvideodraft generate image \\\\\\n \\"Front-facing head-and-shoulders portrait of a friendly coffee expert, direct eye contact, natural expression, clean studio background\\" \\\\\\n --model nano-banana-2 --ar 9:16 --download ./media/avatar.png\\n\\nSCRIPT=$(videodraft avatar script \\"why our espresso subscription saves you money\\" --style ad-style --json | jq -r .script)\\nAVATAR=$(videodraft avatar create ./media/avatar.png --script \\"$SCRIPT\\" --voice elevenlabs-kPzsL2i3teMYv0FxEYQ6 --ar 9:16 --json | jq -r .avatar_video_id)\\nvideodraft avatar render \\"$AVATAR\\" --resolution 720p # VEED Fabric paid step; confirm cost first (~20 credits/sec)\\n```\\n\\n`avatar script` and `avatar create` (including speech) are bundled/free. In this example only the optional portrait generation and Fabric render spend credits.\\n\\nIf the portrait is low resolution, enhance it before `avatar create`:\\n\\n```bash\\nvideodraft upscale image ./founder-small.jpg --scale 2x --download ./media/founder-upscaled.png\\n```\\n\\nFor a one-off portrait animation without creating a managed avatar record:\\n\\n```bash\\nvideodraft avatar fabric ./founder.jpg \\\\\\n --text \\"Welcome to the weekly product update.\\" \\\\\\n --voice-description \\"warm, confident American presenter\\" \\\\\\n --resolution 720p --download ./media/presenter.mp4\\n```\\n\\nWhen the user already has both the video and replacement speech:\\n\\n```bash\\nvideodraft avatar lipsync ./presenter.mp4 \\\\\\n --audio ./localized-voiceover.mp3 \\\\\\n --sync-mode loop --download ./media/presenter-localized.mp4\\n```\\n\\nEdit an existing video with a dedicated edit model:\\n\\n```bash\\nvideodraft models video --category video_edit\\nvideodraft edit video ./product-demo.mp4 \\\\\\n \\"Turn the room into a warm evening scene while preserving the product and camera motion\\" \\\\\\n --model wan-2.7-ref-edit --ref ./evening-style.jpg \\\\\\n --preserve-audio --download ./media/product-demo-evening.mp4\\n```\\n\\nTransfer motion from a reference clip onto a character image:\\n\\n```bash\\nvideodraft edit motion ./character.png \\\\\\n \\"Apply the dancer\'s movement to this character while preserving identity\\" \\\\\\n --motion-video ./dance-reference.mp4 \\\\\\n --model kling-v3-motion-control --quality pro \\\\\\n --download ./media/character-dance.mp4\\n```\\n\\n## 4. Changelog video in CI\\n\\nIn a GitHub Action with `VIDEODRAFT_API_KEY` set as a secret:\\n\\n```bash\\nNOTES=$(git log --oneline v1.2.0..HEAD | head -20)\\nvideodraft create \\"Weekly product update video. Energetic, 20 seconds. Changes: ${NOTES}\\" --ar 16:9 --json > p.json\\nPROJECT=$(jq -r .project_id p.json)\\nvideodraft shots \\"$PROJECT\\" && videodraft produce \\"$PROJECT\\"\\nvideodraft export \\"$PROJECT\\" --download changelog.mp4 --wait-timeout 30m\\n```\\n\\n## 5. Variations and picking a winner\\n\\n```bash\\nvideodraft generate image \\"logo concept: minimalist fox, geometric\\" --num 4 --download \\"./concepts/{job_id}_{index}.{ext}\\" --json\\n# Show all 4 to the user; regenerate the chosen one at higher res:\\nvideodraft generate image \\"<same prompt>\\" --model nano-banana-pro --resolution 4K\\n```\\n\\n## 6. Reaching tools without a curated command\\n\\n```bash\\nvideodraft tools list --json | jq -r \'.[].name\'\\nvideodraft tools schema attach_media_to_shot --json\\nvideodraft call attach_media_to_shot --args \'{\\"project_id\\":\\"...\\",\\"scene_index\\":0,\\"shot_index\\":1,\\"media_url\\":\\"https://...\\",\\"media_type\\":\\"video\\",\\"duration_seconds\\":6}\'\\n```\\n\\nAnything the VideoDraft MCP exposes \u2014 character studio, product studio, timeline editing \u2014 is reachable this way even before it gets a curated command.\\n\\n## 7. Enhance an existing asset without changing it\\n\\n```bash\\n# Light image cleanup, no enlargement\\nvideodraft upscale image ./poster.png --scale 1x --download ./media/poster-enhanced.png\\n\\n# General image and video enlargement\\nvideodraft upscale image ./frame.png --scale 2x --download ./media/frame-2x.png\\nvideodraft upscale video ./clip.mp4 --scale 2x --download ./media/clip-2x.mp4\\n```\\n\\nUse these when the content is correct and only quality or resolution needs improvement. If the poster text, composition, subject, or motion is wrong, edit or regenerate instead.\\n","references/models.md":"# Choosing models (and predicting cost)\\n\\nAlways consult the live catalog instead of memorizing this page \u2014 models change weekly:\\n\\n```bash\\nvideodraft models image --json # every image model + inputs (aspect ratios, resolutions, max refs)\\nvideodraft models video --json # every video model + inputs + per-second pricing metadata\\nvideodraft models audio --json # standalone audio/media models + pricing inputs\\nvideodraft models voices --json # TTS voices\\nvideodraft models styles --json # visual style presets\\n```\\n\\n## Task-based model selection\\n\\nHonor an explicitly named model when it supports the request. Otherwise choose from the task\'s inputs, duration, audio, quality, speed, and cost. Pass the chosen model explicitly instead of relying on a blind platform fallback.\\n\\n### Images\\n\\n| Need | Choose | Why |\\n| -------------------------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------- |\\n| Most generation, editing, character consistency, or reference work | `nano-banana-2` | Best general default; 1K/2K/4K and up to 14 reference images |\\n| Highest-quality complex generation or reasoning | `nano-banana-pro` | Premium Nano Banana quality and reasoning |\\n| Fast, inexpensive drafts and iteration | `nano-banana-2-lite` | Fastest/cheapest Nano Banana option; 1K only, up to 14 references |\\n| Posters, title cards, signs, logos, or any image with important readable text | `gpt-image-2` | Strong text rendering; up to 16 image inputs and 1K/2K/4K output |\\n| Complex multi-image composition, precise editing, or a strong alternate interpretation | `gpt-image-2` | Strong non-Nano alternative with multi-image input |\\n\\nUse `--num 1..4` for variations of one prompt in a single call. Never loop separate paid calls for variations that fit in one request.\\n\\n### Videos\\n\\n| Need | Choose | Important limits |\\n| ---------------------------------------------------------------------------------------------------------- | ------------------- | --------------------------------------------------------------------------------------------------- |\\n| Most text, first-frame, image-reference, or source-video-edit requests up to 10s | `gemini-omni-flash` | 720p, 3-10s or auto, audio always on, up to 10 total image inputs, one source video |\\n| Video/audio references, mixed reference media, broad aspect ratios, frame-mode first+last frame, or 11-15s | `seedance-2` | 4-15s or auto; up to 9 image, 3 video, and 3 audio refs; audio toggle; Mini/Fast are 480p/720p only |\\n| Fast polished 3-15s video with first frame, multi-prompt, and native audio | `kling-v3-turbo` | Audio always on; Pro default; no end frame or reference-media mode |\\n| Cinematic 3-15s with image references, first+last frame, multi-prompt, audio control, or 4K | `kling-o3` | Up to 7 image refs; Standard/Pro/4K; audio toggle |\\n| Kling 3-15s with first+last frame, multi-prompt, optional audio, or 4K, without reference-image mode | `kling-3.0` | Standard/Pro/4K; audio toggle |\\n| User explicitly requests Veo, or the selected workflow specifically needs Veo | `google-veo3.1` | Good fallback, but not the preferred general model |\\n\\nRouting rules:\\n\\n- Around 11-15 seconds with native audio: use Kling or Seedance, not Gemini.\\n- One existing source video that should be edited, with an output up to 10 seconds and no additional media references to preserve: use Gemini Omni Flash.\\n- Video or audio supplied as creative reference: use Seedance 2.0.\\n- A video plus any image/audio references that must all be preserved: use Seedance 2.0. Do not promise that Gemini will preserve mixed source media; its Fal BYOK edit mode accepts only the source video and prompt.\\n- First and last frame control: use Seedance, Kling O3, or Kling 3.0. Gemini supports a first frame but not a last frame.\\n- Seedance reference mode and first-plus-last-frame mode are separate. Do not promise reference video/audio plus a last frame in one generation.\\n- Multi-prompt sequencing: use Kling 3.0 Turbo, Kling O3, or Kling 3.0.\\n- Seedance quality: `mini` for the lowest cost, `fast` for speed, `standard` for maximum quality and for 1080p/4K.\\n\\n### Video edit and motion-control categories\\n\\nUse `videodraft models video --category video_edit` for existing-video transforms and `--category motion_control` for motion transfer.\\n\\n| Need | Command/model | Important limits |\\n| ------------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\\n| Simple prompt edit of one video | `videodraft edit video <video> \\"...\\" --model grok-imagine-video-edit` | No image refs; source truncated to 8s; auto/480p/720p |\\n| Edit with one style/reference image | `--model wan-2.7-ref-edit --ref <image>` | One image ref; 2-10s or match source |\\n| Edit with several image references | `--model happy-horse-video-edit --ref ...` | Up to 5 refs; 720p/1080p; source capped at 15s |\\n| Controlled Kling edit | `--model kling-o3-video-ref-edit --ref ...` | Up to 4 refs; Standard/Pro; source clamped to 3-10s |\\n| Transfer reference motion to an image | `videodraft edit motion <image> \\"...\\" --motion-video <video>` | Kling V3 default; image orientation caps motion at 10s, video orientation at 30s |\\n\\nIf the user explicitly names one of these models, preserve it. The CLI uploads local source videos and reference images automatically. Editing returns an async job and waits by default.\\n\\nKling O3 and Wan 2.7 Ref/Edit are dual-mode cards. `videodraft edit video` uses edit mode. `videodraft generate video --model kling-o3-video-ref-edit` requires exactly one `--ref-video` and generates a new reference-guided clip. `--model wan-2.7-ref-edit` generates a new clip from one or more `--ref`/`--ref-video` inputs.\\n\\n### Reference-first video workflow\\n\\n- Prefer a start frame or reference image whenever a specific character, product, location, style, composition, or brand identity must stay recognizable.\\n- If the user gives a reference, pass it. Never silently replace it with a text description.\\n- If no reference exists and continuity matters, generate a still first with the user\'s explicitly requested compatible image model, otherwise use Nano Banana 2. Wait for the image URL, then animate it with the selected video model. Confirm the combined image plus video cost before starting.\\n- For multi-shot scenes, generate shot images with `videodraft shots <project_id> --model <selected-image-model> --grid`. Preserve an explicitly requested compatible image model; otherwise use `nano-banana-2`. The grid establishes the scene and characters together, then decodes into individual shot images.\\n- Animate the decoded shot images as per-shot start frames or references. Do not independently text-generate each video clip when the shots need to match.\\n- Pure text-to-video remains appropriate for generic one-off footage where no subject, composition, or continuity needs to be preserved.\\n\\n### Audio\\n\\n- **Seed Audio 1.0**: use `videodraft generate audio` for open-ended speech, sound, music, or prompt-driven audio editing. It accepts up to three audio references or one image. Address audio references as `@Audio1`, `@Audio2`, and `@Audio3`. Preset and custom cloned voice IDs are supported. Output is up to 120 seconds. There is no requested-duration input. The CLI automatically retries transient responses with one idempotency key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- **Voiceover/TTS**: prefer ElevenLabs. Brittney is the platform default voice; under ElevenLabs BYOK, use a compatible voice from the user\'s account. Honor another supported voice/provider when the user explicitly selects it.\\n- **Dialogue, voice changing, and dubbing**: ElevenLabs only.\\n- **Sound effects**: ElevenLabs Sound Effects only.\\n- **Music**: use `lyria-3-clip-preview` for a short instrumental/background score, `lyria-3-pro-preview` for a longer or higher-quality instrumental score, and `elevenlabs-music` when vocals/lyrics or a specified 10-120 second length matter.\\n- Voice Changer and Dubbing require the source media duration and currently accept source media up to 300 seconds.\\n\\n### Avatar / talking head\\n\\nChoose the dedicated path from the media the user already has:\\n\\n| Starting media | Command | Use |\\n| ----------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------- |\\n| Portrait + script, reusable avatar record | `videodraft avatar create <portrait> --script \\"...\\"` then `avatar render` | Managed avatar flow with bundled speech preparation |\\n| Portrait + text | `videodraft avatar fabric <portrait> --text \\"...\\"` | One-off direct VEED Fabric text mode |\\n| Portrait + existing audio | `videodraft avatar fabric <portrait> --audio <audio>` | One-off direct VEED Fabric audio lip sync |\\n| Existing video + existing audio | `videodraft avatar lipsync <video> --audio <audio>` | Sync Labs Lipsync 2 |\\n\\nThe managed renderer is VEED Fabric Fast (`veed/fabric-1.0/fast`). Direct Fabric and Sync Labs are paid AI Studio generations and return async job IDs.\\n\\n1. Obtain the avatar image. Prefer the user\'s supplied portrait or an existing character. If none exists, use the user\'s explicitly requested compatible image model, otherwise generate a front-facing head-and-shoulders portrait with `nano-banana-2`, direct eye contact, a natural expression, and a clean background. Match the intended video aspect ratio when practical.\\n2. If the portrait is visibly soft or too small, run Topaz image enhancement/upscaling before animation.\\n3. Generate a script only if needed: `videodraft avatar script \\"<idea>\\"`.\\n4. Create the avatar record and speech: `videodraft avatar create <portrait-url-or-file> --script \\"...\\" --voice <id> --ar 9:16`. Prefer ElevenLabs when unspecified, but honor another explicitly selected supported voice/provider.\\n5. Render with VEED Fabric: `videodraft avatar render <avatar_video_id> --resolution 720p`.\\n\\nThe portrait is passed as the avatar\'s character image, not as a generic video\'s start frame. Prefer rendering directly at 720p. Use 480p only when the user prioritizes lower cost. Avatar script generation and `avatar create` (including speech) are bundled/free. Confirm the Fabric render cost, plus portrait generation or upscaling when needed.\\n\\nDirect Fabric text/audio and Sync Labs do not use the managed avatar record. The CLI uploads local portrait, video, and audio files automatically. `avatar fabric --speed fast` applies only to audio mode. Sync costs 5 credits per verified audio second; under Fal BYOK, `sync_mode` remains available but `temperature` and `active_speaker` are ignored by the provider.\\n\\n### Upscaling / enhancement\\n\\n- **Images**: Topaz via `videodraft upscale image <url-or-file> --scale 1x|2x|4x`. Use 1x for light enhancement without enlargement, 2x as the general default, and 4x only when the source quality and target size justify it. The result is synchronous.\\n- **Videos**: Topaz via `videodraft upscale video <url-or-file> --scale 2x`. Use 2x by default. The job is asynchronous; the CLI waits by default, while MCP callers poll `check_generation_status`. MCP video input must be VideoDraft-hosted, so upload local or external sources first.\\n- Use upscaling to preserve the image/video while improving detail, resolution, or cleanup. It cannot fix the wrong subject, misspelled text, bad framing, unwanted objects, broken continuity, or incorrect motion. Use an edit or regeneration for those problems.\\n- For a new Fabric avatar, render directly at 720p instead of rendering at 480p and then upscaling. Upscale the source portrait first only when the portrait itself is low quality.\\n\\n## Capability gotchas\\n\\n- Each model\'s `inputs` block is authoritative: supported `aspect_ratios`, `resolutions`, `quality_options`, `start_frame`/`end_frame`, `max_reference_images/videos/audio`, `multi_prompt`, `audio_toggle`. Passing an unsupported input fails with a clear error \u2014 check first, don\'t trial-and-error paid calls.\\n- Most video models support only 16:9 / 9:16 / 1:1. A 3:4 request hard-fails on most.\\n- `--seed` reproduces a specific output on models that support it (e.g. Flux, Ideogram V4); everything else ignores it. You do not need a seed for variation \u2014 `--num` already varies.\\n- `--rendering-speed` applies to Ideogram (V3: `Default`/`Turbo`/`Quality`; V4: `Turbo`/`Balanced`/`Quality`) and affects image cost \u2014 pass it to `videodraft costs ... --rendering-speed <tier>` for an accurate estimate. Always trust `videodraft models image --json` over this list; new models and tiers appear there the moment the platform ships them, with no CLI update.\\n- `seedream-v5-pro` supports unified text-to-image and reference-image editing with up to 10 image references. Use `--resolution 1K` for 7 credits/image or `--resolution 2K` for 14 credits/image.\\n- Reference inputs: `--ref <img>` (images), `--ref-video <v>` (Gemini Omni Flash, Seedance 2, Wan 2.7), `--ref-audio <a>` (Seedance 2). The CLI uploads local files for all of these, so you can pass a path or a URL. `--segment \\"<prompt>:<seconds>\\"` (repeatable) drives multi-prompt models (Kling 3.0 / 3.0 Turbo / O3); total 3-15s. `generate image --video-ref` is the nano-banana-2 video reference.\\n- The top-level prompt is OPTIONAL for `generate video` with multi-prompt models and for Kling 3.0 Turbo (`--model kling-v3-turbo`) image-to-video \u2014 a `--segment`-only or `--start-image`-only call is valid. Every other model still needs a prompt; the server enforces per-model rules.\\n- AI Production: `videodraft produce <project> --mode full_video` generates one Seedance 2 video per scene; poll with `videodraft generations`, then `videodraft finalize <project>` swaps them into the timeline before `export`. If the user explicitly requests another compatible video model, do not use this fixed Seedance path. Generate the project shots manually with the requested model and attach them to the timeline.\\n\\n## Cost model\\n\\n- Images: per image (\xD7 `--num`). Matrix-priced models (GPT-Image, Nano Banana Pro, Seedream v5 Pro) vary by resolution/quality.\\n- Video: usually credits/second \xD7 duration; rate depends on model + resolution + quality + native audio on/off.\\n- Shot-image batches: one image per shot (+1 grid image per scene in `--grid` mode) \u2014 the largest single spend in the pipeline.\\n- VEED Fabric avatar renders: ~10 credits/sec at 480p, ~20/sec at 720p. Avatar creation and its speech are bundled/free; only optional portrait generation/upscaling adds cost before the render.\\n- Direct VEED Fabric: text or normal audio is 8 credits/sec at 480p and 15/sec at 720p; fast audio is 10/sec at 480p and 20/sec at 720p.\\n- Sync Labs Lipsync 2: 5 credits per verified audio second.\\n- Voiceover TTS: 10 credits per 1000 characters for standard voices, 30 per 1000 for cloned `custom-*` voices (min 1, pro-rated); applies to standalone voiceovers AND per-scene narration during `produce`. Silent tracks are free. Voice cloning itself is a flat 150 credits per clone.\\n- Lyria music: flat per track, 10 credits (clip) / 15 credits (pro).\\n- Seed Audio 1.0: 19 credits per actual output minute, prorated and rounded up to a whole credit. VideoDraft reserves the 120-second maximum of 38 credits and refunds the unused portion after generation. Fal BYOK is free.\\n- ElevenLabs audio: sound effects are per second, dialogue is per character, music/voice-changer/dubbing are per started minute. Voice changer and dubbing reject source media above 300s in the current synchronous flow.\\n- Upscales: priced by scale and source size.\\n\\nQuote before spending:\\n\\n```bash\\nvideodraft costs gemini-omni-flash --type video --duration 8 --resolution 720p --audio\\nvideodraft costs seedance-2 --type video --duration 15 --resolution 720p --quality standard --audio\\nvideodraft costs elevenlabs-dubbing --type audio --duration 60\\nvideodraft costs seed-audio-1.0 --type audio --duration 60 # scenario only; model controls actual length\\nvideodraft costs elevenlabs-dialogue --type audio --chars 350\\nvideodraft costs voiceover --type audio --chars 800 # TTS: 10 cr / 1000 chars\\nvideodraft generate video \\"...\\" --model gemini-omni-flash --estimate # same quote, inline\\n```\\n","references/pipeline.md":"# VideoDraft pipeline reference\\n\\nEverything here works through the CLI (`videodraft <command>` / `videodraft call <tool>`) or the MCP connector (tool names in backticks). One backend; pick the surface you have.\\n\\nUse direct asset tools for standalone images, clips, audio, upscales, and descriptions. Use a project for any multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export even when the request does not use the word \\"project.\\" Script-only uses a script-stage project and stops at the script.\\n\\n## Stages and their tools\\n\\n| Stage | CLI | Underlying tool |\\n| --------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------ |\\n| Idea \u2192 full storyboard project | `videodraft create \\"<idea>\\"` | `generate_storyboard_from_idea` |\\n| Idea \u2192 script only (stop there) | `videodraft create \\"<idea>\\" --script-only` | `generate_script_from_idea` |\\n| Footage IS the video | `videodraft call generate_storyboard_from_media` | `generate_storyboard_from_media` |\\n| Batch shot images | `videodraft shots <project>` | `generate_shot_images` |\\n| One shot image | `videodraft generate image --project <id> --scene N --shot M` | `generate_image` |\\n| Produce (voiceover, captions, timeline) | `videodraft produce <project>` | `produce_project` |\\n| Per-shot motion prompts | `videodraft video-prompts <project>` | `generate_video_prompts` |\\n| Motion clip for a shot | `videodraft generate video --project <id>` | `generate_video` |\\n| Attach a finished clip to the timeline | `videodraft attach <project> --scene N --shot M --media <url> --type video` | `attach_media_to_shot` |\\n| Background music | `videodraft generate music --attach <project>` | `generate_music` / `set_background_music` |\\n| General or reference-driven audio | `videodraft generate audio \\"...\\"` | `generate_audio` |\\n| Sound effect | `videodraft generate sound-effect \\"...\\"` | `generate_sound_effect` |\\n| Dialogue audio | `videodraft generate dialogue --line \\"voice:text\\"` | `generate_dialogue` |\\n| Voice changer | `videodraft generate voice-changer <audio>` | `change_voice` |\\n| Dubbing | `videodraft generate dub <audio_or_video>` | `dub_media` |\\n| Scene voiceover | `videodraft generate voiceover --project <id> --scene N` | `generate_voiceover` |\\n| Avatar script | `videodraft avatar script \\"<idea>\\"` | `generate_avatar_script` |\\n| Avatar + speech | `videodraft avatar create <portrait> --script \\"...\\"` | `create_avatar_video` |\\n| Talking-head render | `videodraft avatar render <avatar_video_id>` | `render_avatar_video` + `get_avatar_video` |\\n| Direct portrait + text/audio | `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>` | `generate_veed_fabric_video` |\\n| Existing video + replacement audio | `videodraft avatar lipsync <video> --audio <file>` | `generate_sync_lipsync_video` |\\n| Existing-video AI edit | `videodraft edit video <video> \\"<change>\\" --model <video-edit-model>` | `edit_video` |\\n| Motion transfer | `videodraft edit motion <image> \\"<direction>\\" --motion-video <video>` | `generate_motion_control_video` |\\n| Image enhancement/upscale | `videodraft upscale image <image>` | `upscale_image` |\\n| Video enhancement/upscale | `videodraft upscale video <video>` | `upscale_video` |\\n| Final MP4 | `videodraft export <project>` | `export_video` + `check_export_status` |\\n\\n## Rules that prevent broken results\\n\\n- **The storyboard is generated FROM the script**, never from the raw idea. `videodraft create` runs the whole chain correctly. Don\'t call `generate_storyboard_scenes` with a raw idea as the \\"script\\".\\n- **Visual consistency**: never generate a storyboard shot in isolation. Shot prompts carry `[[asset:Name]]` / `[[shot:X-Y]]` tags that `generate_shot_images` resolves against the project\'s visual assets and prior shots. When generating a single shot whose prompt has no tags, pass `--ref` images yourself (the project\'s visual assets and/or the previous shot\'s image; `projects get` exposes both). For scenes with multiple shots or recurring characters, prefer `videodraft shots <project> --model <selected-image-model> --grid`: preserve an explicitly requested compatible image model, otherwise use `nano-banana-2`. It creates one coherent scene grid, then decodes it into individual shot images.\\n- **Reference-first video**: when identity, styling, or composition matters, do not generate each motion clip from text alone. Generate or select the shot still first, then pass the decoded shot image as `--start-image` or `--ref` to the selected video model. AI Production already composes scene grids and sends them to Seedance as references. If the user explicitly requests another compatible video model, bypass fixed Seedance full-video mode and generate the per-shot clips with the requested model, using the individual decoded shot images as anchors.\\n- **Hold off generating shot images while the user is still iterating** on storyboard structure.\\n- **produce \u2192 export ordering**: `export` requires a produced project where every production scene has timeline media. If `produce` returns `generating_shot_images`, poll the job ids it returns, then re-run produce.\\n- **Generated motion clips do not auto-attach**: after `generate video` completes, attach the clip with `attach_media_to_shot` (`media_type:\\"video\\"`, include `duration_seconds`) \u2014 it replaces the production timeline clip while keeping the storyboard still.\\n- **Talking heads use dedicated avatar tools**: do not use `generate video`. Use managed `avatar create` and `avatar render` for reusable avatars, direct `avatar fabric` for a portrait plus text/audio, and `avatar lipsync` for an existing video plus replacement audio. Reuse a supplied person image or generate a clear front-facing portrait with the explicitly requested compatible image model, otherwise Nano Banana 2. Managed avatar creation and speech are bundled/free; direct Fabric, Sync, and render are paid.\\n- **Existing-video edits use their own category**: call `edit_video` or `videodraft edit video` with a `video_edit` model when transforming the source itself. Kling O3 and Wan 2.7 Ref/Edit are dual-mode: their reference-generation modes may use generic `generate_video` to create a new guided clip. Motion transfer similarly uses `generate_motion_control_video` or `videodraft edit motion` with a `motion_control` model.\\n- **Upscaling preserves rather than redesigns**: use Topaz when resolution, detail, or cleanup is the problem. Regenerate or edit when the subject, text, framing, continuity, or motion is wrong. Upscale a low-quality avatar portrait before Fabric; do not render a new avatar at 480p just to upscale the result.\\n- **Timeouts on the one-shot create**: if `create` times out at the transport layer, the project was still created server-side \u2014 `videodraft projects list`, take the most recent, and resume with its id. Don\'t start a duplicate.\\n\\n## User-attached media: classify roles first\\n\\nFor EACH attached file decide:\\n\\n- **visual_asset** \u2014 recurring reference (character / product / location / style). Upload, then pass in `visual_assets` of `generate_storyboard_from_idea` (via `videodraft call`), or add to an existing project with `add_visual_assets`. Type must be one of `character | object | location | style | custom` with a short name + concrete description.\\n- **shot** \u2014 the media IS footage for the video. Whole video = footage \u2192 `generate_storyboard_from_media`. Idea + footage \u2192 `generate_storyboard_from_idea` with `shot_media`. Existing storyboard \u2192 `attach_media_to_shots`.\\n- **reference** \u2014 inspiration only \u2192 fold a description into the idea/instructions; don\'t place it as a shot or asset.\\n\\nAmbiguous (e.g. a person holding a product)? Ask the user.\\n\\nUploads persist in the media library \u2014 recall later with `videodraft media list`.\\n\\n## Editing project data safely\\n\\n1. `videodraft call get_project_schema` \u2014 read the structure once per session.\\n2. `videodraft projects get <id> --raw` \u2014 the exact editable blob.\\n3. Modify; then `videodraft call update_project --stdin` with `{\\"project_id\\": \\"...\\", \\"data\\": {...}}`.\\n - Objects deep-merge key-by-key; **arrays replace wholesale** \u2014 send the complete array you\'re changing (e.g. all of `storyboard.scenes`).\\n - Scene shot arrays (`image_prompt` / `shot_types` / `shot_actions` / `search_prompt` / `preview_media`) are auto-aligned; fix-ups come back as warnings.\\n4. Snapshot before risky edits: `videodraft checkpoint create <id> --name \\"before re-script\\"`. Restore with `videodraft checkpoint restore <id> <version>`.\\n\\n## AI Studio sessions (standalone generations)\\n\\nProject generations group automatically. For standalone work in a long conversation, create one session up front and reuse it:\\n\\n```bash\\nSESSION=$(videodraft call create_ai_studio_session --arg name=\\"Fox brand explorations\\" --json | jq -r .session_id)\\nvideodraft generate image \\"...\\" --session \\"$SESSION\\"\\n```\\n"}') {
3875
+ return JSON.parse('{"SKILL.md":"---\\nname: videodraft\\ndescription: Create AI videos, images, Seed Audio, voiceovers, music, sound effects, dialogue, dubbing, storyboards, avatar videos, media upscales and product/ad videos with VideoDraft. Use when the user mentions VideoDraft, or asks to generate/make a video, video ad, explainer, storyboard, talking-head/avatar video, AI image, prompt-driven or reference-driven audio, voiceover/TTS, background music, sound effects, dialogue audio, voice changing, dubbing, or image/video enhancement and upscaling, including batch/programmatic video generation in scripts or CI. Works via the `videodraft` CLI (preferred in terminals) or the VideoDraft MCP connector.\\n---\\n\\n# VideoDraft\\n\\nVideoDraft is an AI video creation platform where asset generation is the priority lane:\\n\\n- **Asset generation**: standalone images, video clips, Seed Audio, voiceovers, music, sound effects, dialogue, voice-changed audio, dubbed media, upscales, and image descriptions. This is the fastest and most important lane. Treat these as complete deliverables when the user asks for assets.\\n- **Asset I/O**: upload local files, download outputs, auto-upload local references, and save generated media where the user can see it.\\n- **Project production**: idea \u2192 script \u2192 storyboard (scenes + shot images) \u2192 project data \u2192 production timeline \u2192 exported MP4. Use it for a multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export, even when the user does not say \\"project.\\" A script-only request also creates a script-stage project but stops at the script.\\n\\n## How to connect\\n\\nTwo equivalent surfaces (same backend, same credits, same projects):\\n\\n1. **CLI** (preferred when you have a shell): run `videodraft` if it\'s on PATH; otherwise `npx -y videodraft@latest` runs it with no install (needs Node \u226520; the `-y` skips npx\'s install prompt so it runs non-interactively; the package is fetched on first use and cached). For heavy use, `npm install -g videodraft`. If there\'s no Node/shell here but the MCP connector below is available, use that instead; if neither works, tell the user how to install (https://videodraft.ai/cli).\\n - Auth \u2014 pick by context, don\'t guess:\\n \u2022 INTERACTIVE (a human is in the session, e.g. Claude Code / Codex): on exit code 3 (\\"not authenticated\\"), tell the user to run `videodraft login` in their terminal \u2014 it opens their browser for a one-click VideoDraft sign-in (OAuth), no key to copy. Wait for them to confirm it succeeded, then retry the command. This is the preferred path when the user is present.\\n \u2022 HEADLESS / CI (no browser): set `VIDEODRAFT_API_KEY=vd_mcp_...` (a token the user mints at https://app.videodraft.ai/mcp-keys).\\n \u2022 SECURITY: never ask the user to paste a `vd_mcp_...` token into the chat \u2014 use browser `login` or the env var so the token never lands in the transcript.\\n - Every command accepts `--json` (parse this, don\'t scrape text). Exit codes: 0 ok, 1 error, 2 usage, 3 auth (see Auth above), 4 insufficient credits (\u2192 tell the user, don\'t retry).\\n - Tool discovery: start with `videodraft tools list` for the grouped catalog, then narrow with `videodraft tools list --lane assets`, `--lane asset_io`, `--lane project_data`, or `--lane production`.\\n - Asset lane: `videodraft generate ...`, `videodraft edit video|motion`, `videodraft avatar ...`, `videodraft upscale ...`, `videodraft upload`, and `videodraft download`.\\n - Full API access: `videodraft tools schema <name>`, `videodraft call <tool> --args \'<json>\'`.\\n2. **MCP connector**: if VideoDraft MCP tools (e.g. `generate_storyboard_from_idea`) are available, call them directly \u2014 the CLI\'s curated commands map 1:1 onto these tools.\\n\\n## First decision: asset or project?\\n\\n- **One standalone asset** (image, clip, voiceover, music track, sound effect, dialogue track, voice-changed file, dubbed media file, upscale, or description): generate it directly. Do NOT create a project.\\n - `videodraft generate image \\"a red fox in snow, cinematic\\" --ar 16:9 --download ./out/`\\n - `videodraft generate video \\"slow dolly over a misty lake\\" --model gemini-omni-flash --duration 6 --download ./out/`\\n- **A small set of related assets**: still stay in the asset lane. Use an AI Studio session if you need to group related generations. Switch to a project only when the deliverable matches the project criteria below or the user asks to attach the assets to one.\\n- **A multi-scene video / ad / explainer, storyboard, timeline, or final exported video**: create a project so the work stays organized, editable in the web app, and exportable.\\n - `videodraft create \\"30s launch video for our espresso machine\\" --ar 9:16`\\n- **Just a script** (no video asked for): `videodraft create \\"...\\" --script-only`. Stop at the script \u2014 do not build a storyboard the user didn\'t ask for.\\n- **Iterating on existing work**: find it first (`videodraft projects list`) and reuse that project. Never create a new project to change an existing one.\\n\\n## Choose the model from the task\\n\\nIf the user names a model, use it when compatible. If it cannot handle the request, explain why and recommend alternatives instead of silently switching. Otherwise inspect the inputs, duration, audio, quality, speed, and cost, check the live catalog, and pass an explicit model.\\n\\n**Images:**\\n\\n- `nano-banana-2`: general default, editing, consistency, and references.\\n- `nano-banana-pro`: maximum quality. `nano-banana-2-lite`: fast, inexpensive drafts.\\n- `gpt-image-2`: posters, logos, signs, title cards, readable text, or precise composition/editing.\\n\\n**Videos:**\\n\\n- `gemini-omni-flash`: general default up to 10s, first frame/image references, or editing one source video without extra media references. Fixed 720p with audio.\\n- `seedance-2`: 11-15s, video/audio/mixed references, wider ratios, selectable audio, or first/last frames. Use `mini` for cost, `fast` for speed, `standard` for quality or 1080p/4K.\\n- `kling-v3-turbo`: fast polished 3-15s with first frame, multi-prompt, and audio. `kling-o3`: image references, first/last frames, multi-prompt, audio control, or 4K. `kling-3.0`: similar without reference-image mode.\\n- Existing-video edits use `videodraft edit video`, not generic generation. Choose from the `video_edit` catalog category: Grok for simple prompt edits, Wan 2.7 for one style reference or source-matching duration, Happy Horse for up to 5 references, and Kling O3 for controlled reference-image edits.\\n- Kling O3 and Wan 2.7 Ref/Edit also have reference-generation modes. Use `videodraft generate video --model <ref-edit-id>` with `--ref-video`/`--ref` to generate a new guided clip; use `videodraft edit video` when changing the source itself.\\n- Motion transfer uses `videodraft edit motion` with Kling V3 by default, or Kling 2.6 when explicitly requested or lower cost matters. It requires a subject image and a motion-reference video.\\n- Use Veo 3.1 when explicitly requested or as a fallback.\\n\\n**Audio and utilities:**\\n\\n- Use Seed Audio 1.0 for open-ended text-to-audio, speech/music/sound synthesis, voice conditioning, or prompt-driven editing with up to three audio references or one image. Use `videodraft generate audio`. Reference clips are `@Audio1`, `@Audio2`, and `@Audio3` in array order. There is no duration input. Output is up to two minutes and settles at 19 credits per actual minute, with up to 38 credits reserved during generation. The CLI automatically retries transient responses with one operation key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- Prefer ElevenLabs for voiceover, dialogue, voice changing, dubbing, and sound effects. Honor an explicitly selected supported TTS voice/provider. Use Lyria for instrumental music and ElevenLabs Music for vocals, lyrics, or exact timing.\\n- Talking head/presenter: choose by source. Use managed `avatar create` then `avatar render` when the user wants a reusable avatar record and bundled speech. Use `avatar fabric` for a one-off portrait plus text or existing audio. Use `avatar lipsync` when both the source video and replacement audio already exist.\\n- Enhancement: use Topaz image/video upscaling only when the content is already correct. Use image 1x for cleanup, 2x by default, 4x when justified; use video 2x by default. Edit or regenerate creative errors.\\n\\nSee [references/models.md](references/models.md) for the detailed routing table and exact capability limits.\\n\\n## Prefer references when continuity matters\\n\\nPure text-to-image or text-to-video is fine for a generic one-off asset. When a specific character, product, location, style, composition, or brand identity must survive generation, use references instead of hoping the prompt recreates it.\\n\\n- If the user supplies reference media, preserve and pass it. Never reduce the request to text alone.\\n- When continuity matters, generate/select a strong still first with the selected image model (`nano-banana-2` by default), wait for its URL, then animate it as a start frame/reference. Confirm the combined image and video cost.\\n- For multiple shots, use `videodraft shots <project_id> --model <selected-image-model> --grid`, then animate the decoded shots. Preserve explicit models. A requested non-Seedance video model must use manual per-shot generation instead of Seedance full-video mode.\\n\\n## Cost and credits\\n\\nDo not call `videodraft credits` before routine generations. Paid endpoints validate and deduct atomically; if the balance is insufficient, the request is rejected before the provider job starts (CLI exit code 4). Check the balance only when the user asks, gives a credit budget, or a large workflow needs budget planning.\\n\\nFor expensive work, estimate with `--estimate` or `videodraft costs`, state the selected model/settings/cost, and get a go-ahead. This matters most for shot-image batches, long or high-resolution video, AI Production, and paid audio batches. Honor the user\'s confirmation preference for the session.\\n\\n`videodraft models image|video` lists the live image and video catalogs with supported inputs. Video entries are grouped as `generation`, `video_edit`, `motion_control`, `avatar_lipsync`, and `upscale`, and each reports the exact tool. Use `videodraft models video --category video_edit` to narrow the list. `videodraft models audio` lists Seed Audio, Google Lyria, and ElevenLabs audio/media tools, while `videodraft models voices` lists TTS voices. Consult them instead of guessing capabilities.\\n\\n## Async jobs\\n\\nImage/video generation is asynchronous: commands submit a job and **wait by default**, printing output URLs (and saving files with `--download`). Large downloaded images also get a downscaled copy in `previews/` next to them (the `preview` field / \\"inspect via preview\\" line in the output) \u2014 **look at the preview, deliver the original**; viewing full-resolution images bloats the chat permanently. In scripts/CI prefer explicit control:\\n\\n```bash\\nJOB=$(videodraft generate image \\"...\\" --no-wait --json | jq -r .job_id)\\nvideodraft wait \\"$JOB\\" --download \\"./outputs/{job_id}_{index}.{ext}\\" --json\\n```\\n\\nFor MANY jobs: submit each with `--no-wait`, collect ALL with one command \u2014 `videodraft wait <id1> <id2> ...` polls every job from one process with one batched request per tick. Do NOT spawn parallel `wait`/`generate --wait` processes for a batch.\\n\\nIf a wait times out, the job is still running server-side \u2014 `videodraft status <job_id>` later. Never re-submit just because a wait timed out (that double-spends credits).\\n\\n## Local files and reference images\\n\\nReference inputs must be public URLs. The CLI uploads local files automatically wherever a URL is expected (`--ref photo.jpg`, `--start-image frame.png`), or explicitly:\\n\\n```bash\\nURL=$(videodraft upload ./product.png --json | jq -r .url)\\n```\\n\\nNever silently drop a reference you couldn\'t upload \u2014 stop and tell the user. Never upload a user\'s file to a third-party host.\\n\\nWhen the user attaches media, classify each item before acting: a recurring **visual asset** (character/product/location/style), actual **footage to place as shots**, or **inspiration only**. See [references/pipeline.md](references/pipeline.md) for how each role flows into a project.\\n\\n## Showing media to the user\\n\\nGenerated media is **not** displayed in the chat automatically \u2014 you decide what to show. To preview an asset inline, save it locally (use `--download` so it lands under `media/`) and reference its **local path** as a Markdown link with a **leading `./`**:\\n\\n```\\n[ferrari shot](./media/ferrari_01.png) \u2190 image card\\n[the clip](./media/clip.mp4) \u2190 video player\\n[voiceover](./media/vo.mp3) \u2190 audio player\\n```\\n\\nPut the Markdown link **in your message text** \u2014 video and audio embed exactly like images. Do **not** use `SendUserFile` (or other file-send tools) to display media: that renders inside a collapsible tool card and gets buried in the tool list. The Markdown link in your prose is what produces the inline card.\\n\\nUse the path you saved to: a **workspace-relative** path (`./media/clip.mp4`, or `./<any-folder>/clip.mp4` \u2014 any folder in the workspace works), or the **absolute** path for a file outside the workspace (e.g. `/Users/you/Desktop/clip.mp4` or another workspace\'s path). Both render. Show the finished results worth showing (and only those \u2014 not every intermediate job). A bare CDN URL or a JSON dump of output URLs does **not** render; the local-path Markdown link is what produces an inline card.\\n\\n## The full pipeline (idea \u2192 MP4)\\n\\n```bash\\nvideodraft create \\"<idea>\\" --ar 9:16 # project: script \u2192 visual assets \u2192 storyboard\\nvideodraft shots <project_id> --grid --estimate # cost preview, confirm with user\\nvideodraft shots <project_id> --grid # batch shot images (waits, writes onto shot cards)\\nvideodraft produce <project_id> # voiceovers + captions + production timeline\\nvideodraft export <project_id> --download final.mp4\\n```\\n\\nOptional between produce and export: per-shot motion clips (`videodraft generate video ... --project <id>` then place it with `videodraft attach <project> --scene N --shot M --media <url|file> --type video --duration <s>`), music (`videodraft generate music \\"...\\" --attach <project_id>`), and standalone audio assets (`generate audio`, `generate sound-effect`, `generate dialogue`, `generate voice-changer`, `generate dub`). Details, per-step tools and editing rules: [references/pipeline.md](references/pipeline.md).\\n\\nAvatar/talking-head videos use dedicated commands. For a reusable managed avatar, obtain or generate a clear portrait \u2192 `videodraft avatar script` when needed \u2192 `videodraft avatar create` \u2192 `videodraft avatar render --resolution 720p`. For a one-off portrait, use `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>`. For an existing video plus replacement audio, use `videodraft avatar lipsync <video> --audio <file>`. Managed script/creation is bundled/free; direct Fabric, Sync, the managed Fabric render, and optional portrait generation/upscaling are paid. Confirm expensive steps first.\\n\\n## Working with project data\\n\\nA project is one JSON blob (script, storyboard scenes, shot cards, visual assets, production timeline). To inspect: `videodraft projects get <id>`. To edit: fetch `--raw`, modify, then `videodraft call update_project` \u2014 objects deep-merge, **arrays replace wholesale** (send the complete `storyboard.scenes` array to change one scene). Snapshot first with `videodraft checkpoint create <id>` before risky edits. Schema reference: `videodraft call get_project_schema`.\\n\\n## More\\n\\n- [references/pipeline.md](references/pipeline.md) \u2014 project data model, step-by-step tools, attaching media, editing safely\\n- [references/models.md](references/models.md) \u2014 choosing image/video models, pricing patterns, voices and styles\\n- [references/examples.md](references/examples.md) \u2014 recipes: batch product videos from a CSV, talking-head from a script, changelog video in CI\\n","references/examples.md":"# Recipes\\n\\nWorking patterns for common asks. All assume auth (`videodraft login` once, or `VIDEODRAFT_API_KEY` in the environment) and use `--json` for parsing.\\n\\n## 1. Batch product videos from a CSV\\n\\nOne 9:16 product clip per row of `products.csv` (`name,image_url,tagline`):\\n\\n```bash\\n#!/usr/bin/env bash\\nset -euo pipefail\\nmkdir -p outputs\\n\\nwhile IFS=, read -r name image tagline; do\\n job=$(videodraft generate video \\\\\\n \\"Premium product shot of ${name}: ${tagline}. Slow orbit, studio lighting.\\" \\\\\\n --model gemini-omni-flash --ar 9:16 --duration 6 \\\\\\n --start-image \\"$image\\" \\\\\\n --no-wait --json | jq -r .job_id)\\n echo \\"$name,$job\\" >> outputs/jobs.csv\\ndone < <(tail -n +2 products.csv)\\n\\n# Collect ALL results with ONE process (batched polling \u2014 one request per tick)\\nvideodraft wait $(cut -d, -f2 outputs/jobs.csv) \\\\\\n --download \\"outputs/{job_id}_{index}.{ext}\\" --json > outputs/results.json\\n# map job ids back to product names via outputs/jobs.csv\\n```\\n\\nSubmit-then-collect parallelizes server-side generation; the single multi-id `wait` keeps it to one local process and one batched poll request per tick no matter how many jobs. Gemini Omni Flash is selected because these are six-second first-frame product clips. Estimate first: `videodraft costs gemini-omni-flash --type video --duration 6 --resolution 720p --audio` \xD7 rows, and confirm with the user.\\n\\n## 2. Full marketing video from one idea\\n\\n```bash\\nvideodraft create \\"30-second launch video for Solace, a sleep-tracking ring. Calm, premium, dark palette.\\" \\\\\\n --ar 9:16 --style cinematic --json > project.json\\nPROJECT=$(jq -r .project_id project.json)\\n\\nvideodraft shots \\"$PROJECT\\" --grid --estimate # show the user the cost; get a go-ahead\\nvideodraft shots \\"$PROJECT\\" --grid\\nvideodraft produce \\"$PROJECT\\"\\nvideodraft generate music \\"minimal ambient, warm pads, 60 BPM\\" --attach \\"$PROJECT\\"\\nvideodraft generate audio \\"Extend @Audio1 into a 20-second transition\\" --ref-audio ./intro.wav --format wav --download ./transition.wav\\nvideodraft export \\"$PROJECT\\" --download solace-launch.mp4\\n```\\n\\nThe project stays editable at the URL in `project.json` (`.urls`) \u2014 hand it to the user for tweaks.\\n\\n## 3. Talking-head (avatar) video\\n\\nWhen the user has no portrait, generate a clear front-facing avatar image first. Skip this step when they supplied one or an existing character should be reused.\\n\\n```bash\\nvideodraft generate image \\\\\\n \\"Front-facing head-and-shoulders portrait of a friendly coffee expert, direct eye contact, natural expression, clean studio background\\" \\\\\\n --model nano-banana-2 --ar 9:16 --download ./media/avatar.png\\n\\nSCRIPT=$(videodraft avatar script \\"why our espresso subscription saves you money\\" --style ad-style --json | jq -r .script)\\nAVATAR=$(videodraft avatar create ./media/avatar.png --script \\"$SCRIPT\\" --voice elevenlabs-kPzsL2i3teMYv0FxEYQ6 --ar 9:16 --json | jq -r .avatar_video_id)\\nvideodraft avatar render \\"$AVATAR\\" --resolution 720p # VEED Fabric paid step; confirm cost first (~20 credits/sec)\\n```\\n\\n`avatar script` and `avatar create` (including speech) are bundled/free. In this example only the optional portrait generation and Fabric render spend credits.\\n\\nIf the portrait is low resolution, enhance it before `avatar create`:\\n\\n```bash\\nvideodraft upscale image ./founder-small.jpg --scale 2x --download ./media/founder-upscaled.png\\n```\\n\\nFor a one-off portrait animation without creating a managed avatar record:\\n\\n```bash\\nvideodraft avatar fabric ./founder.jpg \\\\\\n --text \\"Welcome to the weekly product update.\\" \\\\\\n --voice-description \\"warm, confident American presenter\\" \\\\\\n --resolution 720p --download ./media/presenter.mp4\\n```\\n\\nWhen the user already has both the video and replacement speech:\\n\\n```bash\\nvideodraft avatar lipsync ./presenter.mp4 \\\\\\n --audio ./localized-voiceover.mp3 \\\\\\n --sync-mode loop --download ./media/presenter-localized.mp4\\n```\\n\\nEdit an existing video with a dedicated edit model:\\n\\n```bash\\nvideodraft models video --category video_edit\\nvideodraft edit video ./product-demo.mp4 \\\\\\n \\"Turn the room into a warm evening scene while preserving the product and camera motion\\" \\\\\\n --model wan-2.7-ref-edit --ref ./evening-style.jpg \\\\\\n --preserve-audio --download ./media/product-demo-evening.mp4\\n```\\n\\nTransfer motion from a reference clip onto a character image:\\n\\n```bash\\nvideodraft edit motion ./character.png \\\\\\n \\"Apply the dancer\'s movement to this character while preserving identity\\" \\\\\\n --motion-video ./dance-reference.mp4 \\\\\\n --model kling-v3-motion-control --quality pro \\\\\\n --download ./media/character-dance.mp4\\n```\\n\\n## 4. Changelog video in CI\\n\\nIn a GitHub Action with `VIDEODRAFT_API_KEY` set as a secret:\\n\\n```bash\\nNOTES=$(git log --oneline v1.2.0..HEAD | head -20)\\nvideodraft create \\"Weekly product update video. Energetic, 20 seconds. Changes: ${NOTES}\\" --ar 16:9 --json > p.json\\nPROJECT=$(jq -r .project_id p.json)\\nvideodraft shots \\"$PROJECT\\" && videodraft produce \\"$PROJECT\\"\\nvideodraft export \\"$PROJECT\\" --download changelog.mp4 --wait-timeout 30m\\n```\\n\\n## 5. Variations and picking a winner\\n\\n```bash\\nvideodraft generate image \\"logo concept: minimalist fox, geometric\\" --num 4 --download \\"./concepts/{job_id}_{index}.{ext}\\" --json\\n# Show all 4 to the user; regenerate the chosen one at higher res:\\nvideodraft generate image \\"<same prompt>\\" --model nano-banana-pro --resolution 4K\\n```\\n\\n## 6. Reaching tools without a curated command\\n\\n```bash\\nvideodraft tools list --json | jq -r \'.[].name\'\\nvideodraft tools schema attach_media_to_shot --json\\nvideodraft call attach_media_to_shot --args \'{\\"project_id\\":\\"...\\",\\"scene_index\\":0,\\"shot_index\\":1,\\"media_url\\":\\"https://...\\",\\"media_type\\":\\"video\\",\\"duration_seconds\\":6}\'\\n```\\n\\nAnything the VideoDraft MCP exposes \u2014 character studio, product studio, timeline editing \u2014 is reachable this way even before it gets a curated command.\\n\\n## 7. Enhance an existing asset without changing it\\n\\n```bash\\n# Light image cleanup, no enlargement\\nvideodraft upscale image ./poster.png --scale 1x --download ./media/poster-enhanced.png\\n\\n# General image and video enlargement\\nvideodraft upscale image ./frame.png --scale 2x --download ./media/frame-2x.png\\nvideodraft upscale video ./clip.mp4 --scale 2x --download ./media/clip-2x.mp4\\n```\\n\\nUse these when the content is correct and only quality or resolution needs improvement. If the poster text, composition, subject, or motion is wrong, edit or regenerate instead.\\n","references/models.md":"# Choosing models (and predicting cost)\\n\\nAlways consult the live catalog instead of memorizing this page \u2014 models change weekly:\\n\\n```bash\\nvideodraft models image --json # every image model + inputs (aspect ratios, resolutions, max refs)\\nvideodraft models video --json # every video model + inputs + per-second pricing metadata\\nvideodraft models audio --json # standalone audio/media models + pricing inputs\\nvideodraft models voices --json # TTS voices\\nvideodraft models styles --json # visual style presets\\n```\\n\\n## Task-based model selection\\n\\nHonor an explicitly named model when it supports the request. Otherwise choose from the task\'s inputs, duration, audio, quality, speed, and cost. Pass the chosen model explicitly instead of relying on a blind platform fallback.\\n\\n### Images\\n\\n| Need | Choose | Why |\\n| -------------------------------------------------------------------------------------- | -------------------- | ----------------------------------------------------------------- |\\n| Most generation, editing, character consistency, or reference work | `nano-banana-2` | Best general default; 1K/2K/4K and up to 14 reference images |\\n| Highest-quality complex generation or reasoning | `nano-banana-pro` | Premium Nano Banana quality and reasoning |\\n| Fast, inexpensive drafts and iteration | `nano-banana-2-lite` | Fastest/cheapest Nano Banana option; 1K only, up to 14 references |\\n| Posters, title cards, signs, logos, or any image with important readable text | `gpt-image-2` | Strong text rendering; up to 16 image inputs and 1K/2K/4K output |\\n| Complex multi-image composition, precise editing, or a strong alternate interpretation | `gpt-image-2` | Strong non-Nano alternative with multi-image input |\\n\\nUse `--num 1..4` for variations of one prompt in a single call. Never loop separate paid calls for variations that fit in one request.\\n\\n### Videos\\n\\n| Need | Choose | Important limits |\\n| ---------------------------------------------------------------------------------------------------------- | ------------------- | --------------------------------------------------------------------------------------------------- |\\n| Most text, first-frame, image-reference, or source-video-edit requests up to 10s | `gemini-omni-flash` | 720p, 3-10s or auto, audio always on, up to 10 total image inputs, one source video |\\n| Video/audio references, mixed reference media, broad aspect ratios, frame-mode first+last frame, or 11-15s | `seedance-2` | 4-15s or auto; up to 9 image, 3 video, and 3 audio refs; audio toggle; Mini/Fast are 480p/720p only |\\n| Fast polished 3-15s video with first frame, multi-prompt, and native audio | `kling-v3-turbo` | Audio always on; Pro default; no end frame or reference-media mode |\\n| Cinematic 3-15s with image references, first+last frame, multi-prompt, audio control, or 4K | `kling-o3` | Up to 7 image refs; Standard/Pro/4K; audio toggle |\\n| Kling 3-15s with first+last frame, multi-prompt, optional audio, or 4K, without reference-image mode | `kling-3.0` | Standard/Pro/4K; audio toggle |\\n| User explicitly requests Veo, or the selected workflow specifically needs Veo | `google-veo3.1` | Good fallback, but not the preferred general model |\\n\\nRouting rules:\\n\\n- Around 11-15 seconds with native audio: use Kling or Seedance, not Gemini.\\n- One existing source video that should be edited, with an output up to 10 seconds and no additional media references to preserve: use Gemini Omni Flash.\\n- Video or audio supplied as creative reference: use Seedance 2.0.\\n- A video plus any image/audio references that must all be preserved: use Seedance 2.0. Do not promise that Gemini will preserve mixed source media; its Fal BYOK edit mode accepts only the source video and prompt.\\n- First and last frame control: use Seedance, Kling O3, or Kling 3.0. Gemini supports a first frame but not a last frame.\\n- Seedance reference mode and first-plus-last-frame mode are separate. Do not promise reference video/audio plus a last frame in one generation.\\n- Multi-prompt sequencing: use Kling 3.0 Turbo, Kling O3, or Kling 3.0.\\n- Seedance quality: `mini` for the lowest cost, `fast` for speed, `standard` for maximum quality and for 1080p/4K.\\n\\n### Video edit and motion-control categories\\n\\nUse `videodraft models video --category video_edit` for existing-video transforms and `--category motion_control` for motion transfer.\\n\\n| Need | Command/model | Important limits |\\n| ------------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------- |\\n| Simple prompt edit of one video | `videodraft edit video <video> \\"...\\" --model grok-imagine-video-edit` | No image refs; source truncated to 8s; auto/480p/720p |\\n| Edit with one style/reference image | `--model wan-2.7-ref-edit --ref <image>` | One image ref; 2-10s or match source |\\n| Edit with several image references | `--model happy-horse-video-edit --ref ...` | Up to 5 refs; 720p/1080p; source capped at 15s |\\n| Controlled Kling edit | `--model kling-o3-video-ref-edit --ref ...` | Up to 4 refs; Standard/Pro; source clamped to 3-10s |\\n| Transfer reference motion to an image | `videodraft edit motion <image> \\"...\\" --motion-video <video>` | Kling V3 default; image orientation caps motion at 10s, video orientation at 30s |\\n\\nIf the user explicitly names one of these models, preserve it. The CLI uploads local source videos and reference images automatically. Editing returns an async job and waits by default.\\n\\nKling O3 and Wan 2.7 Ref/Edit are dual-mode cards. `videodraft edit video` uses edit mode. `videodraft generate video --model kling-o3-video-ref-edit` requires exactly one `--ref-video` and generates a new reference-guided clip. `--model wan-2.7-ref-edit` generates a new clip from one or more `--ref`/`--ref-video` inputs.\\n\\n### Reference-first video workflow\\n\\n- Prefer a start frame or reference image whenever a specific character, product, location, style, composition, or brand identity must stay recognizable.\\n- If the user gives a reference, pass it. Never silently replace it with a text description.\\n- If no reference exists and continuity matters, generate a still first with the user\'s explicitly requested compatible image model, otherwise use Nano Banana 2. Wait for the image URL, then animate it with the selected video model. Confirm the combined image plus video cost before starting.\\n- For multi-shot scenes, generate shot images with `videodraft shots <project_id> --model <selected-image-model> --grid`. Preserve an explicitly requested compatible image model; otherwise use `nano-banana-2`. The grid establishes the scene and characters together, then decodes into individual shot images.\\n- Animate the decoded shot images as per-shot start frames or references. Do not independently text-generate each video clip when the shots need to match.\\n- Pure text-to-video remains appropriate for generic one-off footage where no subject, composition, or continuity needs to be preserved.\\n\\n### Audio\\n\\n- **Seed Audio 1.0**: use `videodraft generate audio` for open-ended speech, sound, music, or prompt-driven audio editing. It accepts up to three audio references or one image. Address audio references as `@Audio1`, `@Audio2`, and `@Audio3`. Preset and custom cloned voice IDs are supported. Output is up to 120 seconds. There is no requested-duration input. The CLI automatically retries transient responses with one idempotency key. To recover after the CLI process itself is interrupted, set `--idempotency-key <uuid>` on the original command and reuse it.\\n- **Voiceover/TTS**: prefer ElevenLabs. Brittney is the platform default voice; under ElevenLabs BYOK, use a compatible voice from the user\'s account. Honor another supported voice/provider when the user explicitly selects it.\\n- **Dialogue, voice changing, and dubbing**: ElevenLabs only.\\n- **Sound effects**: ElevenLabs Sound Effects only.\\n- **Music**: use `lyria-3-clip-preview` for a short instrumental/background score, `lyria-3-pro-preview` for a longer or higher-quality instrumental score, and `elevenlabs-music` when vocals/lyrics or a specified 10-120 second length matter.\\n- Voice Changer and Dubbing require the source media duration and currently accept source media up to 300 seconds.\\n\\n### Avatar / talking head\\n\\nChoose the dedicated path from the media the user already has:\\n\\n| Starting media | Command | Use |\\n| ----------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------- |\\n| Portrait + script, reusable avatar record | `videodraft avatar create <portrait> --script \\"...\\"` then `avatar render` | Managed avatar flow with bundled speech preparation |\\n| Portrait + text | `videodraft avatar fabric <portrait> --text \\"...\\"` | One-off direct VEED Fabric text mode |\\n| Portrait + existing audio | `videodraft avatar fabric <portrait> --audio <audio>` | One-off direct VEED Fabric audio lip sync |\\n| Existing video + existing audio | `videodraft avatar lipsync <video> --audio <audio>` | Sync Labs Lipsync 2 |\\n\\nThe managed renderer is VEED Fabric Fast (`veed/fabric-1.0/fast`). Direct Fabric and Sync Labs are paid AI Studio generations and return async job IDs.\\n\\n1. Obtain the avatar image. Prefer the user\'s supplied portrait or an existing character. If none exists, use the user\'s explicitly requested compatible image model, otherwise generate a front-facing head-and-shoulders portrait with `nano-banana-2`, direct eye contact, a natural expression, and a clean background. Match the intended video aspect ratio when practical.\\n2. If the portrait is visibly soft or too small, run Topaz image enhancement/upscaling before animation.\\n3. Generate a script only if needed: `videodraft avatar script \\"<idea>\\"`.\\n4. Create the avatar record and speech: `videodraft avatar create <portrait-url-or-file> --script \\"...\\" --voice <id> --ar 9:16`. Prefer ElevenLabs when unspecified, but honor another explicitly selected supported voice/provider.\\n5. Render with VEED Fabric: `videodraft avatar render <avatar_video_id> --resolution 720p`.\\n\\nThe portrait is passed as the avatar\'s character image, not as a generic video\'s start frame. Prefer rendering directly at 720p. Use 480p only when the user prioritizes lower cost. Avatar script generation and `avatar create` (including speech) are bundled/free. Confirm the Fabric render cost, plus portrait generation or upscaling when needed.\\n\\nDirect Fabric text/audio and Sync Labs do not use the managed avatar record. The CLI uploads local portrait, video, and audio files automatically. `avatar fabric --speed fast` applies only to audio mode. Sync costs 5 credits per verified audio second; under Fal BYOK, `sync_mode` remains available but `temperature` and `active_speaker` are ignored by the provider.\\n\\n### Upscaling / enhancement\\n\\n- **Images**: Topaz via `videodraft upscale image <url-or-file> --scale 1x|2x|4x`. Use 1x for light enhancement without enlargement, 2x as the general default, and 4x only when the source quality and target size justify it. The result is synchronous.\\n- **Videos**: Topaz via `videodraft upscale video <url-or-file> --scale 2x`. Use 2x by default. The job is asynchronous; the CLI waits by default, while MCP callers poll `check_generation_status`. MCP video input must be VideoDraft-hosted, so upload local or external sources first.\\n- Use upscaling to preserve the image/video while improving detail, resolution, or cleanup. It cannot fix the wrong subject, misspelled text, bad framing, unwanted objects, broken continuity, or incorrect motion. Use an edit or regeneration for those problems.\\n- For a new Fabric avatar, render directly at 720p instead of rendering at 480p and then upscaling. Upscale the source portrait first only when the portrait itself is low quality.\\n\\n## Capability gotchas\\n\\n- Each model\'s `inputs` block is authoritative: supported `aspect_ratios`, `resolutions`, `quality_options`, `start_frame`/`end_frame`, `max_reference_images/videos/audio`, `multi_prompt`, `audio_toggle`. Passing an unsupported input fails with a clear error \u2014 check first, don\'t trial-and-error paid calls.\\n- Most video models support only 16:9 / 9:16 / 1:1. A 3:4 request hard-fails on most.\\n- `--seed` reproduces a specific output on models that support it (e.g. Flux, Ideogram V4); everything else ignores it. You do not need a seed for variation \u2014 `--num` already varies.\\n- `--rendering-speed` applies to Ideogram (V3: `Default`/`Turbo`/`Quality`; V4: `Turbo`/`Balanced`/`Quality`) and affects image cost \u2014 pass it to `videodraft costs ... --rendering-speed <tier>` for an accurate estimate. Always trust `videodraft models image --json` over this list; new models and tiers appear there the moment the platform ships them, with no CLI update.\\n- `seedream-v5-pro` supports unified text-to-image and reference-image editing with up to 10 image references. Use `--resolution 1K` for 7 credits/image or `--resolution 2K` for 14 credits/image.\\n- Reference inputs: `--ref <img>` (images), `--ref-video <v>` (Gemini Omni Flash, Seedance 2, Wan 2.7), `--ref-audio <a>` (Seedance 2). The CLI uploads local files for all of these, so you can pass a path or a URL. `--segment \\"<prompt>:<seconds>\\"` (repeatable) drives multi-prompt models (Kling 3.0 / 3.0 Turbo / O3); total 3-15s. `generate image --video-ref` is the nano-banana-2 video reference.\\n- The top-level prompt is OPTIONAL for `generate video` with multi-prompt models and for Kling 3.0 Turbo (`--model kling-v3-turbo`) image-to-video \u2014 a `--segment`-only or `--start-image`-only call is valid. Every other model still needs a prompt; the server enforces per-model rules.\\n- AI Production: `videodraft produce <project> --mode full_video` generates one Seedance 2 video per scene; poll with `videodraft generations`, then `videodraft finalize <project>` swaps them into the timeline before `export`. If the user explicitly requests another compatible video model, do not use this fixed Seedance path. Generate the project shots manually with the requested model and attach them to the timeline.\\n\\n## Cost model\\n\\n- Images: per image (\xD7 `--num`). Matrix-priced models (GPT-Image, Nano Banana Pro, Seedream v5 Pro) vary by resolution/quality.\\n- Video: usually credits/second \xD7 duration; rate depends on model + resolution + quality + native audio on/off.\\n- Shot-image batches: one image per shot (+1 grid image per scene in `--grid` mode) \u2014 the largest single spend in the pipeline.\\n- VEED Fabric avatar renders: ~10 credits/sec at 480p, ~20/sec at 720p. Avatar creation and its speech are bundled/free; only optional portrait generation/upscaling adds cost before the render.\\n- Direct VEED Fabric: text or normal audio is 8 credits/sec at 480p and 15/sec at 720p; fast audio is 10/sec at 480p and 20/sec at 720p.\\n- Sync Labs Lipsync 2: 5 credits per verified audio second.\\n- Voiceover TTS: 10 credits per 1000 characters for standard voices, 30 per 1000 for cloned `custom-*` voices (min 1, pro-rated); applies to standalone voiceovers AND per-scene narration during `produce`. Silent tracks are free. Voice cloning itself is a flat 150 credits per clone.\\n- Lyria music: flat per track, 10 credits (clip) / 15 credits (pro).\\n- Seed Audio 1.0: 19 credits per actual output minute, prorated and rounded up to a whole credit. VideoDraft reserves the 120-second maximum of 38 credits and refunds the unused portion after generation. Fal BYOK is free.\\n- ElevenLabs audio: sound effects are per second, dialogue is per character, music/voice-changer/dubbing are per started minute. Voice changer and dubbing reject source media above 300s in the current synchronous flow.\\n- Upscales: priced by scale and source size.\\n\\nQuote before spending:\\n\\n```bash\\nvideodraft costs gemini-omni-flash --type video --duration 8 --resolution 720p --audio\\nvideodraft costs seedance-2 --type video --duration 15 --resolution 720p --quality standard --audio\\nvideodraft costs elevenlabs-dubbing --type audio --duration 60\\nvideodraft costs seed-audio-1.0 --type audio --duration 60 # scenario only; model controls actual length\\nvideodraft costs elevenlabs-dialogue --type audio --chars 350\\nvideodraft costs voiceover --type audio --chars 800 # TTS: 10 cr / 1000 chars\\nvideodraft generate video \\"...\\" --model gemini-omni-flash --estimate # same quote, inline\\n```\\n","references/pipeline.md":"# VideoDraft pipeline reference\\n\\nEverything here works through the CLI (`videodraft <command>` / `videodraft call <tool>`) or the MCP connector (tool names in backticks). One backend; pick the surface you have.\\n\\nUse direct asset tools for standalone images, clips, audio, upscales, and descriptions. Use a project for any multi-scene video, story, ad, explainer, storyboard, editable timeline, or final export even when the request does not use the word \\"project.\\" Script-only uses a script-stage project and stops at the script.\\n\\n## Stages and their tools\\n\\n| Stage | CLI | Underlying tool |\\n| --------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------ |\\n| Idea \u2192 full storyboard project | `videodraft create \\"<idea>\\"` | `generate_storyboard_from_idea` |\\n| Idea \u2192 script only (stop there) | `videodraft create \\"<idea>\\" --script-only` | `generate_script_from_idea` |\\n| Footage IS the video | `videodraft call generate_storyboard_from_media` | `generate_storyboard_from_media` |\\n| Batch shot images | `videodraft shots <project>` | `generate_shot_images` |\\n| One shot image | `videodraft generate image --project <id> --scene N --shot M` | `generate_image` |\\n| Produce (voiceover, captions, timeline) | `videodraft produce <project>` | `produce_project` |\\n| Per-shot motion prompts | `videodraft video-prompts <project>` | `generate_video_prompts` |\\n| Motion clip for a shot | `videodraft generate video --project <id>` | `generate_video` |\\n| Attach a finished clip to the timeline | `videodraft attach <project> --scene N --shot M --media <url> --type video` | `attach_media_to_shot` |\\n| Background music | `videodraft generate music --attach <project>` | `generate_music` / `set_background_music` |\\n| General or reference-driven audio | `videodraft generate audio \\"...\\"` | `generate_audio` |\\n| Sound effect | `videodraft generate sound-effect \\"...\\"` | `generate_sound_effect` |\\n| Dialogue audio | `videodraft generate dialogue --line \\"voice:text\\"` | `generate_dialogue` |\\n| Voice changer | `videodraft generate voice-changer <audio>` | `change_voice` |\\n| Dubbing | `videodraft generate dub <audio_or_video>` | `dub_media` |\\n| Scene voiceover | `videodraft generate voiceover --project <id> --scene N` | `generate_voiceover` |\\n| Avatar script | `videodraft avatar script \\"<idea>\\"` | `generate_avatar_script` |\\n| Avatar + speech | `videodraft avatar create <portrait> --script \\"...\\"` | `create_avatar_video` |\\n| Talking-head render | `videodraft avatar render <avatar_video_id>` | `render_avatar_video` + `get_avatar_video` |\\n| Direct portrait + text/audio | `videodraft avatar fabric <portrait> --text \\"...\\"` or `--audio <file>` | `generate_veed_fabric_video` |\\n| Existing video + replacement audio | `videodraft avatar lipsync <video> --audio <file>` | `generate_sync_lipsync_video` |\\n| Existing-video AI edit | `videodraft edit video <video> \\"<change>\\" --model <video-edit-model>` | `edit_video` |\\n| Motion transfer | `videodraft edit motion <image> \\"<direction>\\" --motion-video <video>` | `generate_motion_control_video` |\\n| Image enhancement/upscale | `videodraft upscale image <image>` | `upscale_image` |\\n| Video enhancement/upscale | `videodraft upscale video <video>` | `upscale_video` |\\n| Final MP4 | `videodraft export <project>` | `export_video` + `check_export_status` |\\n\\n## Rules that prevent broken results\\n\\n- **The storyboard is generated FROM the script**, never from the raw idea. `videodraft create` runs the whole chain correctly. Don\'t call `generate_storyboard_scenes` with a raw idea as the \\"script\\".\\n- **Visual consistency**: never generate a storyboard shot in isolation. Shot prompts carry `[[asset:Name]]` / `[[shot:X-Y]]` tags that `generate_shot_images` resolves against the project\'s visual assets and prior shots. When generating a single shot whose prompt has no tags, pass `--ref` images yourself (the project\'s visual assets and/or the previous shot\'s image; `projects get` exposes both). For scenes with multiple shots or recurring characters, prefer `videodraft shots <project> --model <selected-image-model> --grid`: preserve an explicitly requested compatible image model, otherwise use `nano-banana-2`. It creates one coherent scene grid, then decodes it into individual shot images.\\n- **Reference-first video**: when identity, styling, or composition matters, do not generate each motion clip from text alone. Generate or select the shot still first, then pass the decoded shot image as `--start-image` or `--ref` to the selected video model. AI Production already composes scene grids and sends them to Seedance as references. If the user explicitly requests another compatible video model, bypass fixed Seedance full-video mode and generate the per-shot clips with the requested model, using the individual decoded shot images as anchors.\\n- **Hold off generating shot images while the user is still iterating** on storyboard structure.\\n- **produce \u2192 export ordering**: `export` requires a produced project where every production scene has timeline media. If `produce` returns `generating_shot_images`, poll the job ids it returns, then re-run produce.\\n- **Generated motion clips do not auto-attach**: after `generate video` completes, attach the clip with `attach_media_to_shot` (`media_type:\\"video\\"`, include `duration_seconds`) \u2014 it replaces the production timeline clip while keeping the storyboard still.\\n- **Talking heads use dedicated avatar tools**: do not use `generate video`. Use managed `avatar create` and `avatar render` for reusable avatars, direct `avatar fabric` for a portrait plus text/audio, and `avatar lipsync` for an existing video plus replacement audio. Reuse a supplied person image or generate a clear front-facing portrait with the explicitly requested compatible image model, otherwise Nano Banana 2. Managed avatar creation and speech are bundled/free; direct Fabric, Sync, and render are paid.\\n- **Existing-video edits use their own category**: call `edit_video` or `videodraft edit video` with a `video_edit` model when transforming the source itself. Kling O3 and Wan 2.7 Ref/Edit are dual-mode: their reference-generation modes may use generic `generate_video` to create a new guided clip. Motion transfer similarly uses `generate_motion_control_video` or `videodraft edit motion` with a `motion_control` model.\\n- **Upscaling preserves rather than redesigns**: use Topaz when resolution, detail, or cleanup is the problem. Regenerate or edit when the subject, text, framing, continuity, or motion is wrong. Upscale a low-quality avatar portrait before Fabric; do not render a new avatar at 480p just to upscale the result.\\n- **Timeouts on the one-shot create**: if `create` times out at the transport layer, the project was still created server-side \u2014 `videodraft projects list`, take the most recent, and resume with its id. Don\'t start a duplicate.\\n\\n## User-attached media: classify roles first\\n\\nFor EACH attached file decide:\\n\\n- **visual_asset** \u2014 recurring reference (character / product / location / style). Upload, then pass in `visual_assets` of `generate_storyboard_from_idea` (via `videodraft call`), or add to an existing project with `add_visual_assets`. Type must be one of `character | object | location | style | custom` with a short name + concrete description.\\n- **shot** \u2014 the media IS footage for the video. Whole video = footage \u2192 `generate_storyboard_from_media`. Idea + footage \u2192 `generate_storyboard_from_idea` with `shot_media`. Existing storyboard \u2192 `attach_media_to_shots`.\\n- **reference** \u2014 inspiration only \u2192 fold a description into the idea/instructions; don\'t place it as a shot or asset.\\n\\nAmbiguous (e.g. a person holding a product)? Ask the user.\\n\\nUploads persist in the media library \u2014 recall later with `videodraft media list`.\\n\\n## Editing project data safely\\n\\n1. `videodraft call get_project_schema` \u2014 read the structure once per session.\\n2. `videodraft projects get <id> --raw` \u2014 the exact editable blob.\\n3. Modify; then `videodraft call update_project --stdin` with `{\\"project_id\\": \\"...\\", \\"data\\": {...}}`.\\n - Objects deep-merge key-by-key; **arrays replace wholesale** \u2014 send the complete array you\'re changing (e.g. all of `storyboard.scenes`).\\n - Scene shot arrays (`image_prompt` / `shot_types` / `shot_actions` / `search_prompt` / `preview_media`) are auto-aligned; fix-ups come back as warnings.\\n4. Snapshot before risky edits: `videodraft checkpoint create <id> --name \\"before re-script\\"`. Restore with `videodraft checkpoint restore <id> <version>`.\\n\\n## AI Studio sessions (standalone generations)\\n\\nProject generations group automatically. For standalone work in a long conversation, create one session up front and reuse it:\\n\\n```bash\\nSESSION=$(videodraft call create_ai_studio_session --arg name=\\"Fox brand explorations\\" --json | jq -r .session_id)\\nvideodraft generate image \\"...\\" --session \\"$SESSION\\"\\n```\\n"}');
3739
3876
  }
3740
3877
  const root = bundledSkillDir();
3741
3878
  const files = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "videodraft",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Official VideoDraft CLI — create AI videos, images and audio from your terminal. Agent-friendly: --json everywhere, stable exit codes, async job polling.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/skills/index.json CHANGED
@@ -22,8 +22,8 @@
22
22
  },
23
23
  {
24
24
  "path": "SKILL.md",
25
- "sha256": "9224534293e174a776804abd614aa7199dabfcb140dba15c225e28de6edd229c",
26
- "bytes": 15819
25
+ "sha256": "cc80f773350858bc4ef430ebd8cd4e6e55c1a98101c759edea39da443118ab43",
26
+ "bytes": 16074
27
27
  }
28
28
  ]
29
29
  }
@@ -84,7 +84,7 @@ For expensive work, estimate with `--estimate` or `videodraft costs`, state the
84
84
 
85
85
  ## Async jobs
86
86
 
87
- Image/video generation is asynchronous: commands submit a job and **wait by default**, printing output URLs (and saving files with `--download`). In scripts/CI prefer explicit control:
87
+ Image/video generation is asynchronous: commands submit a job and **wait by default**, printing output URLs (and saving files with `--download`). Large downloaded images also get a downscaled copy in `previews/` next to them (the `preview` field / "inspect via preview" line in the output) — **look at the preview, deliver the original**; viewing full-resolution images bloats the chat permanently. In scripts/CI prefer explicit control:
88
88
 
89
89
  ```bash
90
90
  JOB=$(videodraft generate image "..." --no-wait --json | jq -r .job_id)