@vibeframe/cli 0.113.5 → 0.113.7

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/index.js CHANGED
@@ -41111,8 +41111,8 @@ async function executeJumpCut(options) {
41111
41111
  };
41112
41112
  } finally {
41113
41113
  try {
41114
- const { rm: rm5 } = await import("node:fs/promises");
41115
- await rm5(tmpDir, { recursive: true, force: true });
41114
+ const { rm: rm6 } = await import("node:fs/promises");
41115
+ await rm6(tmpDir, { recursive: true, force: true });
41116
41116
  } catch {
41117
41117
  }
41118
41118
  }
@@ -41457,8 +41457,8 @@ SRT saved to: ${outputSrtPath2}`
41457
41457
  };
41458
41458
  } finally {
41459
41459
  try {
41460
- const { rm: rm5 } = await import("node:fs/promises");
41461
- await rm5(tmpDir, { recursive: true, force: true });
41460
+ const { rm: rm6 } = await import("node:fs/promises");
41461
+ await rm6(tmpDir, { recursive: true, force: true });
41462
41462
  } catch {
41463
41463
  }
41464
41464
  }
@@ -62082,7 +62082,7 @@ __export(scene_build_exports, {
62082
62082
  resolveSceneBuildMode: () => resolveSceneBuildMode
62083
62083
  });
62084
62084
  import { existsSync as existsSync49, readFileSync as readFileSync3 } from "node:fs";
62085
- import { copyFile as copyFile5, mkdir as mkdir26, readFile as readFile46, writeFile as writeFile50 } from "node:fs/promises";
62085
+ import { copyFile as copyFile5, mkdir as mkdir26, readFile as readFile46, rm as rm4, writeFile as writeFile50 } from "node:fs/promises";
62086
62086
  import { dirname as dirname24, join as join25, resolve as resolve65 } from "node:path";
62087
62087
  async function executeSceneBuild(opts) {
62088
62088
  const startedAt = Date.now();
@@ -62090,9 +62090,9 @@ async function executeSceneBuild(opts) {
62090
62090
  const onProgress = opts.onProgress ?? (() => {
62091
62091
  });
62092
62092
  const mode = resolveSceneBuildMode(opts);
62093
- let selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
62093
+ const selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
62094
62094
  const skipVideoStopsRender = (opts.skipVideo ?? false) && (selectedStage === "all" || selectedStage === "render");
62095
- if (skipVideoStopsRender) selectedStage = "sync";
62095
+ const effectiveSkipRender = (opts.skipRender ?? false) || skipVideoStopsRender;
62096
62096
  const stageReports = createEmptyStageReports();
62097
62097
  const warnings = [];
62098
62098
  const retryWith = [];
@@ -62588,7 +62588,7 @@ async function executeSceneBuild(opts) {
62588
62588
  });
62589
62589
  }
62590
62590
  }
62591
- if (selectedStage === "sync" || opts.skipRender) {
62591
+ if (selectedStage === "sync" || effectiveSkipRender) {
62592
62592
  return finishBuildResult({
62593
62593
  success: true,
62594
62594
  phase: "sync-only",
@@ -62880,6 +62880,10 @@ async function dispatchNarration(beat, ctx) {
62880
62880
  }
62881
62881
  await mkdir26(dirname24(abs), { recursive: true });
62882
62882
  await writeFile50(abs, result.audioBuffer);
62883
+ for (const otherExt of ["mp3", "wav"]) {
62884
+ const sibling = join25(ctx.projectDir, `assets/narration-${beat.id}.${otherExt}`);
62885
+ if (sibling !== abs && existsSync49(sibling)) await rm4(sibling, { force: true });
62886
+ }
62883
62887
  await mkdir26(dirname24(cacheAbs), { recursive: true });
62884
62888
  await writeFile50(cacheAbs, result.audioBuffer);
62885
62889
  await writeAssetMetadata({
@@ -62912,11 +62916,12 @@ async function dispatchNarration(beat, ctx) {
62912
62916
  }
62913
62917
  function characterSheetPrompt(name, description) {
62914
62918
  return [
62915
- `Character turnaround reference sheet of an original fictional character named ${name}: ${description}.`,
62916
- "Show three full-body views side by side on one clean canvas \u2014 front view, side profile, and back view \u2014",
62917
- "with identical outfit, hairstyle, hair color, and body proportions across all three views.",
62919
+ `Character reference sheet of an original fictional character named ${name}: ${description}.`,
62920
+ "Top row: ONE large, sharp, evenly-lit frontal close-up of the FACE (head and shoulders) as the primary identity anchor \u2014 clear eyes, nose, jawline, and skin detail.",
62921
+ "Bottom row: three full-body views side by side \u2014 front, side profile, and back.",
62922
+ "The face, facial features, hairstyle, hair color, outfit, and body proportions must be IDENTICAL across the close-up and all three views.",
62918
62923
  "Plain light-grey studio background, even neutral lighting, no props.",
62919
- "Photorealistic digital character, professional concept-art character sheet layout."
62924
+ "Photorealistic, professional concept-art character sheet layout."
62920
62925
  ].join(" ");
62921
62926
  }
62922
62927
  async function buildCharacters(characters, ctx) {
@@ -63255,7 +63260,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
63255
63260
  imageSize: size,
63256
63261
  imageQuality: ctx.imageQuality
63257
63262
  };
63258
- const generated = sheetBuffers.length > 0 ? await editKeyframeImage(keyframeCue, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
63263
+ const identityLock = "Keep the EXACT same person and face as the reference image(s): identical facial features (eyes, nose shape, jawline), skin tone and complexion, hairstyle, hair color, and wardrobe. Do not restyle or change the face. Change only the scene, pose, framing, and lighting. ";
63264
+ const generated = sheetBuffers.length > 0 ? await editKeyframeImage(`${identityLock}${keyframeCue}`, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
63259
63265
  if (!generated.success) return { status: "failed", error: generated.error };
63260
63266
  await mkdir26(dirname24(abs), { recursive: true });
63261
63267
  await writeFile50(abs, generated.buffer);
@@ -63397,6 +63403,10 @@ async function dispatchVideo(beat, ctx, keyframe) {
63397
63403
  // reference-to-video.
63398
63404
  image: keyframeImageAbs,
63399
63405
  refImages: keyframeImageAbs ? void 0 : characterRefsAbs.length > 0 ? characterRefsAbs : void 0,
63406
+ // Build clips are always muted in the composition (a separate narration/music
63407
+ // track carries audio), so the model's generated audio is never used. Disable
63408
+ // it: it's wasted, and Seedance's audio moderation can spuriously fail a beat.
63409
+ generateAudio: false,
63400
63410
  apiKey: await apiKeyForVideoProvider(ctx.videoProvider, ctx.projectDir)
63401
63411
  });
63402
63412
  if (!result.success || !result.taskId) {
@@ -74851,7 +74861,7 @@ init_source();
74851
74861
  // package.json
74852
74862
  var package_default = {
74853
74863
  name: "@vibeframe/cli",
74854
- version: "0.113.5",
74864
+ version: "0.113.7",
74855
74865
  description: "VibeFrame CLI - agentic video workflow runtime",
74856
74866
  private: false,
74857
74867
  license: "MIT",
@@ -86704,7 +86714,7 @@ init_ai_edit();
86704
86714
  init_output();
86705
86715
  import { resolve as resolve71 } from "node:path";
86706
86716
  import { existsSync as existsSync52 } from "node:fs";
86707
- import { mkdir as mkdir27, rm as rm4 } from "node:fs/promises";
86717
+ import { mkdir as mkdir27, rm as rm5 } from "node:fs/promises";
86708
86718
  var DEMO_DIR = resolve71(process.cwd(), ".vibeframe-demo");
86709
86719
  async function generateTestVideo(outputPath) {
86710
86720
  const filter = [
@@ -86894,7 +86904,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
86894
86904
  }
86895
86905
  if (!options.keep) {
86896
86906
  try {
86897
- await rm4(DEMO_DIR, { recursive: true, force: true });
86907
+ await rm5(DEMO_DIR, { recursive: true, force: true });
86898
86908
  } catch {
86899
86909
  }
86900
86910
  }
@@ -34576,7 +34576,7 @@ __export(scene_build_exports, {
34576
34576
  resolveSceneBuildMode: () => resolveSceneBuildMode
34577
34577
  });
34578
34578
  import { existsSync as existsSync19, readFileSync as readFileSync3 } from "node:fs";
34579
- import { copyFile as copyFile3, mkdir as mkdir10, readFile as readFile18, writeFile as writeFile18 } from "node:fs/promises";
34579
+ import { copyFile as copyFile3, mkdir as mkdir10, readFile as readFile18, rm, writeFile as writeFile18 } from "node:fs/promises";
34580
34580
  import { dirname as dirname10, join as join16, resolve as resolve25 } from "node:path";
34581
34581
  async function executeSceneBuild(opts) {
34582
34582
  const startedAt = Date.now();
@@ -34584,9 +34584,9 @@ async function executeSceneBuild(opts) {
34584
34584
  const onProgress = opts.onProgress ?? (() => {
34585
34585
  });
34586
34586
  const mode = resolveSceneBuildMode(opts);
34587
- let selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
34587
+ const selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
34588
34588
  const skipVideoStopsRender = (opts.skipVideo ?? false) && (selectedStage === "all" || selectedStage === "render");
34589
- if (skipVideoStopsRender) selectedStage = "sync";
34589
+ const effectiveSkipRender = (opts.skipRender ?? false) || skipVideoStopsRender;
34590
34590
  const stageReports = createEmptyStageReports();
34591
34591
  const warnings = [];
34592
34592
  const retryWith = [];
@@ -35082,7 +35082,7 @@ async function executeSceneBuild(opts) {
35082
35082
  });
35083
35083
  }
35084
35084
  }
35085
- if (selectedStage === "sync" || opts.skipRender) {
35085
+ if (selectedStage === "sync" || effectiveSkipRender) {
35086
35086
  return finishBuildResult({
35087
35087
  success: true,
35088
35088
  phase: "sync-only",
@@ -35374,6 +35374,10 @@ async function dispatchNarration(beat, ctx) {
35374
35374
  }
35375
35375
  await mkdir10(dirname10(abs), { recursive: true });
35376
35376
  await writeFile18(abs, result.audioBuffer);
35377
+ for (const otherExt of ["mp3", "wav"]) {
35378
+ const sibling = join16(ctx.projectDir, `assets/narration-${beat.id}.${otherExt}`);
35379
+ if (sibling !== abs && existsSync19(sibling)) await rm(sibling, { force: true });
35380
+ }
35377
35381
  await mkdir10(dirname10(cacheAbs), { recursive: true });
35378
35382
  await writeFile18(cacheAbs, result.audioBuffer);
35379
35383
  await writeAssetMetadata({
@@ -35406,11 +35410,12 @@ async function dispatchNarration(beat, ctx) {
35406
35410
  }
35407
35411
  function characterSheetPrompt(name, description) {
35408
35412
  return [
35409
- `Character turnaround reference sheet of an original fictional character named ${name}: ${description}.`,
35410
- "Show three full-body views side by side on one clean canvas \u2014 front view, side profile, and back view \u2014",
35411
- "with identical outfit, hairstyle, hair color, and body proportions across all three views.",
35413
+ `Character reference sheet of an original fictional character named ${name}: ${description}.`,
35414
+ "Top row: ONE large, sharp, evenly-lit frontal close-up of the FACE (head and shoulders) as the primary identity anchor \u2014 clear eyes, nose, jawline, and skin detail.",
35415
+ "Bottom row: three full-body views side by side \u2014 front, side profile, and back.",
35416
+ "The face, facial features, hairstyle, hair color, outfit, and body proportions must be IDENTICAL across the close-up and all three views.",
35412
35417
  "Plain light-grey studio background, even neutral lighting, no props.",
35413
- "Photorealistic digital character, professional concept-art character sheet layout."
35418
+ "Photorealistic, professional concept-art character sheet layout."
35414
35419
  ].join(" ");
35415
35420
  }
35416
35421
  async function buildCharacters(characters, ctx) {
@@ -35749,7 +35754,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
35749
35754
  imageSize: size,
35750
35755
  imageQuality: ctx.imageQuality
35751
35756
  };
35752
- const generated = sheetBuffers.length > 0 ? await editKeyframeImage(keyframeCue, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
35757
+ const identityLock = "Keep the EXACT same person and face as the reference image(s): identical facial features (eyes, nose shape, jawline), skin tone and complexion, hairstyle, hair color, and wardrobe. Do not restyle or change the face. Change only the scene, pose, framing, and lighting. ";
35758
+ const generated = sheetBuffers.length > 0 ? await editKeyframeImage(`${identityLock}${keyframeCue}`, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
35753
35759
  if (!generated.success) return { status: "failed", error: generated.error };
35754
35760
  await mkdir10(dirname10(abs), { recursive: true });
35755
35761
  await writeFile18(abs, generated.buffer);
@@ -35891,6 +35897,10 @@ async function dispatchVideo(beat, ctx, keyframe) {
35891
35897
  // reference-to-video.
35892
35898
  image: keyframeImageAbs,
35893
35899
  refImages: keyframeImageAbs ? void 0 : characterRefsAbs.length > 0 ? characterRefsAbs : void 0,
35900
+ // Build clips are always muted in the composition (a separate narration/music
35901
+ // track carries audio), so the model's generated audio is never used. Disable
35902
+ // it: it's wasted, and Seedance's audio moderation can spuriously fail a beat.
35903
+ generateAudio: false,
35894
35904
  apiKey: await apiKeyForVideoProvider(ctx.videoProvider, ctx.projectDir)
35895
35905
  });
35896
35906
  if (!result.success || !result.taskId) {
@@ -37419,8 +37429,8 @@ async function executeJumpCut(options) {
37419
37429
  };
37420
37430
  } finally {
37421
37431
  try {
37422
- const { rm: rm4 } = await import("node:fs/promises");
37423
- await rm4(tmpDir, { recursive: true, force: true });
37432
+ const { rm: rm5 } = await import("node:fs/promises");
37433
+ await rm5(tmpDir, { recursive: true, force: true });
37424
37434
  } catch {
37425
37435
  }
37426
37436
  }
@@ -37497,7 +37507,7 @@ __export(remotion_exports, {
37497
37507
  wrapComponentWithImage: () => wrapComponentWithImage,
37498
37508
  wrapComponentWithVideo: () => wrapComponentWithVideo
37499
37509
  });
37500
- import { writeFile as writeFile21, mkdir as mkdir12, rm, copyFile as copyFile4 } from "node:fs/promises";
37510
+ import { writeFile as writeFile21, mkdir as mkdir12, rm as rm2, copyFile as copyFile4 } from "node:fs/promises";
37501
37511
  import { existsSync as existsSync23 } from "node:fs";
37502
37512
  import { join as join18 } from "node:path";
37503
37513
  import { tmpdir } from "node:os";
@@ -37691,7 +37701,7 @@ async function renderMotion(options) {
37691
37701
  stderr: ${stderr}` : ""}`);
37692
37702
  return { success: false, error: `Remotion render failed: ${msg}` };
37693
37703
  } finally {
37694
- await rm(dir, { recursive: true, force: true }).catch(() => {
37704
+ await rm2(dir, { recursive: true, force: true }).catch(() => {
37695
37705
  });
37696
37706
  }
37697
37707
  }
@@ -37783,7 +37793,7 @@ async function renderWithEmbeddedImage(options) {
37783
37793
  const msg = error instanceof Error ? error.message : String(error);
37784
37794
  return { success: false, error: `Remotion image embed render failed: ${msg}` };
37785
37795
  } finally {
37786
- await rm(dir, { recursive: true, force: true }).catch(() => {
37796
+ await rm2(dir, { recursive: true, force: true }).catch(() => {
37787
37797
  });
37788
37798
  }
37789
37799
  }
@@ -37860,14 +37870,14 @@ async function renderWithEmbeddedVideo(options) {
37860
37870
  "-shortest",
37861
37871
  mp4Out
37862
37872
  ], { timeout: 12e4 });
37863
- await rm(mp4VideoOnly, { force: true }).catch(() => {
37873
+ await rm2(mp4VideoOnly, { force: true }).catch(() => {
37864
37874
  });
37865
37875
  return { success: true, outputPath: mp4Out };
37866
37876
  } catch (error) {
37867
37877
  const msg = error instanceof Error ? error.message : String(error);
37868
37878
  return { success: false, error: `Remotion video embed render failed: ${msg}` };
37869
37879
  } finally {
37870
- await rm(dir, { recursive: true, force: true }).catch(() => {
37880
+ await rm2(dir, { recursive: true, force: true }).catch(() => {
37871
37881
  });
37872
37882
  }
37873
37883
  }
@@ -38431,8 +38441,8 @@ SRT saved to: ${outputSrtPath2}`
38431
38441
  };
