@vibeframe/cli 0.113.4 → 0.113.6

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();
@@ -62091,9 +62091,16 @@ async function executeSceneBuild(opts) {
62091
62091
  });
62092
62092
  const mode = resolveSceneBuildMode(opts);
62093
62093
  const selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
62094
+ const skipVideoStopsRender = (opts.skipVideo ?? false) && (selectedStage === "all" || selectedStage === "render");
62095
+ const effectiveSkipRender = (opts.skipRender ?? false) || skipVideoStopsRender;
62094
62096
  const stageReports = createEmptyStageReports();
62095
62097
  const warnings = [];
62096
62098
  const retryWith = [];
62099
+ if (skipVideoStopsRender) {
62100
+ warnings.push(
62101
+ "--skip-video: skipped render (no clips to capture). Review assets/keyframe-*.png, then build without --skip-video to animate them."
62102
+ );
62103
+ }
62097
62104
  let sceneRepair = skippedSceneRepairSummary();
62098
62105
  const storyboardPath2 = join25(projectDir, "STORYBOARD.md");
62099
62106
  const buildPlan = await createBuildPlan({
@@ -62253,7 +62260,7 @@ async function executeSceneBuild(opts) {
62253
62260
  if (shouldRunStage(selectedStage, "assets")) {
62254
62261
  onProgress({ type: "phase-start", phase: "primitives" });
62255
62262
  const characterPaths = /* @__PURE__ */ new Map();
62256
- if (!(opts.skipVideo ?? false)) {
62263
+ if (!((opts.skipVideo ?? false) && (opts.skipKeyframe ?? false))) {
62257
62264
  const referenced = /* @__PURE__ */ new Set();
62258
62265
  for (const beat of activeBeats) {
62259
62266
  for (const name of beatCharacterNames(beat.cues)) referenced.add(name);
@@ -62581,7 +62588,7 @@ async function executeSceneBuild(opts) {
62581
62588
  });
62582
62589
  }
62583
62590
  }
62584
- if (selectedStage === "sync" || opts.skipRender) {
62591
+ if (selectedStage === "sync" || effectiveSkipRender) {
62585
62592
  return finishBuildResult({
62586
62593
  success: true,
62587
62594
  phase: "sync-only",
@@ -62873,6 +62880,10 @@ async function dispatchNarration(beat, ctx) {
62873
62880
  }
62874
62881
  await mkdir26(dirname24(abs), { recursive: true });
62875
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
+ }
62876
62887
  await mkdir26(dirname24(cacheAbs), { recursive: true });
62877
62888
  await writeFile50(cacheAbs, result.audioBuffer);
62878
62889
  await writeAssetMetadata({
@@ -62905,11 +62916,12 @@ async function dispatchNarration(beat, ctx) {
62905
62916
  }
62906
62917
  function characterSheetPrompt(name, description) {
62907
62918
  return [
62908
- `Character turnaround reference sheet of an original fictional character named ${name}: ${description}.`,
62909
- "Show three full-body views side by side on one clean canvas \u2014 front view, side profile, and back view \u2014",
62910
- "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.",
62911
62923
  "Plain light-grey studio background, even neutral lighting, no props.",
62912
- "Photorealistic digital character, professional concept-art character sheet layout."
62924
+ "Photorealistic, professional concept-art character sheet layout."
62913
62925
  ].join(" ");
62914
62926
  }
62915
62927
  async function buildCharacters(characters, ctx) {
@@ -63248,7 +63260,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
63248
63260
  imageSize: size,
63249
63261
  imageQuality: ctx.imageQuality
63250
63262
  };
63251
- 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);
63252
63265
  if (!generated.success) return { status: "failed", error: generated.error };
63253
63266
  await mkdir26(dirname24(abs), { recursive: true });
63254
63267
  await writeFile50(abs, generated.buffer);
@@ -74844,7 +74857,7 @@ init_source();
74844
74857
  // package.json
74845
74858
  var package_default = {
74846
74859
  name: "@vibeframe/cli",
74847
- version: "0.113.4",
74860
+ version: "0.113.6",
74848
74861
  description: "VibeFrame CLI - agentic video workflow runtime",
74849
74862
  private: false,
74850
74863
  license: "MIT",
@@ -86697,7 +86710,7 @@ init_ai_edit();
86697
86710
  init_output();
86698
86711
  import { resolve as resolve71 } from "node:path";
86699
86712
  import { existsSync as existsSync52 } from "node:fs";
86700
- import { mkdir as mkdir27, rm as rm4 } from "node:fs/promises";
86713
+ import { mkdir as mkdir27, rm as rm5 } from "node:fs/promises";
86701
86714
  var DEMO_DIR = resolve71(process.cwd(), ".vibeframe-demo");
86702
86715
  async function generateTestVideo(outputPath) {
86703
86716
  const filter = [
@@ -86887,7 +86900,7 @@ var demoCommand = new Command("demo").description("Run sample edits on a test vi
86887
86900
  }
86888
86901
  if (!options.keep) {
86889
86902
  try {
86890
- await rm4(DEMO_DIR, { recursive: true, force: true });
86903
+ await rm5(DEMO_DIR, { recursive: true, force: true });
86891
86904
  } catch {
86892
86905
  }
86893
86906
  }
@@ -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();
@@ -34585,9 +34585,16 @@ async function executeSceneBuild(opts) {
34585
34585
  });
34586
34586
  const mode = resolveSceneBuildMode(opts);
34587
34587
  const selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
34588
+ const skipVideoStopsRender = (opts.skipVideo ?? false) && (selectedStage === "all" || selectedStage === "render");
34589
+ const effectiveSkipRender = (opts.skipRender ?? false) || skipVideoStopsRender;
34588
34590
  const stageReports = createEmptyStageReports();
34589
34591
  const warnings = [];
34590
34592
  const retryWith = [];
34593
+ if (skipVideoStopsRender) {
34594
+ warnings.push(
34595
+ "--skip-video: skipped render (no clips to capture). Review assets/keyframe-*.png, then build without --skip-video to animate them."
34596
+ );
34597
+ }
34591
34598
  let sceneRepair = skippedSceneRepairSummary();
34592
34599
  const storyboardPath = join16(projectDir, "STORYBOARD.md");
34593
34600
  const buildPlan = await createBuildPlan({
@@ -34747,7 +34754,7 @@ async function executeSceneBuild(opts) {
34747
34754
  if (shouldRunStage(selectedStage, "assets")) {
34748
34755
  onProgress({ type: "phase-start", phase: "primitives" });
34749
34756
  const characterPaths = /* @__PURE__ */ new Map();
34750
- if (!(opts.skipVideo ?? false)) {
34757
+ if (!((opts.skipVideo ?? false) && (opts.skipKeyframe ?? false))) {
34751
34758
  const referenced = /* @__PURE__ */ new Set();
34752
34759
  for (const beat of activeBeats) {
34753
34760
  for (const name of beatCharacterNames(beat.cues)) referenced.add(name);
@@ -35075,7 +35082,7 @@ async function executeSceneBuild(opts) {
35075
35082
  });
35076
35083
  }
35077
35084
  }
35078
- if (selectedStage === "sync" || opts.skipRender) {
35085
+ if (selectedStage === "sync" || effectiveSkipRender) {
35079
35086
  return finishBuildResult({
35080
35087
  success: true,
35081
35088
  phase: "sync-only",
@@ -35367,6 +35374,10 @@ async function dispatchNarration(beat, ctx) {
35367
35374
  }
35368
35375
  await mkdir10(dirname10(abs), { recursive: true });
35369
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
+ }
35370
35381
  await mkdir10(dirname10(cacheAbs), { recursive: true });
35371
35382
  await writeFile18(cacheAbs, result.audioBuffer);
35372
35383
  await writeAssetMetadata({
@@ -35399,11 +35410,12 @@ async function dispatchNarration(beat, ctx) {
35399
35410
  }
35400
35411
  function characterSheetPrompt(name, description) {
35401
35412
  return [
35402
- `Character turnaround reference sheet of an original fictional character named ${name}: ${description}.`,
35403
- "Show three full-body views side by side on one clean canvas \u2014 front view, side profile, and back view \u2014",
35404
- "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.",
35405
35417
  "Plain light-grey studio background, even neutral lighting, no props.",
35406
- "Photorealistic digital character, professional concept-art character sheet layout."
35418
+ "Photorealistic, professional concept-art character sheet layout."
35407
35419
  ].join(" ");
35408
35420
  }
35409
35421
  async function buildCharacters(characters, ctx) {
@@ -35742,7 +35754,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
35742
35754
  imageSize: size,
35743
35755
  imageQuality: ctx.imageQuality
35744
35756
  };
35745
- 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);
35746
35759
  if (!generated.success) return { status: "failed", error: generated.error };
35747
35760
  await mkdir10(dirname10(abs), { recursive: true });
35748
35761
  await writeFile18(abs, generated.buffer);
@@ -37412,8 +37425,8 @@ async function executeJumpCut(options) {
37412
37425
  };
37413
37426
  } finally {
37414
37427
  try {
37415
- const { rm: rm4 } = await import("node:fs/promises");
37416
- await rm4(tmpDir, { recursive: true, force: true });
37428
+ const { rm: rm5 } = await import("node:fs/promises");
37429
+ await rm5(tmpDir, { recursive: true, force: true });
37417
37430
  } catch {
37418
37431
  }
37419
37432
  }
@@ -37490,7 +37503,7 @@ __export(remotion_exports, {
37490
37503
  wrapComponentWithImage: () => wrapComponentWithImage,
37491
37504
  wrapComponentWithVideo: () => wrapComponentWithVideo
37492
37505
  });
37493
- import { writeFile as writeFile21, mkdir as mkdir12, rm, copyFile as copyFile4 } from "node:fs/promises";
37506
+ import { writeFile as writeFile21, mkdir as mkdir12, rm as rm2, copyFile as copyFile4 } from "node:fs/promises";
37494
37507
  import { existsSync as existsSync23 } from "node:fs";
37495
37508
  import { join as join18 } from "node:path";
37496
37509
  import { tmpdir } from "node:os";
@@ -37684,7 +37697,7 @@ async function renderMotion(options) {
37684
37697
  stderr: ${stderr}` : ""}`);
37685
37698
  return { success: false, error: `Remotion render failed: ${msg}` };
37686
37699
  } finally {
37687
- await rm(dir, { recursive: true, force: true }).catch(() => {
37700
+ await rm2(dir, { recursive: true, force: true }).catch(() => {
37688
37701
  });
37689
37702
  }
37690
37703
  }
@@ -37776,7 +37789,7 @@ async function renderWithEmbeddedImage(options) {
37776
37789
  const msg = error instanceof Error ? error.message : String(error);
37777
37790
  return { success: false, error: `Remotion image embed render failed: ${msg}` };
37778
37791
  } finally {
37779
- await rm(dir, { recursive: true, force: true }).catch(() => {
37792
+ await rm2(dir, { recursive: true, force: true }).catch(() => {
37780
37793
  });
37781
37794
  }
37782
37795
  }
@@ -37853,14 +37866,14 @@ async function renderWithEmbeddedVideo(options) {
37853
37866
  "-shortest",
37854
37867
  mp4Out
37855
37868
  ], { timeout: 12e4 });
37856
- await rm(mp4VideoOnly, { force: true }).catch(() => {
37869
+ await rm2(mp4VideoOnly, { force: true }).catch(() => {
37857
37870
  });
37858
37871
  return { success: true, outputPath: mp4Out };
37859
37872
  } catch (error) {
37860
37873
  const msg = error instanceof Error ? error.message : String(error);
37861
37874
  return { success: false, error: `Remotion video embed render failed: ${msg}` };
37862
37875
  } finally {
37863
- await rm(dir, { recursive: true, force: true }).catch(() => {
37876
+ await rm2(dir, { recursive: true, force: true }).catch(() => {
37864
37877
  });
37865
37878
  }
37866
37879
  }
@@ -38424,8 +38437,8 @@ SRT saved to: ${outputSrtPath2}`
38424
38437
  };
38425
38438
  } finally {
38426
38439
  try {
38427
- const { rm: rm4 } = await import("node:fs/promises");
38428
- await rm4(tmpDir, { recursive: true, force: true });
38440
+ const { rm: rm5 } = await import("node:fs/promises");
38441
+ await rm5(tmpDir, { recursive: true, force: true });
38429
38442
  } catch {
38430
38443
  }
38431
38444
  }
@@ -41044,7 +41057,7 @@ __export(project_builder_exports, {
41044
41057
  buildTempProject: () => buildTempProject,
41045
41058
  resolveSourceUrl: () => resolveSourceUrl
41046
41059
  });
41047
- import { mkdtemp, mkdir as mkdir15, copyFile as copyFile5, writeFile as writeFile26, rm as rm2, readdir as readdir3 } from "node:fs/promises";
41060
+ import { mkdtemp, mkdir as mkdir15, copyFile as copyFile5, writeFile as writeFile26, rm as rm3, readdir as readdir3 } from "node:fs/promises";
41048
41061
  import { existsSync as existsSync32 } from "node:fs";
41049
41062
  import { tmpdir as tmpdir2 } from "node:os";
41050
41063
  import { createRequire } from "node:module";
@@ -41071,7 +41084,7 @@ async function buildTempProject(state, projectFileDir) {
41071
41084
  await writeFile26(path.join(dir, "index.html"), html, "utf-8");
41072
41085
  return {
41073
41086
  dir,
41074
- cleanup: () => rm2(dir, { recursive: true, force: true })
41087
+ cleanup: () => rm3(dir, { recursive: true, force: true })
41075
41088
  };
41076
41089
  }
41077
41090
  async function copyLottieRuntime(tempDir) {
@@ -55375,7 +55388,7 @@ init_api_key();
55375
55388
  init_exec_safe();
55376
55389
  init_remotion();
55377
55390
  import { resolve as resolve36, dirname as dirname17, basename as basename10 } from "node:path";
55378
- import { writeFile as writeFile28, mkdir as mkdir18, rm as rm3 } from "node:fs/promises";
55391
+ import { writeFile as writeFile28, mkdir as mkdir18, rm as rm4 } from "node:fs/promises";
55379
55392
  import { existsSync as existsSync34 } from "node:fs";
55380
55393
  import { tmpdir as tmpdir3 } from "node:os";
55381
55394
  var ASS_STYLES = ["karaoke-sweep", "typewriter"];
@@ -55544,13 +55557,13 @@ async function executeAnimatedCaption(options) {
55544
55557
  ], { timeout: 12e4 });
55545
55558
  const apiKey = await getApiKey("OPENAI_API_KEY", "OpenAI");
55546
55559
  if (!apiKey) {
55547
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55560
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55548
55561
  });
55549
55562
  return { success: false, error: "OPENAI_API_KEY required for Whisper transcription. Run 'vibe setup' or set OPENAI_API_KEY in .env" };
55550
55563
  }
55551
55564
  const transcript = await transcribeWithWords(audioPath, apiKey, language);
55552
55565
  if (!transcript.words || transcript.words.length === 0) {
55553
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55566
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55554
55567
  });
55555
55568
  return { success: false, error: "No words detected in transcription" };
55556
55569
  }
@@ -55604,12 +55617,12 @@ async function executeAnimatedCaption(options) {
55604
55617
  outputPath: absOutputPath
55605
55618
  });
55606
55619
  if (!renderResult.success) {
55607
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55620
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55608
55621
  });
55609
55622
  return { success: false, error: renderResult.error };
55610
55623
  }
55611
55624
  }
55612
- await rm3(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55625
+ await rm4(tmpAudioDir, { recursive: true, force: true }).catch(() => {
55613
55626
  });
55614
55627
  return {
55615
55628
  success: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeframe/cli",
3
- "version": "0.113.4",
3
+ "version": "0.113.6",
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.4",
87
- "@vibeframe/core": "0.113.4"
86
+ "@vibeframe/ai-providers": "0.113.6",
87
+ "@vibeframe/core": "0.113.6"
88
88
  },
89
89
  "engines": {
90
90
  "node": ">=20"