@vibeframe/mcp-server 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.
Files changed (2) hide show
  1. package/dist/index.js +38 -25
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -473791,7 +473791,7 @@ __export(scene_build_exports, {
473791
473791
  resolveSceneBuildMode: () => resolveSceneBuildMode
473792
473792
  });
473793
473793
  import { existsSync as existsSync35, readFileSync as readFileSync12 } from "node:fs";
473794
- import { copyFile as copyFile4, mkdir as mkdir13, readFile as readFile18, writeFile as writeFile20 } from "node:fs/promises";
473794
+ import { copyFile as copyFile4, mkdir as mkdir13, readFile as readFile18, rm as rm3, writeFile as writeFile20 } from "node:fs/promises";
473795
473795
  import { dirname as dirname18, join as join31, resolve as resolve33 } from "node:path";
473796
473796
  async function executeSceneBuild(opts) {
473797
473797
  const startedAt = Date.now();
@@ -473800,9 +473800,16 @@ async function executeSceneBuild(opts) {
473800
473800
  });
473801
473801
  const mode = resolveSceneBuildMode(opts);
473802
473802
  const selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
473803
+ const skipVideoStopsRender = (opts.skipVideo ?? false) && (selectedStage === "all" || selectedStage === "render");
473804
+ const effectiveSkipRender = (opts.skipRender ?? false) || skipVideoStopsRender;
473803
473805
  const stageReports = createEmptyStageReports();
473804
473806
  const warnings = [];
473805
473807
  const retryWith = [];
473808
+ if (skipVideoStopsRender) {
473809
+ warnings.push(
473810
+ "--skip-video: skipped render (no clips to capture). Review assets/keyframe-*.png, then build without --skip-video to animate them."
473811
+ );
473812
+ }
473806
473813
  let sceneRepair = skippedSceneRepairSummary();
473807
473814
  const storyboardPath = join31(projectDir, "STORYBOARD.md");