38432
38442
  } finally {
38433
38443
  try {
38434
- const { rm: rm4 } = await import("node:fs/promises");
38435
- await rm4(tmpDir, { recursive: true, force: true });
38444
+ const { rm: rm5 } = await import("node:fs/promises");
38445
+ await rm5(tmpDir, { recursive: true, force: true });
38436
38446
  } catch {
38437
38447
  }
38438
38448
  }
@@ -41051,7 +41061,7 @@ __export(project_builder_exports, {
41051
41061
  buildTempProject: () => buildTempProject,
41052
41062
  resolveSourceUrl: () => resolveSourceUrl
41053
41063
  });
41054
- import { mkdtemp, mkdir as mkdir15, copyFile as copyFile5, writeFile as writeFile26, rm as rm2, readdir as readdir3 } from "node:fs/promises";
41064
+ import { mkdtemp, mkdir as mkdir15, copyFile as copyFile5, writeFile as writeFile26, rm as rm3, readdir as readdir3 } from "node:fs/promises";
41055
41065
  import { existsSync as existsSync32 } from "node:fs";
41056
41066
  import { tmpdir as tmpdir2 } from "node:os";
41057
41067
  import { createRequire } from "node:module";
@@ -41078,7 +41088,7 @@ async function buildTempProject(state, projectFileDir) {
41078
41088
  await writeFile26(path.join(dir, "index.html"), html, "utf-8");
41079
41089
  return {
41080
41090
  dir,
41081
- cleanup: () => rm2(dir, { recursive: true, force: true })
41091
+ cleanup: () => rm3(dir, { recursive: true, force: true })
41082
41092
  };
41083
41093
  }
