@vibeframe/mcp-server 0.105.2 → 0.106.0
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 +250 -65
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -435908,6 +435908,40 @@ var init_whisper = __esm3({
|
|
|
435908
435908
|
init_WhisperProvider();
|
|
435909
435909
|
}
|
|
435910
435910
|
});
|
|
435911
|
+
function isGeminiTextModelAlias(model) {
|
|
435912
|
+
return Object.prototype.hasOwnProperty.call(GEMINI_TEXT_MODEL_ALIASES, model);
|
|
435913
|
+
}
|
|
435914
|
+
function resolveGeminiTextModel(model) {
|
|
435915
|
+
const trimmed = model?.trim();
|
|
435916
|
+
if (!trimmed)
|
|
435917
|
+
return GEMINI_DEFAULT_TEXT_MODEL;
|
|
435918
|
+
if (isGeminiTextModelAlias(trimmed))
|
|
435919
|
+
return GEMINI_TEXT_MODEL_ALIASES[trimmed];
|
|
435920
|
+
if (trimmed.startsWith("gemini-"))
|
|
435921
|
+
return trimmed;
|
|
435922
|
+
return GEMINI_DEFAULT_TEXT_MODEL;
|
|
435923
|
+
}
|
|
435924
|
+
var GEMINI_DEFAULT_TEXT_MODEL;
|
|
435925
|
+
var GEMINI_AGENT_DEFAULT_TEXT_MODEL;
|
|
435926
|
+
var GEMINI_TEXT_MODEL_ALIASES;
|
|
435927
|
+
var GEMINI_TEXT_MODEL_HELP;
|
|
435928
|
+
var init_gemini_models = __esm3({
|
|
435929
|
+
"../ai-providers/dist/gemini/gemini-models.js"() {
|
|
435930
|
+
"use strict";
|
|
435931
|
+
GEMINI_DEFAULT_TEXT_MODEL = "gemini-3.5-flash";
|
|
435932
|
+
GEMINI_AGENT_DEFAULT_TEXT_MODEL = "gemini-2.5-flash";
|
|
435933
|
+
GEMINI_TEXT_MODEL_ALIASES = {
|
|
435934
|
+
flash: GEMINI_DEFAULT_TEXT_MODEL,
|
|
435935
|
+
latest: GEMINI_DEFAULT_TEXT_MODEL,
|
|
435936
|
+
"flash-3.5": GEMINI_DEFAULT_TEXT_MODEL,
|
|
435937
|
+
"flash-3": "gemini-3-flash-preview",
|
|
435938
|
+
"flash-2.5": "gemini-2.5-flash",
|
|
435939
|
+
pro: "gemini-2.5-pro",
|
|
435940
|
+
"pro-3.1": "gemini-3.1-pro-preview"
|
|
435941
|
+
};
|
|
435942
|
+
GEMINI_TEXT_MODEL_HELP = "flash/latest (Gemini 3.5 Flash), flash-3.5, flash-3, flash-2.5, pro, pro-3.1, or a full gemini-* model ID";
|
|
435943
|
+
}
|
|
435944
|
+
});
|
|
435911
435945
|
function buildMotionSystemPrompt(width, height, fps, duration, durationInFrames, stylePreset) {
|
|
435912
435946
|
return `You are a world-class broadcast motion graphics designer (like Apple Keynote, Netflix intros, ESPN graphics). Create STUNNING, jaw-dropping overlays that make viewers go "wow".
|
|
435913
435947
|
|
|
@@ -436060,7 +436094,7 @@ async function generateMotion(api, description, options = {}) {
|
|
|
436060
436094
|
const duration = options.duration || 5;
|
|
436061
436095
|
const durationInFrames = Math.round(duration * fps);
|
|
436062
436096
|
const stylePreset = options.style || "modern and clean";
|
|
436063
|
-
const modelId = options.model
|
|
436097
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
436064
436098
|
let systemPrompt = buildMotionSystemPrompt(width, height, fps, duration, durationInFrames, stylePreset);
|
|
436065
436099
|
if (options.videoContext) {
|
|
436066
436100
|
const sourceLabel = options.sourceType === "image" ? "IMAGE" : "VIDEO";
|
|
@@ -436141,7 +436175,7 @@ async function refineMotion(api, existingCode, instructions, options = {}) {
|
|
|
436141
436175
|
const fps = options.fps || 30;
|
|
436142
436176
|
const duration = options.duration || 5;
|
|
436143
436177
|
const durationInFrames = Math.round(duration * fps);
|
|
436144
|
-
const modelId = options.model
|
|
436178
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
436145
436179
|
const systemPrompt = `You are a world-class broadcast motion graphics designer. Modify the provided Remotion component based on instructions.
|
|
436146
436180
|
|
|
436147
436181
|
CANVAS: ${width}\xD7${height}px | ${fps}fps | ${durationInFrames} frames (${duration}s)
|
|
@@ -436237,9 +436271,18 @@ var STYLE_USER_INSTRUCTIONS;
|
|
|
436237
436271
|
var init_gemini_motion = __esm3({
|
|
436238
436272
|
"../ai-providers/dist/gemini/gemini-motion.js"() {
|
|
436239
436273
|
"use strict";
|
|
436274
|
+
init_gemini_models();
|
|
436240
436275
|
GEMINI_MOTION_MODELS = {
|
|
436276
|
+
gemini: GEMINI_DEFAULT_TEXT_MODEL,
|
|
436277
|
+
flash: GEMINI_DEFAULT_TEXT_MODEL,
|
|
436278
|
+
latest: GEMINI_DEFAULT_TEXT_MODEL,
|
|
436279
|
+
"flash-3.5": GEMINI_DEFAULT_TEXT_MODEL,
|
|
436280
|
+
"flash-3": "gemini-3-flash-preview",
|
|
436281
|
+
"flash-2.5": "gemini-2.5-flash",
|
|
436241
436282
|
pro: "gemini-2.5-pro",
|
|
436242
|
-
"
|
|
436283
|
+
"2.5-pro": "gemini-2.5-pro",
|
|
436284
|
+
"3.1-pro": "gemini-3.1-pro-preview",
|
|
436285
|
+
"pro-3.1": "gemini-3.1-pro-preview"
|
|
436243
436286
|
};
|
|
436244
436287
|
STYLE_USER_INSTRUCTIONS = {
|
|
436245
436288
|
minimal: "CENTER-ALIGNED pure typography. Thin lines + large title + subtitle. NO glass panels, NO bokeh, NO dark bars. Breathing pulse during hold.",
|
|
@@ -436358,7 +436401,7 @@ async function analyzeContent(api, content, targetDuration, options) {
|
|
|
436358
436401
|
maxOutputTokens: 4096
|
|
436359
436402
|
}
|
|
436360
436403
|
};
|
|
436361
|
-
const response = await fetch(`${api.baseUrl}/models
|
|
436404
|
+
const response = await fetch(`${api.baseUrl}/models/${GEMINI_DEFAULT_TEXT_MODEL}:generateContent?key=${api.apiKey}`, {
|
|
436362
436405
|
method: "POST",
|
|
436363
436406
|
headers: { "Content-Type": "application/json" },
|
|
436364
436407
|
body: JSON.stringify(payload)
|
|
@@ -436391,6 +436434,7 @@ var init_gemini_storyboard = __esm3({
|
|
|
436391
436434
|
"../ai-providers/dist/gemini/gemini-storyboard.js"() {
|
|
436392
436435
|
"use strict";
|
|
436393
436436
|
init_storyboard_prompt();
|
|
436437
|
+
init_gemini_models();
|
|
436394
436438
|
}
|
|
436395
436439
|
});
|
|
436396
436440
|
async function fetchJson(label, url, init) {
|
|
@@ -436427,6 +436471,7 @@ var init_GeminiProvider = __esm3({
|
|
|
436427
436471
|
"../ai-providers/dist/gemini/GeminiProvider.js"() {
|
|
436428
436472
|
"use strict";
|
|
436429
436473
|
init_gemini_motion();
|
|
436474
|
+
init_gemini_models();
|
|
436430
436475
|
init_gemini_storyboard();
|
|
436431
436476
|
init_http();
|
|
436432
436477
|
MODEL_MAP = {
|
|
@@ -436935,7 +436980,7 @@ var init_GeminiProvider = __esm3({
|
|
|
436935
436980
|
error: "Google API key not configured"
|
|
436936
436981
|
};
|
|
436937
436982
|
}
|
|
436938
|
-
const modelId = options.model
|
|
436983
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
436939
436984
|
try {
|
|
436940
436985
|
let videoPart;
|
|
436941
436986
|
if (typeof videoData === "string") {
|
|
@@ -437042,7 +437087,7 @@ var init_GeminiProvider = __esm3({
|
|
|
437042
437087
|
error: "Google API key not configured"
|
|
437043
437088
|
};
|
|
437044
437089
|
}
|
|
437045
|
-
const modelId = options.model
|
|
437090
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
437046
437091
|
try {
|
|
437047
437092
|
const buffers = Array.isArray(imageData) ? imageData : [imageData];
|
|
437048
437093
|
const imageParts = buffers.map((buf) => ({
|
|
@@ -437144,7 +437189,7 @@ Example response:
|
|
|
437144
437189
|
[{"type":"trim","description":"Trim intro to 3 seconds","clipIds":["clip-1"],"params":{"newDuration":3},"confidence":0.9}]
|
|
437145
437190
|
|
|
437146
437191
|
Respond with ONLY the JSON array, no other text.`;
|
|
437147
|
-
const response = await fetch(`${this.baseUrl}/models
|
|
437192
|
+
const response = await fetch(`${this.baseUrl}/models/${GEMINI_DEFAULT_TEXT_MODEL}:generateContent?key=${this.apiKey}`, {
|
|
437148
437193
|
method: "POST",
|
|
437149
437194
|
headers: {
|
|
437150
437195
|
"Content-Type": "application/json"
|
|
@@ -437264,6 +437309,7 @@ var init_gemini = __esm3({
|
|
|
437264
437309
|
"use strict";
|
|
437265
437310
|
init_GeminiProvider();
|
|
437266
437311
|
init_gemini_motion();
|
|
437312
|
+
init_gemini_models();
|
|
437267
437313
|
init_define_provider();
|
|
437268
437314
|
defineProvider({
|
|
437269
437315
|
id: "gemini",
|
|
@@ -446526,6 +446572,10 @@ __export3(dist_exports22, {
|
|
|
446526
446572
|
ClaudeProvider: () => ClaudeProvider,
|
|
446527
446573
|
ElevenLabsProvider: () => ElevenLabsProvider,
|
|
446528
446574
|
FalProvider: () => FalProvider,
|
|
446575
|
+
GEMINI_AGENT_DEFAULT_TEXT_MODEL: () => GEMINI_AGENT_DEFAULT_TEXT_MODEL,
|
|
446576
|
+
GEMINI_DEFAULT_TEXT_MODEL: () => GEMINI_DEFAULT_TEXT_MODEL,
|
|
446577
|
+
GEMINI_TEXT_MODEL_ALIASES: () => GEMINI_TEXT_MODEL_ALIASES,
|
|
446578
|
+
GEMINI_TEXT_MODEL_HELP: () => GEMINI_TEXT_MODEL_HELP,
|
|
446529
446579
|
GeminiProvider: () => GeminiProvider,
|
|
446530
446580
|
GrokProvider: () => GrokProvider,
|
|
446531
446581
|
KNOWN_VOICES: () => KNOWN_VOICES,
|
|
@@ -446556,6 +446606,7 @@ __export3(dist_exports22, {
|
|
|
446556
446606
|
getProvidersFor: () => getProvidersFor,
|
|
446557
446607
|
getSetupProviders: () => getSetupProviders,
|
|
446558
446608
|
grokProvider: () => grokProvider,
|
|
446609
|
+
isGeminiTextModelAlias: () => isGeminiTextModelAlias,
|
|
446559
446610
|
klingProvider: () => klingProvider,
|
|
446560
446611
|
kokoroProvider: () => kokoroProvider,
|
|
446561
446612
|
ollamaProvider: () => ollamaProvider,
|
|
@@ -446563,6 +446614,7 @@ __export3(dist_exports22, {
|
|
|
446563
446614
|
openaiProvider: () => openaiProvider,
|
|
446564
446615
|
providerRegistry: () => providerRegistry,
|
|
446565
446616
|
replicateProvider: () => replicateProvider,
|
|
446617
|
+
resolveGeminiTextModel: () => resolveGeminiTextModel,
|
|
446566
446618
|
resolveVoiceId: () => resolveVoiceId,
|
|
446567
446619
|
runwayProvider: () => runwayProvider,
|
|
446568
446620
|
whisperProvider: () => whisperProvider
|
|
@@ -449708,6 +449760,7 @@ var CONFIG_PROVIDER_BY_COMPOSER;
|
|
|
449708
449760
|
var init_compose_scenes_skills = __esm3({
|
|
449709
449761
|
"src/commands/_shared/compose-scenes-skills.ts"() {
|
|
449710
449762
|
"use strict";
|
|
449763
|
+
init_dist22();
|
|
449711
449764
|
init_config();
|
|
449712
449765
|
init_bundle();
|
|
449713
449766
|
init_scene_lint();
|
|
@@ -449729,12 +449782,12 @@ var init_compose_scenes_skills = __esm3({
|
|
|
449729
449782
|
medium: { model: "gpt-5", maxTokens: 6e3, costPerMTokIn: 1.25, costPerMTokOut: 10 },
|
|
449730
449783
|
high: { model: "gpt-5", maxTokens: 8e3, costPerMTokIn: 1.25, costPerMTokOut: 10 }
|
|
449731
449784
|
},
|
|
449732
|
-
// Google Gemini
|
|
449733
|
-
//
|
|
449785
|
+
// Google Gemini 3.5 Flash — current one-shot Gemini default for
|
|
449786
|
+
// analysis/composition. Keep agent loops on their explicit 2.5 Flash default.
|
|
449734
449787
|
gemini: {
|
|
449735
|
-
low: { model:
|
|
449736
|
-
medium: { model:
|
|
449737
|
-
high: { model:
|
|
449788
|
+
low: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 4e3, costPerMTokIn: 1.5, costPerMTokOut: 9 },
|
|
449789
|
+
medium: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 6e3, costPerMTokIn: 1.5, costPerMTokOut: 9 },
|
|
449790
|
+
high: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 8e3, costPerMTokIn: 1.5, costPerMTokOut: 9 }
|
|
449738
449791
|
}
|
|
449739
449792
|
};
|
|
449740
449793
|
ComposeBeatError = class extends Error {
|
|
@@ -456309,12 +456362,7 @@ async function detectSilencePeriodsWithGemini(videoPath, minDuration, options) {
|
|
|
456309
456362
|
const gemini = new GeminiProvider();
|
|
456310
456363
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
456311
456364
|
const videoBuffer = await readFile18(videoPath);
|
|
456312
|
-
const
|
|
456313
|
-
flash: "gemini-3-flash-preview",
|
|
456314
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
456315
|
-
pro: "gemini-2.5-pro"
|
|
456316
|
-
};
|
|
456317
|
-
const modelId = options.model ? modelMap[options.model] || modelMap.flash : void 0;
|
|
456365
|
+
const modelId = options.model ? resolveGeminiTextModel(options.model) : void 0;
|
|
456318
456366
|
const prompt3 = `Analyze this video and identify all silent or dead segments where there is NO meaningful content.
|
|
456319
456367
|
|
|
456320
456368
|
Detect these as silent/dead segments:
|
|
@@ -459710,7 +459758,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
459710
459758
|
6. Recommended animation timing and entrance/exit style
|
|
459711
459759
|
7. Any moments where overlays should pause, fade, or stay minimal`;
|
|
459712
459760
|
const analysisResult = await gemini.analyzeVideo(videoBuffer, analysisPrompt, {
|
|
459713
|
-
model:
|
|
459761
|
+
model: GEMINI_DEFAULT_TEXT_MODEL,
|
|
459714
459762
|
fps: 1,
|
|
459715
459763
|
lowResolution: true
|
|
459716
459764
|
});
|
|
@@ -459879,7 +459927,7 @@ function registerMotionCommand(aiCommand) {
|
|
|
459879
459927
|
"auto"
|
|
459880
459928
|
).option("--understanding-prompt <text>", "Custom prompt for --video understanding").option("--from-tsx <path>", "Refine an existing TSX file instead of generating from scratch").option(
|
|
459881
459929
|
"-m, --model <alias>",
|
|
459882
|
-
"LLM model: sonnet (default), opus, gemini, gemini-3.1-pro",
|
|
459930
|
+
"LLM model: sonnet (default), opus, gemini, gemini-2.5-pro, gemini-3.1-pro",
|
|
459883
459931
|
"sonnet"
|
|
459884
459932
|
).option("--dry-run", "Preview parameters without executing").action(async (description, options) => {
|
|
459885
459933
|
const startedAt = Date.now();
|
|
@@ -460023,7 +460071,8 @@ var init_ai_motion = __esm3({
|
|
|
460023
460071
|
sonnet: { provider: "claude", modelId: "claude-sonnet-4-6" },
|
|
460024
460072
|
opus: { provider: "claude", modelId: "claude-opus-4-7" },
|
|
460025
460073
|
"opus-4-6": { provider: "claude", modelId: "claude-opus-4-6" },
|
|
460026
|
-
gemini: { provider: "gemini", modelId:
|
|
460074
|
+
gemini: { provider: "gemini", modelId: GEMINI_DEFAULT_TEXT_MODEL },
|
|
460075
|
+
"gemini-2.5-pro": { provider: "gemini", modelId: "gemini-2.5-pro" },
|
|
460027
460076
|
"gemini-3.1-pro": { provider: "gemini", modelId: "gemini-3.1-pro-preview" }
|
|
460028
460077
|
};
|
|
460029
460078
|
}
|
|
@@ -460584,7 +460633,7 @@ async function executeMotionOverlay(options) {
|
|
|
460584
460633
|
};
|
|
460585
460634
|
}
|
|
460586
460635
|
function registerMotionOverlayCommand(parent) {
|
|
460587
|
-
parent.command("motion-overlay").description("Apply designed motion graphics overlays to an existing video").argument("<video>", "Video file path").argument("[description]", "Motion overlay description (omit when using --asset)").option("--asset <path>", "User-provided .json/.lottie animation to overlay").option("-o, --output <path>", "Output video file path").option("-d, --duration <sec>", "Overlay/render duration in seconds").option("--start <sec>", "Overlay start time in seconds", "0").option("--style <style>", "Style preset for generated overlays: minimal, corporate, playful, cinematic").option("-m, --model <alias>", "LLM model for generated overlays: sonnet, opus, gemini, gemini-3.1-pro", "sonnet").option("--understand <mode>", "Analyze video before generated overlay: auto, off, required", "auto").option("--understanding-prompt <text>", "Custom prompt for video understanding").option("--position <position>", "Lottie position: full, center, top-left, top-right, bottom-left, bottom-right", "full").option("--scale <number>", "Lottie overlay scale (0.01-2)").option("--opacity <number>", "Lottie overlay opacity (0-1)", "1").option("--loop", "Loop Lottie overlay", true).option("--no-loop", "Do not loop Lottie overlay").option("--dry-run", "Preview parameters without executing").action(async (videoPath, description, options) => {
|
|
460636
|
+
parent.command("motion-overlay").description("Apply designed motion graphics overlays to an existing video").argument("<video>", "Video file path").argument("[description]", "Motion overlay description (omit when using --asset)").option("--asset <path>", "User-provided .json/.lottie animation to overlay").option("-o, --output <path>", "Output video file path").option("-d, --duration <sec>", "Overlay/render duration in seconds").option("--start <sec>", "Overlay start time in seconds", "0").option("--style <style>", "Style preset for generated overlays: minimal, corporate, playful, cinematic").option("-m, --model <alias>", "LLM model for generated overlays: sonnet, opus, gemini, gemini-2.5-pro, gemini-3.1-pro", "sonnet").option("--understand <mode>", "Analyze video before generated overlay: auto, off, required", "auto").option("--understanding-prompt <text>", "Custom prompt for video understanding").option("--position <position>", "Lottie position: full, center, top-left, top-right, bottom-left, bottom-right", "full").option("--scale <number>", "Lottie overlay scale (0.01-2)").option("--opacity <number>", "Lottie overlay opacity (0-1)", "1").option("--loop", "Loop Lottie overlay", true).option("--no-loop", "Do not loop Lottie overlay").option("--dry-run", "Preview parameters without executing").action(async (videoPath, description, options) => {
|
|
460588
460637
|
const startedAt = Date.now();
|
|
460589
460638
|
try {
|
|
460590
460639
|
if (options.output) validateOutputPath(options.output);
|
|
@@ -461864,13 +461913,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
461864
461913
|
await gemini.initialize({ apiKey: googleKey });
|
|
461865
461914
|
const videoData = await readFile25(videoPath);
|
|
461866
461915
|
const analysisPrompt = prompt3 || 'Analyze this video and find the single best frame for a thumbnail. Look for frames that are visually striking, well-composed, emotionally engaging, and representative of the video content. Avoid blurry frames, transitions, or dark scenes. Return ONLY a JSON object: {"timestamp": <seconds as number>, "reason": "<brief explanation>"}';
|
|
461867
|
-
const
|
|
461868
|
-
flash: "gemini-3-flash-preview",
|
|
461869
|
-
latest: "gemini-2.5-flash",
|
|
461870
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
461871
|
-
pro: "gemini-2.5-pro"
|
|
461872
|
-
};
|
|
461873
|
-
const modelId = modelMap[model] || "gemini-3-flash-preview";
|
|
461916
|
+
const modelId = resolveGeminiTextModel(model);
|
|
461874
461917
|
const result = await gemini.analyzeVideo(videoData, analysisPrompt, {
|
|
461875
461918
|
model: modelId,
|
|
461876
461919
|
fps: 1
|
|
@@ -461925,12 +461968,7 @@ async function executeGeminiVideo(options) {
|
|
|
461925
461968
|
return { success: false, error: "Google API key required. Run 'vibe setup' or set GOOGLE_API_KEY in .env" };
|
|
461926
461969
|
}
|
|
461927
461970
|
const isYouTube = options.source.includes("youtube.com") || options.source.includes("youtu.be");
|
|
461928
|
-
const
|
|
461929
|
-
flash: "gemini-3-flash-preview",
|
|
461930
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
461931
|
-
pro: "gemini-2.5-pro"
|
|
461932
|
-
};
|
|
461933
|
-
const modelId = modelMap[options.model || "flash"] || modelMap.flash;
|
|
461971
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
461934
461972
|
let videoData;
|
|
461935
461973
|
if (isYouTube) {
|
|
461936
461974
|
videoData = options.source;
|
|
@@ -461991,12 +462029,7 @@ async function executeAnalyze(options) {
|
|
|
461991
462029
|
error: "Cannot detect source type. Supported: images (.png/.jpg/.webp/.gif), videos (.mp4/.mov/.webm), YouTube URLs, image URLs."
|
|
461992
462030
|
};
|
|
461993
462031
|
}
|
|
461994
|
-
const
|
|
461995
|
-
flash: "gemini-3-flash-preview",
|
|
461996
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
461997
|
-
pro: "gemini-2.5-pro"
|
|
461998
|
-
};
|
|
461999
|
-
const modelId = modelMap[options.model || "flash"] || modelMap.flash;
|
|
462032
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
462000
462033
|
const gemini = new GeminiProvider();
|
|
462001
462034
|
await gemini.initialize({ apiKey });
|
|
462002
462035
|
if (isImage) {
|
|
@@ -462076,7 +462109,7 @@ async function executeAnalyze(options) {
|
|
|
462076
462109
|
}
|
|
462077
462110
|
}
|
|
462078
462111
|
function registerAnalyzeCommands(aiCommand) {
|
|
462079
|
-
aiCommand.command("gemini-video").description("Analyze video using Gemini (summarize, Q&A, extract info)").argument("<source>", "Video file path or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>",
|
|
462112
|
+
aiCommand.command("gemini-video").description("Analyze video using Gemini (summarize, Q&A, extract info)").argument("<source>", "Video file path or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>", `Model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").option("--fps <number>", "Frames per second (default: 1, higher for action)").option("--start <seconds>", "Start offset in seconds (for clipping)").option("--end <seconds>", "End offset in seconds (for clipping)").option("--low-res", "Use low resolution mode (fewer tokens, longer videos)").option("-v, --verbose", "Show token usage").action(async (source3, prompt3, options) => {
|
|
462080
462113
|
try {
|
|
462081
462114
|
if (options.apiKey) {
|
|
462082
462115
|
process.env.GOOGLE_API_KEY = options.apiKey;
|
|
@@ -462119,7 +462152,7 @@ function registerAnalyzeCommands(aiCommand) {
|
|
|
462119
462152
|
exitWithError(apiError(`Video analysis failed: ${error instanceof Error ? error.message : String(error)}`, true));
|
|
462120
462153
|
}
|
|
462121
462154
|
});
|
|
462122
|
-
aiCommand.command("analyze").description("Analyze any media: images, videos, or YouTube URLs using Gemini").argument("<source>", "Image/video file path, image URL, or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Describe this image', 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>",
|
|
462155
|
+
aiCommand.command("analyze").description("Analyze any media: images, videos, or YouTube URLs using Gemini").argument("<source>", "Image/video file path, image URL, or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Describe this image', 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>", `Model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").option("--fps <number>", "Frames per second for video (default: 1)").option("--start <seconds>", "Start offset in seconds (video only)").option("--end <seconds>", "End offset in seconds (video only)").option("--low-res", "Use low resolution mode (fewer tokens)").option("-v, --verbose", "Show token usage").action(async (source3, prompt3, options) => {
|
|
462123
462156
|
try {
|
|
462124
462157
|
if (options.apiKey) {
|
|
462125
462158
|
process.env.GOOGLE_API_KEY = options.apiKey;
|
|
@@ -462235,12 +462268,7 @@ ${content}`;
|
|
|
462235
462268
|
|
|
462236
462269
|
Project context for beat-aware review:
|
|
462237
462270
|
${projectContext}` : "";
|
|
462238
|
-
const
|
|
462239
|
-
flash: "gemini-3-flash-preview",
|
|
462240
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
462241
|
-
pro: "gemini-2.5-pro"
|
|
462242
|
-
};
|
|
462243
|
-
const modelId = modelMap[model] || modelMap.flash;
|
|
462271
|
+
const modelId = resolveGeminiTextModel(model);
|
|
462244
462272
|
const reviewPrompt = `You are a professional video editor reviewing this video for quality. Analyze the video and return a JSON review with the following structure. Return ONLY valid JSON, no extra text.
|
|
462245
462273
|
|
|
462246
462274
|
{
|
|
@@ -462347,7 +462375,7 @@ Score each category 1-10. Prefer beatIssues when you can map a problem to a stor
|
|
|
462347
462375
|
return result;
|
|
462348
462376
|
}
|
|
462349
462377
|
function registerReviewCommand(aiCommand) {
|
|
462350
|
-
aiCommand.command("review", { hidden: true }).description("Review video quality using Gemini AI and optionally auto-fix issues").argument("<source>", "Video file path").option("--storyboard <path>", "Storyboard JSON file for context").option("--auto-apply", "Automatically apply fixable corrections").option("--verify", "Run verification pass after applying fixes").option("-m, --model <model>",
|
|
462378
|
+
aiCommand.command("review", { hidden: true }).description("Review video quality using Gemini AI and optionally auto-fix issues").argument("<source>", "Video file path").option("--storyboard <path>", "Storyboard JSON file for context").option("--auto-apply", "Automatically apply fixable corrections").option("--verify", "Run verification pass after applying fixes").option("-m, --model <model>", `Gemini model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").option("-o, --output <path>", "Output video file path (for auto-apply)").option("--dry-run", "Preview parameters without executing").action(async (videoPath, options) => {
|
|
462351
462379
|
const startedAt = Date.now();
|
|
462352
462380
|
try {
|
|
462353
462381
|
if (options.output) {
|
|
@@ -463204,7 +463232,7 @@ var init_speech = __esm3({
|
|
|
463204
463232
|
}
|
|
463205
463233
|
});
|
|
463206
463234
|
function registerThumbnailCommand(parent) {
|
|
463207
|
-
parent.command("thumbnail").description("Generate video thumbnail (DALL-E) or extract best frame from video (Gemini)").argument("[description]", "Thumbnail description (for DALL-E generation)").option("-k, --api-key <key>", "API key (OpenAI for generation, Google for best-frame)").option("-o, --output <path>", "Output file path").option("--style <style>", "Platform style: youtube, instagram, tiktok, twitter").option("--best-frame <video>", "Extract best thumbnail frame from video using Gemini AI").option("--prompt <prompt>", "Custom prompt for best-frame analysis").option("--model <model>",
|
|
463235
|
+
parent.command("thumbnail").description("Generate video thumbnail (DALL-E) or extract best frame from video (Gemini)").argument("[description]", "Thumbnail description (for DALL-E generation)").option("-k, --api-key <key>", "API key (OpenAI for generation, Google for best-frame)").option("-o, --output <path>", "Output file path").option("--style <style>", "Platform style: youtube, instagram, tiktok, twitter").option("--best-frame <video>", "Extract best thumbnail frame from video using Gemini AI").option("--prompt <prompt>", "Custom prompt for best-frame analysis").option("--model <model>", `Gemini model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").action(async (description, options) => {
|
|
463208
463236
|
const startedAt = Date.now();
|
|
463209
463237
|
try {
|
|
463210
463238
|
if (description) rejectControlChars(description);
|
|
@@ -465404,7 +465432,7 @@ function registerVideoCommand(parent) {
|
|
|
465404
465432
|
"--seedance-model <model>",
|
|
465405
465433
|
"Seedance variant: quality or fast (fal.ai only)",
|
|
465406
465434
|
"quality"
|
|
465407
|
-
).option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 720p, 1080p, 4k
|
|
465435
|
+
).option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 480p, 720p, 1080p, or 4k depending on provider").option("--last-frame <path>", "Last frame image for frame interpolation (Veo) or Seedance end frame").option("--end-image <path>", "Ending frame image for Seedance image-to-video").option(
|
|
465408
465436
|
"--ref-images <paths...>",
|
|
465409
465437
|
"Reference images for Seedance reference-to-video or Veo character consistency"
|
|
465410
465438
|
).option("--ref-videos <paths...>", "Reference videos for Seedance reference-to-video").option("--ref-audio <paths...>", "Reference audio for Seedance reference-to-video").option("--no-generate-audio", "Disable native audio when the provider supports it").option("--person <mode>", "Person generation: allow_all, allow_adult (Veo only)").option("--veo-model <model>", "Veo model: 3.0, 3.1, 3.1-fast (default: 3.1-fast)", "3.1-fast").option(
|
|
@@ -465865,6 +465893,30 @@ Examples:
|
|
|
465865
465893
|
exitWithError(apiError(message, true));
|
|
465866
465894
|
}
|
|
465867
465895
|
}
|
|
465896
|
+
let seedanceEndImage;
|
|
465897
|
+
const seedanceEndImagePath = options.endImage ?? options.lastFrame;
|
|
465898
|
+
if (seedanceEndImagePath && seedanceReferences.length === 0) {
|
|
465899
|
+
try {
|
|
465900
|
+
const absEndImagePath = resolve50(process.cwd(), seedanceEndImagePath);
|
|
465901
|
+
const endImageBuffer = await readFile32(absEndImagePath);
|
|
465902
|
+
const ext = seedanceEndImagePath.toLowerCase().split(".").pop();
|
|
465903
|
+
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
465904
|
+
const uploadHost = await resolveUploadHost();
|
|
465905
|
+
spinner2.text = `Uploading end image via ${uploadHost.provider} for Seedance...`;
|
|
465906
|
+
const upload = await uploadHost.uploadImage(endImageBuffer, {
|
|
465907
|
+
filename: seedanceEndImagePath,
|
|
465908
|
+
mimeType
|
|
465909
|
+
});
|
|
465910
|
+
seedanceEndImage = upload.url;
|
|
465911
|
+
} catch (err) {
|
|
465912
|
+
spinner2.fail("End image upload failed");
|
|
465913
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
465914
|
+
if (message.includes("IMGBB_API_KEY")) {
|
|
465915
|
+
exitWithError(authError("IMGBB_API_KEY", "ImgBB"));
|
|
465916
|
+
}
|
|
465917
|
+
exitWithError(apiError(message, true));
|
|
465918
|
+
}
|
|
465919
|
+
}
|
|
465868
465920
|
spinner2.text = "Generating video with fal.ai Seedance 2.0 (this may take 1-3 minutes)...";
|
|
465869
465921
|
const seedanceModel = String(options.seedanceModel ?? "quality").toLowerCase();
|
|
465870
465922
|
const falModel = seedanceModel === "fast" || seedanceModel === "seedance-2.0-fast" ? "seedance-2.0-fast" : "seedance-2.0";
|
|
@@ -465877,7 +465929,8 @@ Examples:
|
|
|
465877
465929
|
negativePrompt: options.negative,
|
|
465878
465930
|
model: falModel,
|
|
465879
465931
|
resolution: options.resolution,
|
|
465880
|
-
generateAudio: options.generateAudio
|
|
465932
|
+
generateAudio: options.generateAudio,
|
|
465933
|
+
lastFrame: seedanceEndImage
|
|
465881
465934
|
});
|
|
465882
465935
|
finalResult = result;
|
|
465883
465936
|
}
|
|
@@ -471712,6 +471765,14 @@ var SCENE_PRESETS = [
|
|
|
471712
471765
|
"kinetic-type",
|
|
471713
471766
|
"product-shot"
|
|
471714
471767
|
];
|
|
471768
|
+
var LOTTIE_POSITIONS = [
|
|
471769
|
+
"full",
|
|
471770
|
+
"center",
|
|
471771
|
+
"top-left",
|
|
471772
|
+
"top-right",
|
|
471773
|
+
"bottom-left",
|
|
471774
|
+
"bottom-right"
|
|
471775
|
+
];
|
|
471715
471776
|
var GSAP_CDN = "https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js";
|
|
471716
471777
|
function esc(text) {
|
|
471717
471778
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -471992,6 +472053,56 @@ function buildPreset(input3) {
|
|
|
471992
472053
|
}
|
|
471993
472054
|
}
|
|
471994
472055
|
}
|
|
472056
|
+
var DOTLOTTIE_WC_VERSION = "0.9.12";
|
|
472057
|
+
var DOTLOTTIE_WEB_VERSION = "0.71.0";
|
|
472058
|
+
var DOTLOTTIE_WC_CDN = `https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-wc@${DOTLOTTIE_WC_VERSION}/dist/index.js`;
|
|
472059
|
+
var DOTLOTTIE_WASM_CDN = `https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@${DOTLOTTIE_WEB_VERSION}/dist/dotlottie-player.wasm`;
|
|
472060
|
+
function lottieOverlayStyle(input3) {
|
|
472061
|
+
const pos = input3.position ?? "full";
|
|
472062
|
+
const rawScale = input3.scale ?? (pos === "full" ? 1 : 0.25);
|
|
472063
|
+
const scale = Math.max(0.01, Math.min(2, rawScale));
|
|
472064
|
+
const opacity = Math.max(0, Math.min(1, input3.opacity ?? 1));
|
|
472065
|
+
const base = [
|
|
472066
|
+
"position:absolute",
|
|
472067
|
+
"pointer-events:none",
|
|
472068
|
+
`opacity:${opacity}`
|
|
472069
|
+
];
|
|
472070
|
+
if (pos === "full") {
|
|
472071
|
+
base.push("inset:0", "width:100%", "height:100%");
|
|
472072
|
+
} else {
|
|
472073
|
+
const pct = scale * 100;
|
|
472074
|
+
base.push(`width:${pct}%`, `height:${pct}%`);
|
|
472075
|
+
switch (pos) {
|
|
472076
|
+
case "center":
|
|
472077
|
+
base.push("top:50%", "left:50%", "transform:translate(-50%,-50%)");
|
|
472078
|
+
break;
|
|
472079
|
+
case "top-left":
|
|
472080
|
+
base.push("top:4%", "left:4%");
|
|
472081
|
+
break;
|
|
472082
|
+
case "top-right":
|
|
472083
|
+
base.push("top:4%", "right:4%");
|
|
472084
|
+
break;
|
|
472085
|
+
case "bottom-left":
|
|
472086
|
+
base.push("bottom:4%", "left:4%");
|
|
472087
|
+
break;
|
|
472088
|
+
case "bottom-right":
|
|
472089
|
+
base.push("bottom:4%", "right:4%");
|
|
472090
|
+
break;
|
|
472091
|
+
}
|
|
472092
|
+
}
|
|
472093
|
+
return base.join(";");
|
|
472094
|
+
}
|
|
472095
|
+
function buildLottieOverlay(input3, sceneId) {
|
|
472096
|
+
const loop = input3.loop ?? true ? " loop" : "";
|
|
472097
|
+
const style = lottieOverlayStyle(input3);
|
|
472098
|
+
const overlayId = `lottie-overlay-${sceneId}`;
|
|
472099
|
+
const markup = `<dotlottie-wc id="${overlayId}" src="${esc(input3.src)}" autoplay${loop} style="${style}"></dotlottie-wc>`;
|
|
472100
|
+
const script = `<script type="module">
|
|
472101
|
+
import { setWasmUrl } from "${DOTLOTTIE_WC_CDN}";
|
|
472102
|
+
setWasmUrl("${DOTLOTTIE_WASM_CDN}");
|
|
472103
|
+
</script>`;
|
|
472104
|
+
return { markup, script };
|
|
472105
|
+
}
|
|
471995
472106
|
function emitSceneHtml(input3) {
|
|
471996
472107
|
if (input3.duration <= 0) {
|
|
471997
472108
|
throw new Error(`Scene duration must be > 0, got ${input3.duration}`);
|
|
@@ -472012,15 +472123,20 @@ function emitSceneHtml(input3) {
|
|
|
472012
472123
|
data-volume="1"
|
|
472013
472124
|
></audio>
|
|
472014
472125
|
` : "";
|
|
472126
|
+
const lottieLayer = input3.lottie ? buildLottieOverlay(input3.lottie, id) : null;
|
|
472127
|
+
const lottieMarkup = lottieLayer ? `
|
|
472128
|
+
${lottieLayer.markup}` : "";
|
|
472129
|
+
const lottieScript = lottieLayer ? `
|
|
472130
|
+
${lottieLayer.script}` : "";
|
|
472015
472131
|
return `<template id="scene-${id}-template">
|
|
472016
472132
|
<div data-composition-id="${id}" data-start="0" data-duration="${dur}" data-width="${input3.width}" data-height="${input3.height}">
|
|
472017
472133
|
<style>
|
|
472018
472134
|
${parts.css}
|
|
472019
472135
|
</style>
|
|
472020
472136
|
|
|
472021
|
-
${parts.body}
|
|
472137
|
+
${parts.body}${lottieMarkup}
|
|
472022
472138
|
${audioBlock}
|
|
472023
|
-
<script src="${GSAP_CDN}"></script
|
|
472139
|
+
<script src="${GSAP_CDN}"></script>${lottieScript}
|
|
472024
472140
|
<script>
|
|
472025
472141
|
window.__timelines = window.__timelines || {};
|
|
472026
472142
|
const tl = gsap.timeline({ paused: true });
|
|
@@ -472435,9 +472551,40 @@ sceneCommand.command("add").description("Add a new scene to a project: AI narrat
|
|
|
472435
472551
|
).option("--no-image", "Skip image generation even when --visuals is provided").option(
|
|
472436
472552
|
"--no-transcribe",
|
|
472437
472553
|
"Skip Whisper word-level transcribe step (no transcript-<id>.json emitted)"
|
|
472438
|
-
).option("--transcribe-language <code>", "BCP-47 language code passed to Whisper (e.g. en, ko)").option("--force", "Overwrite an existing compositions/scene-<id>.html").option("--
|
|
472554
|
+
).option("--transcribe-language <code>", "BCP-47 language code passed to Whisper (e.g. en, ko)").option("--force", "Overwrite an existing compositions/scene-<id>.html").option("--lottie <path>", "Lottie animation file (.json/.lottie) to overlay on the scene").option(
|
|
472555
|
+
"--lottie-position <position>",
|
|
472556
|
+
`Lottie position: ${LOTTIE_POSITIONS.join(", ")}`,
|
|
472557
|
+
"full"
|
|
472558
|
+
).option("--lottie-scale <number>", "Lottie overlay scale (0.01-2)").option("--lottie-opacity <number>", "Lottie overlay opacity (0-1)", "1").option("--lottie-no-loop", "Do not loop the Lottie animation").option("--dry-run", "Preview parameters without writing files or calling APIs").action(async (name, options) => {
|
|
472439
472559
|
const startedAt = Date.now();
|
|
472440
472560
|
if (options.style) options.style = validatePreset(options.style);
|
|
472561
|
+
if (options.lottiePosition) {
|
|
472562
|
+
if (!LOTTIE_POSITIONS.includes(options.lottiePosition)) {
|
|
472563
|
+
exitWithError(
|
|
472564
|
+
usageError(
|
|
472565
|
+
`Invalid --lottie-position "${options.lottiePosition}". Valid: ${LOTTIE_POSITIONS.join(", ")}`
|
|
472566
|
+
)
|
|
472567
|
+
);
|
|
472568
|
+
}
|
|
472569
|
+
}
|
|
472570
|
+
let lottieScale;
|
|
472571
|
+
if (options.lottieScale !== void 0) {
|
|
472572
|
+
lottieScale = Number(options.lottieScale);
|
|
472573
|
+
if (!Number.isFinite(lottieScale) || lottieScale < 0.01 || lottieScale > 2) {
|
|
472574
|
+
exitWithError(
|
|
472575
|
+
usageError(`Invalid --lottie-scale "${options.lottieScale}". Must be between 0.01 and 2.`)
|
|
472576
|
+
);
|
|
472577
|
+
}
|
|
472578
|
+
}
|
|
472579
|
+
let lottieOpacity = 1;
|
|
472580
|
+
if (options.lottieOpacity !== void 0) {
|
|
472581
|
+
lottieOpacity = Number(options.lottieOpacity);
|
|
472582
|
+
if (!Number.isFinite(lottieOpacity) || lottieOpacity < 0 || lottieOpacity > 1) {
|
|
472583
|
+
exitWithError(
|
|
472584
|
+
usageError(`Invalid --lottie-opacity "${options.lottieOpacity}". Must be between 0 and 1.`)
|
|
472585
|
+
);
|
|
472586
|
+
}
|
|
472587
|
+
}
|
|
472441
472588
|
if (options.duration !== void 0) options.duration = validateDuration(options.duration);
|
|
472442
472589
|
let tts;
|
|
472443
472590
|
try {
|
|
@@ -472466,7 +472613,11 @@ sceneCommand.command("add").description("Add a new scene to a project: AI narrat
|
|
|
472466
472613
|
imageProvider: options.imageProvider,
|
|
472467
472614
|
tts,
|
|
472468
472615
|
audio: options.audio,
|
|
472469
|
-
|
|
472616
|
+
lottie: options.lottie ?? null,
|
|
472617
|
+
lottiePosition: options.lottiePosition,
|
|
472618
|
+
lottieScale: lottieScale ?? null,
|
|
472619
|
+
lottieOpacity: options.lottieOpacity !== void 0 ? lottieOpacity : null,
|
|
472620
|
+
lottieLoop: !options.lottieNoLoop,
|
|
472470
472621
|
image: options.image
|
|
472471
472622
|
}
|
|
472472
472623
|
}
|
|
@@ -472494,6 +472645,13 @@ sceneCommand.command("add").description("Add a new scene to a project: AI narrat
|
|
|
472494
472645
|
skipTranscribe: options.transcribe === false,
|
|
472495
472646
|
transcribeLanguage: options.transcribeLanguage,
|
|
472496
472647
|
force: !!options.force,
|
|
472648
|
+
lottie: options.lottie ? {
|
|
472649
|
+
src: options.lottie,
|
|
472650
|
+
position: options.lottiePosition ?? "full",
|
|
472651
|
+
scale: lottieScale,
|
|
472652
|
+
opacity: options.lottieOpacity !== void 0 ? lottieOpacity : 1,
|
|
472653
|
+
loop: !options.lottieNoLoop
|
|
472654
|
+
} : void 0,
|
|
472497
472655
|
onProgress: (msg) => {
|
|
472498
472656
|
if (spinner2) spinner2.text = msg;
|
|
472499
472657
|
}
|
|
@@ -472769,6 +472927,30 @@ async function executeSceneAdd(opts) {
|
|
|
472769
472927
|
await writeFile10(imageAbsPath, buffer);
|
|
472770
472928
|
}
|
|
472771
472929
|
}
|
|
472930
|
+
let lottieRelPath;
|
|
472931
|
+
let lottieAbsPath;
|
|
472932
|
+
let lottieInput;
|
|
472933
|
+
if (opts.lottie) {
|
|
472934
|
+
const sourceAbs = resolve122(opts.lottie.src);
|
|
472935
|
+
if (!await pathExists2(sourceAbs)) {
|
|
472936
|
+
return errResult(`Lottie file not found: ${sourceAbs}`);
|
|
472937
|
+
}
|
|
472938
|
+
const ext = (sourceAbs.match(/\.([a-z0-9]+)$/i)?.[1] ?? "json").toLowerCase();
|
|
472939
|
+
if (ext !== "json" && ext !== "lottie") {
|
|
472940
|
+
return errResult(`Unsupported Lottie file extension: .${ext}. Use .json or .lottie.`);
|
|
472941
|
+
}
|
|
472942
|
+
lottieRelPath = `assets/lottie-${id}.${ext}`;
|
|
472943
|
+
lottieAbsPath = resolve122(projectDir, lottieRelPath);
|
|
472944
|
+
await mkdir5(dirname33(lottieAbsPath), { recursive: true });
|
|
472945
|
+
await copyFile6(sourceAbs, lottieAbsPath);
|
|
472946
|
+
lottieInput = {
|
|
472947
|
+
src: lottieRelPath,
|
|
472948
|
+
position: opts.lottie.position,
|
|
472949
|
+
scale: opts.lottie.scale,
|
|
472950
|
+
opacity: opts.lottie.opacity,
|
|
472951
|
+
loop: opts.lottie.loop
|
|
472952
|
+
};
|
|
472953
|
+
}
|
|
472772
472954
|
const cfg = await loadVibeProjectConfig(projectDir);
|
|
472773
472955
|
const fallback2 = cfg?.defaultSceneDuration ?? 5;
|
|
472774
472956
|
const NARRATION_TAIL_BUFFER = 0.5;
|
|
@@ -472797,7 +472979,8 @@ async function executeSceneAdd(opts) {
|
|
|
472797
472979
|
kicker: opts.kicker,
|
|
472798
472980
|
imagePath: imageRelPath,
|
|
472799
472981
|
audioPath: audioRelPath,
|
|
472800
|
-
transcript: transcriptWords
|
|
472982
|
+
transcript: transcriptWords,
|
|
472983
|
+
lottie: lottieInput
|
|
472801
472984
|
});
|
|
472802
472985
|
await mkdir5(dirname33(scenePath), { recursive: true });
|
|
472803
472986
|
await writeFile10(scenePath, sceneHtml, "utf-8");
|
|
@@ -472818,6 +473001,7 @@ async function executeSceneAdd(opts) {
|
|
|
472818
473001
|
rootPath: relative5(process.cwd(), rootPath) || rootPath,
|
|
472819
473002
|
audioPath: audioAbsPath ? relative5(process.cwd(), audioAbsPath) || audioAbsPath : void 0,
|
|
472820
473003
|
imagePath: imageAbsPath ? relative5(process.cwd(), imageAbsPath) || imageAbsPath : void 0,
|
|
473004
|
+
lottiePath: lottieAbsPath ? relative5(process.cwd(), lottieAbsPath) || lottieAbsPath : void 0,
|
|
472821
473005
|
transcriptPath: transcriptAbsPath ? relative5(process.cwd(), transcriptAbsPath) || transcriptAbsPath : void 0,
|
|
472822
473006
|
transcriptWordCount
|
|
472823
473007
|
};
|
|
@@ -474070,7 +474254,7 @@ var editMotionOverlayTool = defineTool({
|
|
|
474070
474254
|
duration: external_exports.number().optional().describe("Overlay/render duration in seconds"),
|
|
474071
474255
|
start: external_exports.number().optional().describe("Overlay start time in seconds"),
|
|
474072
474256
|
style: external_exports.string().optional().describe("Style preset for generated overlays"),
|
|
474073
|
-
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-3.1-pro"]).optional().describe("LLM model for generated overlays"),
|
|
474257
|
+
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-2.5-pro", "gemini-3.1-pro"]).optional().describe("LLM model for generated overlays"),
|
|
474074
474258
|
understand: external_exports.enum(["auto", "off", "required"]).optional().describe("Analyze video before generated overlay (default: auto)"),
|
|
474075
474259
|
understandingPrompt: external_exports.string().optional().describe("Custom prompt for video understanding"),
|
|
474076
474260
|
position: external_exports.enum(["full", "center", "top-left", "top-right", "bottom-left", "bottom-right"]).optional().describe("Lottie overlay position"),
|
|
@@ -475785,7 +475969,7 @@ var inspectRenderTool = defineTool({
|
|
|
475785
475969
|
outputPath: external_exports.string().optional().describe("Optional review report path. Defaults to <project>/review-report.json."),
|
|
475786
475970
|
report: external_exports.boolean().optional().describe("Write review-report.json. Default true."),
|
|
475787
475971
|
ai: external_exports.boolean().optional().describe("Also run Gemini video review and merge findings into review-report.json. Default false."),
|
|
475788
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant for ai review. Default flash."),
|
|
475972
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant for ai review. Default flash."),
|
|
475789
475973
|
dryRun: external_exports.boolean().optional().describe("Preview resolved inputs without probing video or calling Gemini.")
|
|
475790
475974
|
}),
|
|
475791
475975
|
async execute(args, ctx) {
|
|
@@ -475837,7 +476021,7 @@ var analyzeMediaTool = defineTool({
|
|
|
475837
476021
|
schema: external_exports.object({
|
|
475838
476022
|
source: external_exports.string().describe("Path to image/video or YouTube URL"),
|
|
475839
476023
|
prompt: external_exports.string().describe("Analysis prompt (e.g., 'Describe the scene', 'Count people')"),
|
|
475840
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant (default: flash)"),
|
|
476024
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant (default: flash)"),
|
|
475841
476025
|
fps: external_exports.number().optional().describe("Frames per second for video sampling (default: 1)"),
|
|
475842
476026
|
start: external_exports.number().optional().describe("Start time in seconds for video analysis"),
|
|
475843
476027
|
end: external_exports.number().optional().describe("End time in seconds for video analysis"),
|
|
@@ -475865,7 +476049,7 @@ var analyzeVideoTool = defineTool({
|
|
|
475865
476049
|
schema: external_exports.object({
|
|
475866
476050
|
source: external_exports.string().describe("Path to video file"),
|
|
475867
476051
|
prompt: external_exports.string().describe("Analysis prompt"),
|
|
475868
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant (default: flash)"),
|
|
476052
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant (default: flash)"),
|
|
475869
476053
|
fps: external_exports.number().optional().describe("Frames per second for sampling"),
|
|
475870
476054
|
start: external_exports.number().optional().describe("Start time in seconds"),
|
|
475871
476055
|
end: external_exports.number().optional().describe("End time in seconds"),
|
|
@@ -475895,7 +476079,7 @@ var analyzeReviewTool = defineTool({
|
|
|
475895
476079
|
storyboardPath: external_exports.string().optional().describe("Path to storyboard.json for intent comparison"),
|
|
475896
476080
|
autoApply: external_exports.boolean().optional().describe("Automatically apply suggested fixes (default: false)"),
|
|
475897
476081
|
verify: external_exports.boolean().optional().describe("Re-review after applying fixes (default: false)"),
|
|
475898
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant (default: flash)"),
|
|
476082
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant (default: flash)"),
|
|
475899
476083
|
outputPath: external_exports.string().optional().describe("Output path for fixed video")
|
|
475900
476084
|
}),
|
|
475901
476085
|
async execute(args) {
|
|
@@ -475977,7 +476161,7 @@ var generateMotionTool = defineTool({
|
|
|
475977
476161
|
"Analyze the base video with Gemini before generating motion graphics: auto, off, or required (default: auto)"
|
|
475978
476162
|
),
|
|
475979
476163
|
understandingPrompt: external_exports.string().optional().describe("Custom prompt for video understanding when --video is provided"),
|
|
475980
|
-
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-3.1-pro"]).optional().describe("LLM model for code generation (default: sonnet)"),
|
|
476164
|
+
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-2.5-pro", "gemini-3.1-pro"]).optional().describe("LLM model for code generation (default: sonnet)"),
|
|
475981
476165
|
output: external_exports.string().optional().describe("Output path (TSX if code-only, MP4 if rendered)")
|
|
475982
476166
|
}),
|
|
475983
476167
|
async execute(args) {
|
|
@@ -476242,6 +476426,7 @@ var generateVideoTool = defineTool({
|
|
|
476242
476426
|
"Video provider (default: seedance when FAL_API_KEY is configured, otherwise first configured provider)"
|
|
476243
476427
|
),
|
|
476244
476428
|
image: external_exports.string().optional().describe("Reference image path for image-to-video"),
|
|
476429
|
+
endImage: external_exports.string().optional().describe("Ending frame image path for Seedance image-to-video"),
|
|
476245
476430
|
refImages: external_exports.array(external_exports.string()).optional().describe("Reference images for Seedance reference-to-video"),
|
|
476246
476431
|
refVideos: external_exports.array(external_exports.string()).optional().describe("Reference videos for Seedance reference-to-video"),
|
|
476247
476432
|
refAudio: external_exports.array(external_exports.string()).optional().describe("Reference audio files for Seedance reference-to-video"),
|
|
@@ -476249,7 +476434,7 @@ var generateVideoTool = defineTool({
|
|
|
476249
476434
|
ratio: external_exports.string().optional().describe("Aspect ratio: 16:9, 9:16, 1:1 (default: 16:9)"),
|
|
476250
476435
|
mode: external_exports.string().optional().describe("Kling mode: std or pro"),
|
|
476251
476436
|
negative: external_exports.string().optional().describe("Negative prompt (Seedance/Kling/Veo)"),
|
|
476252
|
-
resolution: external_exports.string().optional().describe("Resolution: 720p, 1080p, 4k
|
|
476437
|
+
resolution: external_exports.string().optional().describe("Resolution: 480p, 720p, 1080p, or 4k depending on provider"),
|
|
476253
476438
|
veoModel: external_exports.string().optional().describe("Veo model: 3.0, 3.1, 3.1-fast"),
|
|
476254
476439
|
runwayModel: external_exports.string().optional().describe("Runway model: gen4.5, gen4_turbo"),
|
|
476255
476440
|
seedanceModel: external_exports.string().optional().describe("Seedance variant: quality or fast (fal.ai only)"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.106.0",
|
|
4
4
|
"description": "VibeFrame MCP Server - AI-native video editing via Model Context Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -57,8 +57,8 @@
|
|
|
57
57
|
"tsx": "^4.21.0",
|
|
58
58
|
"typescript": "^5.3.3",
|
|
59
59
|
"vitest": "^1.2.2",
|
|
60
|
-
"@vibeframe/cli": "0.
|
|
61
|
-
"@vibeframe/core": "0.
|
|
60
|
+
"@vibeframe/cli": "0.106.0",
|
|
61
|
+
"@vibeframe/core": "0.106.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=20"
|