@vibeframe/mcp-server 0.104.1 → 0.104.3
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 +96 -42
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -7613,7 +7613,7 @@ YAML cues that drive narration, backdrop generation, and timing.
|
|
|
7613
7613
|
|
|
7614
7614
|
\`\`\`yaml
|
|
7615
7615
|
narration: "Introduce the promise in one crisp sentence."
|
|
7616
|
-
backdrop: "
|
|
7616
|
+
backdrop: "Topic-aligned editorial background plate, abstract visual system, no readable text, no logos, no consumer products, clean negative space for HTML overlays"
|
|
7617
7617
|
duration: 4
|
|
7618
7618
|
\`\`\`
|
|
7619
7619
|
|
|
@@ -7624,7 +7624,7 @@ screen and one spoken breath.
|
|
|
7624
7624
|
|
|
7625
7625
|
\`\`\`yaml
|
|
7626
7626
|
narration: "Show the mechanism or proof point that makes the promise believable."
|
|
7627
|
-
backdrop: "
|
|
7627
|
+
backdrop: "Topic-aligned analytical background plate, abstract dashboard structure, no readable text, no product photos, no shoes, no unrelated objects"
|
|
7628
7628
|
duration: 4
|
|
7629
7629
|
\`\`\`
|
|
7630
7630
|
|
|
@@ -7635,7 +7635,7 @@ before/after.
|
|
|
7635
7635
|
|
|
7636
7636
|
\`\`\`yaml
|
|
7637
7637
|
narration: "Close with the action the viewer should remember."
|
|
7638
|
-
backdrop: "Resolved
|
|
7638
|
+
backdrop: "Resolved editorial background plate, confident final composition, clean negative space, no readable text, no logos, no unrelated products"
|
|
7639
7639
|
duration: 4
|
|
7640
7640
|
\`\`\`
|
|
7641
7641
|
|
|
@@ -7688,6 +7688,25 @@ consult this file \u2014 run the generate command directly.
|
|
|
7688
7688
|
Browse named styles: \`vibe scene list-styles\`. Re-seed from one with
|
|
7689
7689
|
\`vibe scene init . --visual-style "Swiss Pulse"\` (idempotent).
|
|
7690
7690
|
|
|
7691
|
+
## Provider keys and project scope
|
|
7692
|
+
|
|
7693
|
+
Use VibeFrame CLI generation for project assets:
|
|
7694
|
+
\`vibe generate image|video|speech ...\`. This lets VibeFrame use keys
|
|
7695
|
+
from \`vibe setup --scope project\`.
|
|
7696
|
+
|
|
7697
|
+
Project-scope keys may live in a parent directory, for example
|
|
7698
|
+
\`../.vibeframe/config.yaml\` when this scene was created by
|
|
7699
|
+
\`vibe init launch\`. The \`vibe\` CLI searches upward automatically, so do
|
|
7700
|
+
not decide keys are missing just because \`.vibeframe/config.yaml\` is not
|
|
7701
|
+
inside this scene folder.
|
|
7702
|
+
|
|
7703
|
+
To verify scope without exposing secrets, run \`vibe doctor --json\` from
|
|
7704
|
+
this directory and inspect \`data.scope.activeScope\` plus
|
|
7705
|
+
\`data.scope.project.configPath\`. Never print config contents. Do not use
|
|
7706
|
+
a host agent's built-in image/audio generation tool for VibeFrame project
|
|
7707
|
+
assets unless the user explicitly requests an external, non-VibeFrame
|
|
7708
|
+
asset.
|
|
7709
|
+
|
|
7691
7710
|
## Skills \u2014 USE THESE FIRST
|
|
7692
7711
|
|
|
7693
7712
|
@SKILL.md
|
|
@@ -7749,7 +7768,11 @@ npx hyperframes render
|
|
|
7749
7768
|
\`\`\`
|
|
7750
7769
|
4. Videos use \`muted\` with a separate \`<audio>\` element for the audio track.
|
|
7751
7770
|
5. Sub-compositions use \`data-composition-src="compositions/file.html"\`.
|
|
7752
|
-
6.
|
|
7771
|
+
6. For render-stable text, do not apply continuous \`scale\`, \`x\`, \`y\`, or
|
|
7772
|
+
\`filter\` tweens to \`.scene-content\` or any ancestor containing live text.
|
|
7773
|
+
Animate background/media layers instead; text/cards should enter briefly and
|
|
7774
|
+
then hold still at their final CSS positions.
|
|
7775
|
+
7. Only deterministic logic \u2014 no \`Date.now()\`, \`Math.random()\`, or network fetches.
|
|
7753
7776
|
|
|
7754
7777
|
## Linting \u2014 run after changes
|
|
7755
7778
|
|
|
@@ -25916,21 +25939,8 @@ async function prompt(question, hidden = false) {
|
|
|
25916
25939
|
});
|
|
25917
25940
|
}
|
|
25918
25941
|
async function getApiKey(envVar, providerName, optionValue) {
|
|
25919
|
-
|
|
25920
|
-
|
|
25921
|
-
}
|
|
25922
|
-
const providerKey = providerKeyForEnvVar(envVar);
|
|
25923
|
-
if (providerKey) {
|
|
25924
|
-
const configKey = await getApiKeyFromConfig(providerKey);
|
|
25925
|
-
if (configKey) {
|
|
25926
|
-
return configKey;
|
|
25927
|
-
}
|
|
25928
|
-
}
|
|
25929
|
-
loadEnv();
|
|
25930
|
-
const envValue = getEnvValue2(envVar);
|
|
25931
|
-
if (envValue) {
|
|
25932
|
-
return envValue;
|
|
25933
|
-
}
|
|
25942
|
+
const configuredKey = await getConfiguredApiKey(envVar, optionValue);
|
|
25943
|
+
if (configuredKey) return configuredKey;
|
|
25934
25944
|
if (!process.stdin.isTTY) {
|
|
25935
25945
|
return null;
|
|
25936
25946
|
}
|
|
@@ -25951,6 +25961,19 @@ async function getApiKey(envVar, providerName, optionValue) {
|
|
|
25951
25961
|
}
|
|
25952
25962
|
return apiKey.trim();
|
|
25953
25963
|
}
|
|
25964
|
+
async function getConfiguredApiKey(envVar, optionValue, options = {}) {
|
|
25965
|
+
if (optionValue) return optionValue;
|
|
25966
|
+
const providerKey = providerKeyForEnvVar(envVar);
|
|
25967
|
+
if (providerKey) {
|
|
25968
|
+
const configKey = await getApiKeyFromConfig(providerKey, { cwd: options.cwd });
|
|
25969
|
+
if (configKey) return configKey;
|
|
25970
|
+
}
|
|
25971
|
+
loadEnv();
|
|
25972
|
+
return getEnvValue2(envVar);
|
|
25973
|
+
}
|
|
25974
|
+
async function hasConfiguredApiKey(envVar, optionValue, options = {}) {
|
|
25975
|
+
return Boolean(await getConfiguredApiKey(envVar, optionValue, options));
|
|
25976
|
+
}
|
|
25954
25977
|
function hasApiKey(envVar) {
|
|
25955
25978
|
loadEnv();
|
|
25956
25979
|
return !!getEnvValue2(envVar);
|
|
@@ -26047,7 +26070,7 @@ var init_api_key = __esm({
|
|
|
26047
26070
|
|
|
26048
26071
|
// ../cli/src/commands/_shared/tts-resolve.ts
|
|
26049
26072
|
async function resolveTtsProvider(preferred = "auto") {
|
|
26050
|
-
const choice = preferred === "auto" ?
|
|
26073
|
+
const choice = preferred === "auto" ? await getConfiguredApiKey("ELEVENLABS_API_KEY") ? "elevenlabs" : "kokoro" : preferred;
|
|
26051
26074
|
if (choice === "elevenlabs") {
|
|
26052
26075
|
return buildElevenLabs();
|
|
26053
26076
|
}
|
|
@@ -26091,7 +26114,6 @@ var init_tts_resolve = __esm({
|
|
|
26091
26114
|
"use strict";
|
|
26092
26115
|
init_dist();
|
|
26093
26116
|
init_api_key();
|
|
26094
|
-
init_api_key();
|
|
26095
26117
|
TtsKeyMissingError = class extends Error {
|
|
26096
26118
|
constructor(provider) {
|
|
26097
26119
|
super(
|
|
@@ -449161,13 +449183,18 @@ Requirements (non-negotiable):
|
|
|
449161
449183
|
producer's seek lands past the timeline's natural end and visibility state
|
|
449162
449184
|
goes stale \u2014 the hold phase renders BLACK. Anchor the timeline to the full
|
|
449163
449185
|
beat duration via either:
|
|
449164
|
-
1. A subtle idle motion spanning 0\u2192duration on a
|
|
449165
|
-
\`tl.fromTo(".
|
|
449186
|
+
1. A subtle idle motion spanning 0\u2192duration on a background/media layer,
|
|
449187
|
+
e.g. \`tl.fromTo(".backdrop", { scale: 1.0 }, { scale: 1.015, duration: <beat>, ease: "none" }, 0);\`
|
|
449166
449188
|
(Ken-Burns, breathing opacity, gradient drift \u2014 should be barely
|
|
449167
449189
|
perceptible so it doesn't compete with entry/exit beats).
|
|
449168
449190
|
2. OR an explicit \`tl.set(target, { ...natural state... }, <beat - 0.001>)\`
|
|
449169
449191
|
anchor at the end.
|
|
449170
449192
|
This is the #2 source of "text disappears mid-beat" bugs after \`.clip\` sizing.
|
|
449193
|
+
- Do not apply continuous \`scale\`, \`x\`, \`y\`, \`filter\`, or other transform
|
|
449194
|
+
tweens to \`.scene-content\` or any ancestor that contains live text/cards.
|
|
449195
|
+
Animate the backdrop/media plane instead; let text enter briefly, then hold
|
|
449196
|
+
still at its final CSS position. Continuous transforms on text ancestors can
|
|
449197
|
+
create subpixel shimmer in screenshot-captured renders.
|
|
449171
449198
|
- Timed children inside the composition have \`class="clip"\` plus
|
|
449172
449199
|
\`data-start\`, \`data-duration\`, \`data-track-index\`.
|
|
449173
449200
|
- If \`assets/backdrop-${ctx.beat.id}.png\` exists, use that local file as the
|
|
@@ -449237,7 +449264,9 @@ Reference shape (verbatim \u2014 match this skeleton exactly, no DOCTYPE / html
|
|
|
449237
449264
|
const tl = gsap.timeline({ paused: true });
|
|
449238
449265
|
// Idle motion spanning full beat duration \u2014 required to keep timeline
|
|
449239
449266
|
// length aligned with data-duration (otherwise hold phase goes black).
|
|
449240
|
-
|
|
449267
|
+
// Keep continuous motion on the background/media layer so live text does
|
|
449268
|
+
// not shimmer from subpixel resampling.
|
|
449269
|
+
tl.fromTo(".backdrop", { scale: 1.0 }, { scale: 1.015, duration: <sec>, ease: "none" }, 0);
|
|
449241
449270
|
// entry tweens
|
|
449242
449271
|
window.__timelines["${compositionId}"] = tl;
|
|
449243
449272
|
</script>
|
|
@@ -451179,6 +451208,32 @@ var init_build_asset_metadata = __esm({
|
|
|
451179
451208
|
}
|
|
451180
451209
|
});
|
|
451181
451210
|
|
|
451211
|
+
// ../cli/src/commands/_shared/build-backdrop-prompt.ts
|
|
451212
|
+
function augmentBackdropPrompt(cue) {
|
|
451213
|
+
const trimmed = cue.trim();
|
|
451214
|
+
const lower = trimmed.toLowerCase();
|
|
451215
|
+
const requestsTextOrMarks = /\b(text|typography|title|headline|label|caption|logo|logos|wordmark|brand mark|brand marks)\b/.test(lower);
|
|
451216
|
+
const forbidsTextOrMarks = /\b(no|without|avoid)\s+(readable\s+)?(text|typography|titles?|headlines?|labels?|captions?|brand\s+logos?|logos?|wordmarks?|brand\s+marks?)\b/.test(
|
|
451217
|
+
lower
|
|
451218
|
+
);
|
|
451219
|
+
const allowsTextOrMarks = requestsTextOrMarks && !forbidsTextOrMarks;
|
|
451220
|
+
const overlayContract = allowsTextOrMarks ? "The image is a video background or end-card plate; do not add any text, logos, charts, or UI beyond what the scene cue explicitly requests." : "The image is a background only; HTML overlays will provide all final text, charts, logos, and UI labels.";
|
|
451221
|
+
const textRule = allowsTextOrMarks ? "If text, logos, or brand marks are explicitly requested, keep them minimal, legible, and do not invent extras." : "No readable text, labels, UI copy, logos, brand marks, watermarks, or invented typography.";
|
|
451222
|
+
return [
|
|
451223
|
+
"Create a 16:9 video background plate for a HyperFrames scene.",
|
|
451224
|
+
overlayContract,
|
|
451225
|
+
`Scene cue: ${trimmed}`,
|
|
451226
|
+
textRule,
|
|
451227
|
+
"Avoid unrelated consumer product photography, shoes, packaging, food, people, celebrity faces, advertisements, and random objects unless explicitly requested by the scene cue.",
|
|
451228
|
+
"Leave generous negative space for overlay text and cards. Keep the result topic-aligned, editorial, cinematic, and non-distracting."
|
|
451229
|
+
].join(" ");
|
|
451230
|
+
}
|
|
451231
|
+
var init_build_backdrop_prompt = __esm({
|
|
451232
|
+
"../cli/src/commands/_shared/build-backdrop-prompt.ts"() {
|
|
451233
|
+
"use strict";
|
|
451234
|
+
}
|
|
451235
|
+
});
|
|
451236
|
+
|
|
451182
451237
|
// ../cli/src/commands/_shared/storyboard-edit.ts
|
|
451183
451238
|
function validateStoryboardMarkdown(markdown) {
|
|
451184
451239
|
const parsed = parseStoryboard(markdown);
|
|
@@ -451463,6 +451518,7 @@ async function createBuildPlan(opts) {
|
|
|
451463
451518
|
const voice = stringOrUndefined3(cue.voice) ?? resolved.voice;
|
|
451464
451519
|
const narrationText = stringOrUndefined3(cue.narration);
|
|
451465
451520
|
const backdropPrompt = stringOrUndefined3(cue.backdrop);
|
|
451521
|
+
const augmentedBackdropPrompt = backdropPrompt ? augmentBackdropPrompt(backdropPrompt) : null;
|
|
451466
451522
|
const videoPrompt = stringOrUndefined3(cue.video);
|
|
451467
451523
|
const musicPrompt = stringOrUndefined3(cue.music);
|
|
451468
451524
|
const genericReference = resolveGenericAssetReference(projectDir, cue.asset);
|
|
@@ -451482,9 +451538,9 @@ async function createBuildPlan(opts) {
|
|
|
451482
451538
|
voice,
|
|
451483
451539
|
ext: resolved.narration.resolved === "elevenlabs" ? "mp3" : "wav"
|
|
451484
451540
|
}) : null;
|
|
451485
|
-
const backdropCache =
|
|
451541
|
+
const backdropCache = augmentedBackdropPrompt && !backdropReference ? backdropCacheDescriptor({
|
|
451486
451542
|
beatId: beat.id,
|
|
451487
|
-
cue:
|
|
451543
|
+
cue: augmentedBackdropPrompt,
|
|
451488
451544
|
provider: resolved.image.resolved,
|
|
451489
451545
|
quality: imageQuality,
|
|
451490
451546
|
size: imageSize2,
|
|
@@ -452014,6 +452070,7 @@ var init_build_plan = __esm({
|
|
|
452014
452070
|
init_build_asset_reference();
|
|
452015
452071
|
init_build_cache();
|
|
452016
452072
|
init_build_asset_metadata();
|
|
452073
|
+
init_build_backdrop_prompt();
|
|
452017
452074
|
init_composer_resolve();
|
|
452018
452075
|
init_storyboard_parse();
|
|
452019
452076
|
init_project_config();
|
|
@@ -452436,7 +452493,7 @@ async function executeVideoGenerate(options) {
|
|
|
452436
452493
|
fal: "FAL_API_KEY"
|
|
452437
452494
|
};
|
|
452438
452495
|
const envKey = envKeyMap[provider] || "";
|
|
452439
|
-
const key2 =
|
|
452496
|
+
const key2 = await getConfiguredApiKey(envKey, apiKey);
|
|
452440
452497
|
if (!key2) return { success: false, error: `${envKeyMap[provider]} required for ${provider}` };
|
|
452441
452498
|
let referenceImage;
|
|
452442
452499
|
let referenceImageBuffer;
|
|
@@ -452868,7 +452925,7 @@ var init_validate = __esm({
|
|
|
452868
452925
|
// ../cli/src/commands/generate/music-status.ts
|
|
452869
452926
|
async function executeMusicStatus(options) {
|
|
452870
452927
|
try {
|
|
452871
|
-
const apiKey =
|
|
452928
|
+
const apiKey = await getConfiguredApiKey("REPLICATE_API_TOKEN", options.apiKey);
|
|
452872
452929
|
if (!apiKey)
|
|
452873
452930
|
return { success: false, error: "REPLICATE_API_TOKEN required for music status" };
|
|
452874
452931
|
const replicate = new ReplicateProvider();
|
|
@@ -452941,7 +452998,6 @@ var init_music_status = __esm({
|
|
|
452941
452998
|
init_source();
|
|
452942
452999
|
init_dist();
|
|
452943
453000
|
init_api_key();
|
|
452944
|
-
init_config();
|
|
452945
453001
|
init_output();
|
|
452946
453002
|
}
|
|
452947
453003
|
});
|
|
@@ -453741,7 +453797,7 @@ async function executeMusic(options) {
|
|
|
453741
453797
|
try {
|
|
453742
453798
|
const provider = options.provider || "elevenlabs";
|
|
453743
453799
|
if (provider === "elevenlabs") {
|
|
453744
|
-
const apiKey2 =
|
|
453800
|
+
const apiKey2 = await getConfiguredApiKey("ELEVENLABS_API_KEY");
|
|
453745
453801
|
if (!apiKey2)
|
|
453746
453802
|
return {
|
|
453747
453803
|
success: false,
|
|
@@ -453761,7 +453817,7 @@ async function executeMusic(options) {
|
|
|
453761
453817
|
await writeFile18(outputPath2, result2.audioBuffer);
|
|
453762
453818
|
return { success: true, outputPath: outputPath2, provider: "elevenlabs", duration: duration2 };
|
|
453763
453819
|
}
|
|
453764
|
-
const apiKey =
|
|
453820
|
+
const apiKey = await getConfiguredApiKey("REPLICATE_API_TOKEN");
|
|
453765
453821
|
if (!apiKey)
|
|
453766
453822
|
return {
|
|
453767
453823
|
success: false,
|
|
@@ -453996,7 +454052,6 @@ var init_music = __esm({
|
|
|
453996
454052
|
init_ora();
|
|
453997
454053
|
init_dist();
|
|
453998
454054
|
init_api_key();
|
|
453999
|
-
init_config();
|
|
454000
454055
|
init_output();
|
|
454001
454056
|
init_validate();
|
|
454002
454057
|
init_status_jobs();
|
|
@@ -454770,8 +454825,9 @@ async function dispatchNarration(beat, ctx) {
|
|
|
454770
454825
|
async function dispatchBackdrop(beat, ctx) {
|
|
454771
454826
|
const reference = assetReferenceForBeat(ctx.projectDir, "backdrop", beat);
|
|
454772
454827
|
if (reference) return referencePrimitiveOutcome("backdrop", beat, ctx, reference);
|
|
454773
|
-
const
|
|
454774
|
-
if (!
|
|
454828
|
+
const cue = stringOrUndefined4(beat.cues?.backdrop);
|
|
454829
|
+
if (!cue) return { status: "no-cue" };
|
|
454830
|
+
const prompt3 = augmentBackdropPrompt(cue);
|
|
454775
454831
|
const rel = `assets/backdrop-${beat.id}.png`;
|
|
454776
454832
|
const abs = join33(ctx.projectDir, rel);
|
|
454777
454833
|
const size = ctx.imageSize ?? "1536x1024";
|
|
@@ -455749,6 +455805,7 @@ var init_scene_build = __esm({
|
|
|
455749
455805
|
init_root_sync();
|
|
455750
455806
|
init_build_cache();
|
|
455751
455807
|
init_build_asset_metadata();
|
|
455808
|
+
init_build_backdrop_prompt();
|
|
455752
455809
|
init_ai_video();
|
|
455753
455810
|
init_music();
|
|
455754
455811
|
init_status_jobs();
|
|
@@ -462409,7 +462466,7 @@ import { resolve as resolve54 } from "node:path";
|
|
|
462409
462466
|
import { writeFile as writeFile32 } from "node:fs/promises";
|
|
462410
462467
|
async function executeSoundEffect(options) {
|
|
462411
462468
|
try {
|
|
462412
|
-
const apiKey =
|
|
462469
|
+
const apiKey = await getConfiguredApiKey("ELEVENLABS_API_KEY");
|
|
462413
462470
|
if (!apiKey)
|
|
462414
462471
|
return {
|
|
462415
462472
|
success: false,
|
|
@@ -462508,7 +462565,6 @@ var init_sound_effect = __esm({
|
|
|
462508
462565
|
init_ora();
|
|
462509
462566
|
init_dist();
|
|
462510
462567
|
init_api_key();
|
|
462511
|
-
init_config();
|
|
462512
462568
|
init_output();
|
|
462513
462569
|
init_validate();
|
|
462514
462570
|
}
|
|
@@ -462590,7 +462646,7 @@ import { resolve as resolve55, dirname as dirname30 } from "node:path";
|
|
|
462590
462646
|
import { writeFile as writeFile33, mkdir as mkdir23 } from "node:fs/promises";
|
|
462591
462647
|
async function executeBackground(options) {
|
|
462592
462648
|
try {
|
|
462593
|
-
const apiKey =
|
|
462649
|
+
const apiKey = await getConfiguredApiKey("OPENAI_API_KEY", options.apiKey);
|
|
462594
462650
|
if (!apiKey)
|
|
462595
462651
|
return { success: false, error: "OPENAI_API_KEY required for background generation" };
|
|
462596
462652
|
const openaiImage = new OpenAIImageProvider();
|
|
@@ -462721,7 +462777,6 @@ var init_background = __esm({
|
|
|
462721
462777
|
init_ora();
|
|
462722
462778
|
init_dist();
|
|
462723
462779
|
init_api_key();
|
|
462724
|
-
init_config();
|
|
462725
462780
|
init_output();
|
|
462726
462781
|
init_validate();
|
|
462727
462782
|
}
|
|
@@ -462962,7 +463017,7 @@ import { resolve as resolve57 } from "node:path";
|
|
|
462962
463017
|
import { writeFile as writeFile35 } from "node:fs/promises";
|
|
462963
463018
|
async function executeSpeech(options) {
|
|
462964
463019
|
try {
|
|
462965
|
-
const apiKey =
|
|
463020
|
+
const apiKey = await getConfiguredApiKey("ELEVENLABS_API_KEY");
|
|
462966
463021
|
if (!apiKey)
|
|
462967
463022
|
return {
|
|
462968
463023
|
success: false,
|
|
@@ -463177,7 +463232,6 @@ var init_speech = __esm({
|
|
|
463177
463232
|
init_dist();
|
|
463178
463233
|
init_api_key();
|
|
463179
463234
|
init_tty();
|
|
463180
|
-
init_config();
|
|
463181
463235
|
init_output();
|
|
463182
463236
|
init_validate();
|
|
463183
463237
|
}
|
|
@@ -463978,7 +464032,7 @@ Examples:
|
|
|
463978
464032
|
)
|
|
463979
464033
|
);
|
|
463980
464034
|
}
|
|
463981
|
-
if (providerEnvMap[provider] && !
|
|
464035
|
+
if (providerEnvMap[provider] && !await hasConfiguredApiKey(providerEnvMap[provider], options.apiKey)) {
|
|
463982
464036
|
const resolved = resolveProvider("image");
|
|
463983
464037
|
if (resolved) {
|
|
463984
464038
|
log(source_default.dim(` ${provider} key not found. Using ${resolved.label} instead.`));
|
|
@@ -465418,7 +465472,7 @@ Examples:
|
|
|
465418
465472
|
);
|
|
465419
465473
|
provider = "seedance";
|
|
465420
465474
|
}
|
|
465421
|
-
if (videoEnvMap[provider] && !
|
|
465475
|
+
if (videoEnvMap[provider] && !await hasConfiguredApiKey(videoEnvMap[provider], options.apiKey)) {
|
|
465422
465476
|
const resolved = resolveProvider("video");
|
|
465423
465477
|
if (resolved) {
|
|
465424
465478
|
log(source_default.dim(` ${provider} key not found. Using ${resolved.label} instead.`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeframe/mcp-server",
|
|
3
|
-
"version": "0.104.
|
|
3
|
+
"version": "0.104.3",
|
|
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.104.
|
|
61
|
-
"@vibeframe/core": "0.104.
|
|
60
|
+
"@vibeframe/cli": "0.104.3",
|
|
61
|
+
"@vibeframe/core": "0.104.3"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=20"
|