41084
41094
  async function copyLottieRuntime(tempDir) {
@@ -55382,7 +55392,7 @@ init_api_key();
55382
55392
  init_exec_safe();
55383
55393
  init_remotion();
55384
55394
  import { resolve as resolve36, dirname as dirname17, basename as basename10 } from "node:path";
55385
- import { writeFile as writeFile28, mkdir as mkdir18, rm as rm3 } from "node:fs/promises";
55395
+ import { writeFile as writeFile28, mkdir as mkdir18, rm as rm4 } from "node:fs/promises";
55386
55396
  import { existsSync as existsSync34 } from "node:fs";
55387
55397
  import { tmpdir as tmpdir3 } from "node:os";
55388
55398
  var ASS_STYLES = ["karaoke-sweep", "typewriter"];
@@ -55551,13 +55561,13 @@ async function executeAnimatedCaption(options) {
55551
55561
  ], { timeout: 12e4 });
55552
55562
  const apiKey = await getApiKey("OPENAI_API_KEY", "OpenAI");
55553
55563
  if (!apiKey) {
55554
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55564
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55555
55565
  });
55556
55566
  return { success: false, error: "OPENAI_API_KEY required for Whisper transcription. Run 'vibe setup' or set OPENAI_API_KEY in .env" };
55557
55567
  }