473808
473815
  const buildPlan = await createBuildPlan({
@@ -473962,7 +473969,7 @@ async function executeSceneBuild(opts) {
473962
473969
  if (shouldRunStage(selectedStage, "assets")) {
473963
473970
  onProgress({ type: "phase-start", phase: "primitives" });
473964
473971
  const characterPaths = /* @__PURE__ */ new Map();
473965
- if (!(opts.skipVideo ?? false)) {
473972
+ if (!((opts.skipVideo ?? false) && (opts.skipKeyframe ?? false))) {
473966
473973
  const referenced = /* @__PURE__ */ new Set();
473967
473974
  for (const beat of activeBeats) {
473968
473975
  for (const name of beatCharacterNames(beat.cues)) referenced.add(name);
@@ -474290,7 +474297,7 @@ async function executeSceneBuild(opts) {
474290
474297
  });
474291
474298
  }
474292
474299
  }
474293
- if (selectedStage === "sync" || opts.skipRender) {
474300
+ if (selectedStage === "sync" || effectiveSkipRender) {
474294
474301
  return finishBuildResult({
474295
474302
  success: true,
474296
474303
  phase: "sync-only",
@@ -474582,6 +474589,10 @@ async function dispatchNarration(beat, ctx) {
474582
474589
  }
474583
474590
  await mkdir13(dirname18(abs), { recursive: true });
474584
474591
  await writeFile20(abs, result.audioBuffer);
474592
+ for (const otherExt of ["mp3", "wav"]) {
474593
+ const sibling = join31(ctx.projectDir, `assets/narration-${beat.id}.${otherExt}`);
474594
+ if (sibling !== abs && existsSync35(sibling)) await rm3(sibling, { force: true });
474595
+ }
474585
474596
  await mkdir13(dirname18(cacheAbs), { recursive: true });
474586
474597
  await writeFile20(cacheAbs, result.audioBuffer);
474587
474598
  await writeAssetMetadata({
@@ -474614,11 +474625,12 @@ async function dispatchNarration(beat, ctx) {
474614
474625
  }
474615
474626
  function characterSheetPrompt(name, description) {
474616
474627
  return [
474617
- `Character turnaround reference sheet of an original fictional character named ${name}: ${description}.`,
474618
- "Show three full-body views side by side on one clean canvas \u2014 front view, side profile, and back view \u2014",
474619
- "with identical outfit, hairstyle, hair color, and body proportions across all three views.",
474628
+ `Character reference sheet of an original fictional character named ${name}: ${description}.`,
474629
+ "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.",
474630
+ "Bottom row: three full-body views side by side \u2014 front, side profile, and back.",
474631
+ "The face, facial features, hairstyle, hair color, outfit, and body proportions must be IDENTICAL across the close-up and all three views.",
474620
474632
  "Plain light-grey studio background, even neutral lighting, no props.",
474621
- "Photorealistic digital character, professional concept-art character sheet layout."
474633
+ "Photorealistic, professional concept-art character sheet layout."
474622
474634
  ].join(" ");
474623
474635
  }
474624
474636
  async function buildCharacters(characters, ctx) {
@@ -474957,7 +474969,8 @@ async function ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel) {
474957
474969
  imageSize: size,
474958
474970
  imageQuality: ctx.imageQuality
474959
474971
  };
474960
- const generated = sheetBuffers.length > 0 ? await editKeyframeImage(keyframeCue, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
474972
+ 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. ";
474973
+ const generated = sheetBuffers.length > 0 ? await editKeyframeImage(`${identityLock}${keyframeCue}`, sheetBuffers, imgCtx, ratio) : await generateBackdropImage(keyframeCue, imgCtx, ratio);
474961
474974
  if (!generated.success) return { status: "failed", error: generated.error };
474962
474975
  await mkdir13(dirname18(abs), { recursive: true });
474963
474976
  await writeFile20(abs, generated.buffer);
@@ -476627,8 +476640,8 @@ async function executeJumpCut(options) {
476627
476640
  };
476628
476641
  } finally {
476629
476642
  try {
476630
- const { rm: rm6 } = await import("node:fs/promises");
476631
- await rm6(tmpDir, { recursive: true, force: true });
476643
+ const { rm: rm7 } = await import("node:fs/promises");
476644
+ await rm7(tmpDir, { recursive: true, force: true });
476632
476645
  } catch {
476633
476646
  }
476634
476647
  }
@@ -476705,7 +476718,7 @@ __export(remotion_exports, {
476705
476718
  wrapComponentWithImage: () => wrapComponentWithImage,
476706
476719
  wrapComponentWithVideo: () => wrapComponentWithVideo
476707
476720
  });
476708
- import { writeFile as writeFile23, mkdir as mkdir15, rm as rm3, copyFile as copyFile5 } from "node:fs/promises";
476721
+ import { writeFile as writeFile23, mkdir as mkdir15, rm as rm4, copyFile as copyFile5 } from "node:fs/promises";
476709
476722
  import { existsSync as existsSync39 } from "node:fs";
476710
476723
  import { join as join34 } from "node:path";
476711
476724
  import { tmpdir as tmpdir3 } from "node:os";
@@ -476899,7 +476912,7 @@ async function renderMotion(options) {
476899
476912
  stderr: ${stderr}` : ""}`);
476900
476913
  return { success: false, error: `Remotion render failed: ${msg}` };
476901
476914
  } finally {
476902
- await rm3(dir, { recursive: true, force: true }).catch(() => {
476915
+ await rm4(dir, { recursive: true, force: true }).catch(() => {
476903
476916
  });
476904
476917
  }
476905
476918
  }
@@ -476991,7 +477004,7 @@ async function renderWithEmbeddedImage(options) {
476991
477004
  const msg = error instanceof Error ? error.message : String(error);
476992
477005
  return { success: false, error: `Remotion image embed render failed: ${msg}` };
476993
477006
  } finally {
476994
- await rm3(dir, { recursive: true, force: true }).catch(() => {
477007
+ await rm4(dir, { recursive: true, force: true }).catch(() => {
476995
477008
  });
476996
477009
  }
476997
477010
  }
@@ -477068,14 +477081,14 @@ async function renderWithEmbeddedVideo(options) {
477068
477081
  "-shortest",
477069
477082
  mp4Out
477070
477083
  ], { timeout: 12e4 });
477071
- await rm3(mp4VideoOnly, { force: true }).catch(() => {
477084
+ await rm4(mp4VideoOnly, { force: true }).catch(() => {
477072
477085
  });
477073
477086
  return { success: true, outputPath: mp4Out };
477074
477087
  } catch (error) {
477075
477088
  const msg = error instanceof Error ? error.message : String(error);
477076
477089
  return { success: false, error: `Remotion video embed render failed: ${msg}` };
477077
477090
  } finally {
477078
- await rm3(dir, { recursive: true, force: true }).catch(() => {
477091
+ await rm4(dir, { recursive: true, force: true }).catch(() => {
477079
477092
  });
477080
477093
  }
477081
477094
  }
@@ -477639,8 +477652,8 @@ SRT saved to: ${outputSrtPath2}`
477639
477652
  };
477640
477653
  } finally {
477641
477654
  try {
477642
- const { rm: rm6 } = await import("node:fs/promises");
477643
- await rm6(tmpDir, { recursive: true, force: true });
477655
+ const { rm: rm7 } = await import("node:fs/promises");
477656
+ await rm7(tmpDir, { recursive: true, force: true });
477644
477657
  } catch {
477645
477658
  }
477646
477659
  }
@@ -480258,7 +480271,7 @@ __export(project_builder_exports, {
480258
480271
  buildTempProject: () => buildTempProject,
480259
480272
  resolveSourceUrl: () => resolveSourceUrl
480260
480273
  });
480261
- import { mkdtemp as mkdtemp4, mkdir as mkdir18, copyFile as copyFile6, writeFile as writeFile28, rm as rm4, readdir as readdir5 } from "node:fs/promises";
480274
+ import { mkdtemp as mkdtemp4, mkdir as mkdir18, copyFile as copyFile6, writeFile as writeFile28, rm as rm5, readdir as readdir5 } from "node:fs/promises";
480262
480275
  import { existsSync as existsSync49 } from "node:fs";
480263
480276
  import { tmpdir as tmpdir4 } from "node:os";
480264
480277
  import { createRequire } from "node:module";
@@ -480285,7 +480298,7 @@ async function buildTempProject(state, projectFileDir) {
480285
480298
  await writeFile28(path13.join(dir, "index.html"), html, "utf-8");
480286
480299
  return {
480287
480300
  dir,
480288
- cleanup: () => rm4(dir, { recursive: true, force: true })
480301
+ cleanup: () => rm5(dir, { recursive: true, force: true })
480289
480302
  };
480290
480303
  }
480291
480304
  async function copyLottieRuntime(tempDir) {
@@ -490563,7 +490576,7 @@ init_api_key();
490563
490576
  init_exec_safe();
490564
490577
  init_remotion();
490565
490578
  import { resolve as resolve45, dirname as dirname26, basename as basename13 } from "node:path";
490566
- import { writeFile as writeFile30, mkdir as mkdir21, rm as rm5 } from "node:fs/promises";
490579
+ import { writeFile as writeFile30, mkdir as mkdir21, rm as rm6 } from "node:fs/promises";
490567
490580
  import { existsSync as existsSync51 } from "node:fs";
490568
490581
  import { tmpdir as tmpdir5 } from "node:os";
490569
490582
  var ASS_STYLES = ["karaoke-sweep", "typewriter"];
@@ -490732,13 +490745,13 @@ async function executeAnimatedCaption(options) {
490732
490745
  ], { timeout: 12e4 });
490733
490746
  const apiKey = await getApiKey("OPENAI_API_KEY", "OpenAI");
490734
490747
  if (!apiKey) {
490735
- await rm5(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490748
+ await rm6(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490736
490749
  });
490737
490750
  return { success: false, error: "OPENAI_API_KEY required for Whisper transcription. Run 'vibe setup' or set OPENAI_API_KEY in .env" };
490738
490751
  }
490739
490752
  const transcript = await transcribeWithWords(audioPath, apiKey, language);
490740
490753
  if (!transcript.words || transcript.words.length === 0) {
490741
- await rm5(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490754
+ await rm6(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490742
490755
  });
490743
490756
  return { success: false, error: "No words detected in transcription" };
490744
490757
  }
@@ -490792,12 +490805,12 @@ async function executeAnimatedCaption(options) {
490792
490805
  outputPath: absOutputPath
490793
490806
  });
490794
490807
  if (!renderResult.success) {
490795
- await rm5(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490808
+ await rm6(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490796
490809
  });
490797
490810
  return { success: false, error: renderResult.error };
490798
490811
  }
490799
490812
  }
490800
- await rm5(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490813
+ await rm6(tmpAudioDir, { recursive: true, force: true }).catch(() => {
490801
490814
  });
490802
490815
  return {
490803
490816
  success: true,
@@ -499724,7 +499737,7 @@ var server2 = new Server(
499724
499737
  {
499725
499738
  name: "vibeframe",
499726
499739
  // Stamped with the package version by build.js at bundle time.
499727
- version: "0.113.4"
499740
+ version: "0.113.6"
499728
499741
  },
499729
499742
  {
499730
499743
  capabilities: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeframe/mcp-server",
3
- "version": "0.113.4",
3
+ "version": "0.113.6",
4
4
  "description": "VibeFrame MCP Server - AI-native video editing via Model Context Protocol",
5
5
  "type": "module",
6
6
  "bin": {
@@ -60,8 +60,8 @@
60
60
  "tsx": "^4.21.0",
61
61
  "typescript": "^5.3.3",
62
62
  "vitest": "^1.2.2",
63
- "@vibeframe/cli": "0.113.4",
64
- "@vibeframe/core": "0.113.4"
63
+ "@vibeframe/cli": "0.113.6",
64
+ "@vibeframe/core": "0.113.6"
65
65
  },
66
66
  "engines": {
67
67
  "node": ">=20"