@vibeframe/mcp-server 0.113.3 → 0.113.5
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 +66 -34
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -472894,6 +472894,14 @@ async function createBuildPlan(opts) {
|
|
|
472894
472894
|
duration: beat.duration,
|
|
472895
472895
|
keyframe: keyframePrompt
|
|
472896
472896
|
}) : null;
|
|
472897
|
+
const keyframeCache2 = keyframePrompt ? keyframeCacheDescriptor({
|
|
472898
|
+
beatId: beat.id,
|
|
472899
|
+
cue: keyframePrompt,
|
|
472900
|
+
provider: resolved.image.resolved,
|
|
472901
|
+
quality: imageQuality,
|
|
472902
|
+
size: imageSize2,
|
|
472903
|
+
ratio: imageRatio
|
|
472904
|
+
}) : null;
|
|
472897
472905
|
const musicCache = musicPrompt && !musicReference ? musicCacheDescriptor({
|
|
472898
472906
|
beatId: beat.id,
|
|
472899
472907
|
cue: musicPrompt,
|
|
@@ -472929,6 +472937,19 @@ async function createBuildPlan(opts) {
|
|
|
472929
472937
|
cost: backdropCostUsd(imageQuality),
|
|
472930
472938
|
active: includeAssets
|
|
472931
472939
|
}) : null;
|
|
472940
|
+
const keyframe = keyframePrompt && !opts.skipKeyframe ? assetPlan({
|
|
472941
|
+
kind: "keyframe",
|
|
472942
|
+
beatId: beat.id,
|
|
472943
|
+
cue: keyframePrompt,
|
|
472944
|
+
provider: resolved.image.resolved,
|
|
472945
|
+
path: `assets/keyframe-${beat.id}.png`,
|
|
472946
|
+
cache: keyframeCache2,
|
|
472947
|
+
reference: null,
|
|
472948
|
+
projectDir,
|
|
472949
|
+
force: opts.force,
|
|
472950
|
+
cost: backdropCostUsd(imageQuality),
|
|
472951
|
+
active: includeAssets
|
|
472952
|
+
}) : null;
|
|
472932
472953
|
const video = videoCue && !opts.skipVideo ? assetPlan({
|
|
472933
472954
|
kind: "video",
|
|
472934
472955
|
beatId: beat.id,
|
|
@@ -472961,7 +472982,7 @@ async function createBuildPlan(opts) {
|
|
|
472961
472982
|
}) : null;
|
|
472962
472983
|
const compositionPath = `compositions/scene-${beat.id}.html`;
|
|
472963
472984
|
const compositionExists = existsSync33(join30(projectDir, compositionPath));
|
|
472964
|
-
for (const asset of [narration, backdrop, video, music]) {
|
|
472985
|
+
for (const asset of [narration, backdrop, keyframe, video, music]) {
|
|
472965
472986
|
if (!asset) continue;
|
|
472966
472987
|
if (asset.referenceError) {
|
|
472967
472988
|
missing.add("assets");
|
|
@@ -472986,13 +473007,9 @@ async function createBuildPlan(opts) {
|
|
|
472986
473007
|
if (narration?.willGenerate) noteProviderNeed(resolved.narration, "Narration");
|
|
472987
473008
|
if (backdrop?.willGenerate && isSupportedBuildImageProvider(resolved.image.resolved))
|
|
472988
473009
|
noteProviderNeed(resolved.image, "Backdrop generation");
|
|
473010
|
+
if (keyframe?.willGenerate && isSupportedBuildImageProvider(resolved.image.resolved))
|
|
473011
|
+
noteProviderNeed(resolved.image, "Keyframe generation");
|
|
472989
473012
|
if (video?.willGenerate) noteProviderNeed(resolved.video, "Video generation");
|
|
472990
|
-
if (keyframePrompt && video?.willGenerate) {
|
|
472991
|
-
estimatedCostUsd += backdropCostUsd(imageQuality);
|
|
472992
|
-
providers.add(resolved.image.resolved);
|
|
472993
|
-
if (isSupportedBuildImageProvider(resolved.image.resolved))
|
|
472994
|
-
noteProviderNeed(resolved.image, "Keyframe generation");
|
|
472995
|
-
}
|
|
472996
473013
|
if (music?.willGenerate) noteProviderNeed(resolved.music, "Music generation");
|
|
472997
473014
|
if (!compositionExists) missing.add("compositions");
|
|
472998
473015
|
if (includeCompose && !compositionExists && mode !== "agent") {
|
|
@@ -473005,7 +473022,7 @@ async function createBuildPlan(opts) {
|
|
|
473005
473022
|
heading: beat.heading,
|
|
473006
473023
|
durationSec: beat.duration ?? null,
|
|
473007
473024
|
cues: cue,
|
|
473008
|
-
assets: { narration, backdrop, video, music },
|
|
473025
|
+
assets: { narration, backdrop, keyframe, video, music },
|
|
473009
473026
|
composition: {
|
|
473010
473027
|
path: compositionPath,
|
|
473011
473028
|
exists: compositionExists
|
|
@@ -473221,6 +473238,7 @@ function providerResolutionsForPlan(resolved, beats, opts, includeAssets) {
|
|
|
473221
473238
|
return [
|
|
473222
473239
|
includeAssets && !opts.skipNarration && needsProvider("narration") ? resolved.narration : null,
|
|
473223
473240
|
includeAssets && !opts.skipBackdrop && needsProvider("backdrop") ? resolved.image : null,
|
|
473241
|
+
includeAssets && !opts.skipKeyframe && needsProvider("keyframe") ? resolved.image : null,
|
|
473224
473242
|
includeAssets && !opts.skipVideo && needsProvider("video") ? resolved.video : null,
|
|
473225
473243
|
includeAssets && !opts.skipMusic && needsProvider("music") ? resolved.music : null,
|
|
473226
473244
|
resolved.composer ?? null
|
|
@@ -473781,10 +473799,17 @@ async function executeSceneBuild(opts) {
|
|
|
473781
473799
|
const onProgress = opts.onProgress ?? (() => {
|
|
473782
473800
|
});
|
|
473783
473801
|
const mode = resolveSceneBuildMode(opts);
|
|
473784
|
-
|
|
473802
|
+
let selectedStage = opts.stage ?? (opts.skipRender ? "sync" : "all");
|
|
473803
|
+
const skipVideoStopsRender = (opts.skipVideo ?? false) && (selectedStage === "all" || selectedStage === "render");
|
|
473804
|
+
if (skipVideoStopsRender) selectedStage = "sync";
|
|
473785
473805
|
const stageReports = createEmptyStageReports();
|
|
473786
473806
|
const warnings = [];
|
|
473787
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
|
+
}
|
|
473788
473813
|
let sceneRepair = skippedSceneRepairSummary();
|
|
473789
473814
|
const storyboardPath = join31(projectDir, "STORYBOARD.md");
|
|
473790
473815
|
const buildPlan = await createBuildPlan({
|
|
@@ -473795,6 +473820,7 @@ async function executeSceneBuild(opts) {
|
|
|
473795
473820
|
skipNarration: opts.skipNarration,
|
|
473796
473821
|
skipBackdrop: opts.skipBackdrop,
|
|
473797
473822
|
skipVideo: opts.skipVideo,
|
|
473823
|
+
skipKeyframe: opts.skipKeyframe,
|
|
473798
473824
|
skipMusic: opts.skipMusic,
|
|
473799
473825
|
ttsProvider: opts.ttsProvider,
|
|
473800
473826
|
voice: opts.voice,
|
|
@@ -473943,7 +473969,7 @@ async function executeSceneBuild(opts) {
|
|
|
473943
473969
|
if (shouldRunStage(selectedStage, "assets")) {
|
|
473944
473970
|
onProgress({ type: "phase-start", phase: "primitives" });
|
|
473945
473971
|
const characterPaths = /* @__PURE__ */ new Map();
|
|
473946
|
-
if (!(opts.skipVideo ?? false)) {
|
|
473972
|
+
if (!((opts.skipVideo ?? false) && (opts.skipKeyframe ?? false))) {
|
|
473947
473973
|
const referenced = /* @__PURE__ */ new Set();
|
|
473948
473974
|
for (const beat of activeBeats) {
|
|
473949
473975
|
for (const name of beatCharacterNames(beat.cues)) referenced.add(name);
|
|
@@ -473980,6 +474006,7 @@ async function executeSceneBuild(opts) {
|
|
|
473980
474006
|
skipNarration: opts.skipNarration ?? false,
|
|
473981
474007
|
skipBackdrop: opts.skipBackdrop ?? false,
|
|
473982
474008
|
skipVideo: opts.skipVideo ?? false,
|
|
474009
|
+
skipKeyframe: opts.skipKeyframe ?? false,
|
|
473983
474010
|
skipMusic: opts.skipMusic ?? false,
|
|
473984
474011
|
force: opts.force ?? false,
|
|
473985
474012
|
onProgress,
|
|
@@ -474356,10 +474383,11 @@ async function executeSceneBuild(opts) {
|
|
|
474356
474383
|
});
|
|
474357
474384
|
}
|
|
474358
474385
|
async function buildBeatPrimitives(beat, ctx) {
|
|
474386
|
+
const keyframe = ctx.skipKeyframe ? await skipped("keyframe", beat.id, "--skip-keyframe", ctx) : await dispatchKeyframe(beat, ctx);
|
|
474359
474387
|
const [narration, backdrop, video, music] = await Promise.all([
|
|
474360
474388
|
ctx.skipNarration ? skipped("narration", beat.id, "--skip-narration", ctx) : dispatchNarration(beat, ctx),
|
|
474361
474389
|
ctx.skipBackdrop ? skipped("backdrop", beat.id, "--skip-backdrop", ctx) : dispatchBackdrop(beat, ctx),
|
|
474362
|
-
ctx.skipVideo ? skipped("video", beat.id, "--skip-video", ctx) : dispatchVideo(beat, ctx),
|
|
474390
|
+
ctx.skipVideo ? skipped("video", beat.id, "--skip-video", ctx) : dispatchVideo(beat, ctx, keyframe),
|
|
474363
474391
|
ctx.skipMusic ? skipped("music", beat.id, "--skip-music", ctx) : dispatchMusic(beat, ctx)
|
|
474364
474392
|
]);
|
|
474365
474393
|
return {
|
|
@@ -474403,8 +474431,8 @@ async function buildBeatPrimitives(beat, ctx) {
|
|
|
474403
474431
|
videoMetadataPath: video.metadataPath,
|
|
474404
474432
|
videoFreshness: video.freshness,
|
|
474405
474433
|
videoSourcePath: video.sourcePath,
|
|
474406
|
-
keyframeStatus:
|
|
474407
|
-
keyframePath:
|
|
474434
|
+
keyframeStatus: keyframe.status,
|
|
474435
|
+
keyframePath: keyframe.path,
|
|
474408
474436
|
musicStatus: music.status,
|
|
474409
474437
|
musicPath: music.path,
|
|
474410
474438
|
musicJobId: music.job?.id,
|
|
@@ -474975,7 +475003,21 @@ function imageProviderKeyInfo(provider) {
|
|
|
474975
475003
|
if (provider === "grok") return { configKey: "xai", envVar: "XAI_API_KEY" };
|
|
474976
475004
|
return { configKey: "openai", envVar: "OPENAI_API_KEY" };
|
|
474977
475005
|
}
|
|
474978
|
-
async function
|
|
475006
|
+
async function dispatchKeyframe(beat, ctx) {
|
|
475007
|
+
const keyframeCue = stringOrUndefined4(beat.cues?.keyframe);
|
|
475008
|
+
if (!keyframeCue) return { status: "no-cue" };
|
|
475009
|
+
const characterRefsRel = beatCharacterNames(beat.cues).map((name) => ctx.characterPaths?.get(name)).filter((p2) => typeof p2 === "string");
|
|
475010
|
+
const kf = await ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel);
|
|
475011
|
+
if (kf.status === "failed") {
|
|
475012
|
+
ctx.onProgress({ type: "keyframe-failed", beatId: beat.id, error: kf.error });
|
|
475013
|
+
return { status: "failed", error: kf.error };
|
|
475014
|
+
}
|
|
475015
|
+
ctx.onProgress(
|
|
475016
|
+
kf.status === "cached" ? { type: "keyframe-cached", beatId: beat.id, path: kf.rel } : { type: "keyframe-generated", beatId: beat.id, path: kf.rel, provider: ctx.imageProvider }
|
|
475017
|
+
);
|
|
475018
|
+
return { status: kf.status, path: kf.rel, provider: ctx.imageProvider };
|
|
475019
|
+
}
|
|
475020
|
+
async function dispatchVideo(beat, ctx, keyframe) {
|
|
474979
475021
|
const reference = assetReferenceForBeat(ctx.projectDir, "video", beat);
|
|
474980
475022
|
if (reference) return referencePrimitiveOutcome("video", beat, ctx, reference);
|
|
474981
475023
|
const keyframeCue = stringOrUndefined4(beat.cues?.keyframe);
|
|
@@ -475045,20 +475087,14 @@ async function dispatchVideo(beat, ctx) {
|
|
|
475045
475087
|
freshness: "fresh"
|
|
475046
475088
|
};
|
|
475047
475089
|
}
|
|
475048
|
-
|
|
475049
|
-
|
|
475050
|
-
|
|
475051
|
-
|
|
475052
|
-
|
|
475053
|
-
const kf = await ensureKeyframe(beat, ctx, keyframeCue, characterRefsRel);
|
|
475054
|
-
if (kf.status === "failed") {
|
|
475055
|
-
ctx.onProgress({ type: "video-failed", beatId: beat.id, error: kf.error });
|
|
475056
|
-
return { status: "failed", error: kf.error };
|
|
475057
|
-
}
|
|
475058
|
-
keyframeStatus = kf.status;
|
|
475059
|
-
keyframeRel = kf.rel;
|
|
475060
|
-
keyframeImageAbs = join31(ctx.projectDir, kf.rel);
|
|
475090
|
+
const keyframeImageRel = keyframeCue && (keyframe.status === "generated" || keyframe.status === "cached") ? keyframe.path : void 0;
|
|
475091
|
+
if (keyframeCue && !keyframeImageRel) {
|
|
475092
|
+
const reason = keyframe.status === "failed" ? `keyframe unavailable: ${keyframe.error ?? "generation failed"}` : "keyframe not generated (build without --skip-keyframe first)";
|
|
475093
|
+
ctx.onProgress({ type: "video-skipped", beatId: beat.id, reason });
|
|
475094
|
+
return { status: "skipped" };
|
|
475061
475095
|
}
|
|
475096
|
+
const keyframeImageAbs = keyframeImageRel ? join31(ctx.projectDir, keyframeImageRel) : void 0;
|
|
475097
|
+
loadSceneBuildEnv(ctx.projectDir);
|
|
475062
475098
|
const result = await executeVideoGenerate({
|
|
475063
475099
|
prompt: prompt3,
|
|
475064
475100
|
provider: ctx.videoProvider,
|
|
@@ -475104,9 +475140,7 @@ async function dispatchVideo(beat, ctx) {
|
|
|
475104
475140
|
cachePath: cache.path,
|
|
475105
475141
|
cacheKey: cache.key,
|
|
475106
475142
|
metadataPath,
|
|
475107
|
-
freshness: "fresh"
|
|
475108
|
-
keyframeStatus,
|
|
475109
|
-
keyframePath: keyframeRel
|
|
475143
|
+
freshness: "fresh"
|
|
475110
475144
|
};
|
|
475111
475145
|
}
|
|
475112
475146
|
const job = await createAndWriteJobRecord({
|
|
@@ -475138,9 +475172,7 @@ async function dispatchVideo(beat, ctx) {
|
|
|
475138
475172
|
provider: job.provider,
|
|
475139
475173
|
cachePath: cache.path,
|
|
475140
475174
|
cacheKey: cache.key,
|
|
475141
|
-
metadataPath
|
|
475142
|
-
keyframeStatus,
|
|
475143
|
-
keyframePath: keyframeRel
|
|
475175
|
+
metadataPath
|
|
475144
475176
|
};
|
|
475145
475177
|
}
|
|
475146
475178
|
async function dispatchMusic(beat, ctx) {
|
|
@@ -499699,7 +499731,7 @@ var server2 = new Server(
|
|
|
499699
499731
|
{
|
|
499700
499732
|
name: "vibeframe",
|
|
499701
499733
|
// Stamped with the package version by build.js at bundle time.
|
|
499702
|
-
version: "0.113.
|
|
499734
|
+
version: "0.113.5"
|
|
499703
499735
|
},
|
|
499704
499736
|
{
|
|
499705
499737
|
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.5",
|
|
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.5",
|
|
64
|
+
"@vibeframe/core": "0.113.5"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=20"
|