55558
55568
  const transcript = await transcribeWithWords(audioPath, apiKey, language);
55559
55569
  if (!transcript.words || transcript.words.length === 0) {
55560
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55570
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55561
55571
  });
55562
55572
  return { success: false, error: "No words detected in transcription" };
55563
55573
  }
@@ -55611,12 +55621,12 @@ async function executeAnimatedCaption(options) {
55611
55621
  outputPath: absOutputPath
55612
55622
  });
55613
55623
  if (!renderResult.success) {
55614
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55624
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55615
55625
  });
55616
55626
  return { success: false, error: renderResult.error };
55617
55627
  }
55618
55628
  }
55619
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55629
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55620
55630
  });
55621
55631
  return {
55622
55632
  success: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeframe/cli",
3
- "version": "0.113.5",
3
+ "version": "0.113.7",
4
4
  "description": "VibeFrame CLI - agentic video workflow runtime",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -83,8 +83,8 @@
83
83
  "tsx": "^4.21.0",
84
84
  "typescript": "^5.3.3",
85
85
  "vitest": "^1.2.2",
86
- "@vibeframe/ai-providers": "0.113.5",
87
- "@vibeframe/core": "0.113.5"
86
+ "@vibeframe/ai-providers": "0.113.7",
87
+ "@vibeframe/core": "0.113.7"
88
88
  },
89
89
  "engines": {
90
90
  "node": ">=20"