@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.
- package/dist/index.js +38 -25
- 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" ||
|
|
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
|
|
474618
|
-
"
|
|
474619
|
-
"
|
|
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
|
|
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
|
|
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:
|
|
476631
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
477643
|
-
await
|
|
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
|
|
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: () =>
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
64
|
-
"@vibeframe/core": "0.113.
|
|
63
|
+
"@vibeframe/cli": "0.113.6",
|
|
64
|
+
"@vibeframe/core": "0.113.6"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=20"
|