@vibeframe/mcp-server 0.102.0 → 0.103.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +192 -57
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -7643,9 +7643,14 @@ End on the product name, offer, or command. Avoid adding a new idea in the
7643
7643
  final beat.
7644
7644
  `;
7645
7645
  }
7646
- function buildProjectClaudeMd(name) {
7646
+ function buildProjectAgentsMd(name) {
7647
7647
  return `# ${name} \u2014 Scene Authoring Project
7648
7648
 
7649
+ This is the canonical cross-agent guidance file for this scene project.
7650
+ Claude Code imports it through \`CLAUDE.md\`; Codex, Cursor, Aider,
7651
+ Gemini CLI, OpenCode, and other bash-capable agents should read it
7652
+ directly.
7653
+
7649
7654
  This project is **bilingual**: it works with both VibeFrame (\`vibe\`) and
7650
7655
  HeyGen Hyperframes (\`hyperframes\`). You can run either CLI inside this
7651
7656
  directory.
@@ -7685,6 +7690,8 @@ Browse named styles: \`vibe scene list-styles\`. Re-seed from one with
7685
7690
 
7686
7691
  ## Skills \u2014 USE THESE FIRST
7687
7692
 
7693
+ @SKILL.md
7694
+
7688
7695
  **Always invoke the relevant skill before authoring scenes.** Skills encode
7689
7696
  framework-specific patterns (GSAP timeline registration, data-attribute
7690
7697
  semantics, VibeFrame pipeline conventions) that are NOT in generic web docs.
@@ -7753,6 +7760,17 @@ vibe scene lint --json # structured output for agent loops
7753
7760
  \`\`\`
7754
7761
  `;
7755
7762
  }
7763
+ function buildProjectClaudeMd(name) {
7764
+ return `@AGENTS.md
7765
+
7766
+ # ${name} \u2014 Claude Code Overrides
7767
+
7768
+ This file imports \`AGENTS.md\`; keep cross-agent VibeFrame and
7769
+ Hyperframes instructions there so Codex, Cursor, Aider, Gemini CLI, and
7770
+ OpenCode see the same project rules. Add Claude-Code-specific notes below
7771
+ only when this project needs them.
7772
+ `;
7773
+ }
7756
7774
  function buildSceneGitignore() {
7757
7775
  return `# VibeFrame \u2014 caches, checkpoints, and project-scope config.yaml (may contain API keys)
7758
7776
  .vibeframe/
@@ -7792,6 +7810,7 @@ function describeSceneScaffold(opts) {
7792
7810
  }
7793
7811
  if (profile === "agent" || profile === "full") {
7794
7812
  groups.agent = [
7813
+ resolve2(dir, "AGENTS.md"),
7795
7814
  resolve2(dir, "SKILL.md"),
7796
7815
  resolve2(dir, "references"),
7797
7816
  resolve2(dir, "CLAUDE.md")
@@ -7871,9 +7890,24 @@ async function scaffoldSceneProject(opts) {
7871
7890
  created.push(vibePath);
7872
7891
  }
7873
7892
  if (profile === "agent" || profile === "full") {
7893
+ const agentsPath = resolve2(dir, "AGENTS.md");
7894
+ if (await pathExists(agentsPath)) {
7895
+ skipped2.push(agentsPath);
7896
+ } else {
7897
+ await writeFile(agentsPath, buildProjectAgentsMd(name), "utf-8");
7898
+ created.push(agentsPath);
7899
+ }
7874
7900
  const claudePath = resolve2(dir, "CLAUDE.md");
7875
7901
  if (await pathExists(claudePath)) {
7876
- skipped2.push(claudePath);
7902
+ const existing = await readFile2(claudePath, "utf-8");
7903
+ if (existing.includes("@AGENTS.md")) {
7904
+ skipped2.push(claudePath);
7905
+ } else {
7906
+ await writeFile(claudePath, `@AGENTS.md
7907
+
7908
+ ${existing}`, "utf-8");
7909
+ merged.push(claudePath);
7910
+ }
7877
7911
  } else {
7878
7912
  await writeFile(claudePath, buildProjectClaudeMd(name), "utf-8");
7879
7913
  created.push(claudePath);
@@ -25606,6 +25640,7 @@ __export(config_exports, {
25606
25640
  USER_CONFIG_DIR: () => USER_CONFIG_DIR,
25607
25641
  USER_CONFIG_PATH: () => USER_CONFIG_PATH,
25608
25642
  createDefaultConfig: () => createDefaultConfig,
25643
+ findProjectConfigPath: () => findProjectConfigPath,
25609
25644
  getActiveScope: () => getActiveScope,
25610
25645
  getApiKeyFromConfig: () => getApiKeyFromConfig,
25611
25646
  getConfigDir: () => getConfigDir,
@@ -450988,9 +451023,22 @@ function backdropCacheDescriptor(opts) {
450988
451023
  provider: opts.provider,
450989
451024
  quality: opts.quality,
450990
451025
  size: opts.size,
451026
+ ratio: opts.ratio,
450991
451027
  ext: "png"
450992
451028
  });
450993
451029
  }
451030
+ function imageRatioForSize(size) {
451031
+ switch (size) {
451032
+ case "1024x1024":
451033
+ return "1:1";
451034
+ case "1024x1536":
451035
+ return "2:3";
451036
+ case "1536x1024":
451037
+ return "3:2";
451038
+ default:
451039
+ return "16:9";
451040
+ }
451041
+ }
450994
451042
  function videoCacheDescriptor(opts) {
450995
451043
  return cacheAssetDescriptor("video", {
450996
451044
  beatId: opts.beatId,
@@ -451319,6 +451367,7 @@ async function createBuildPlan(opts) {
451319
451367
  }
451320
451368
  const storyboardMd = await readFile13(storyboardPath, "utf-8");
451321
451369
  const validation3 = validateStoryboardMarkdown(storyboardMd);
451370
+ const validationIssues = [...validation3.issues];
451322
451371
  const parsed = parseStoryboard(storyboardMd);
451323
451372
  let sourceBeats = parsed.beats;
451324
451373
  if (opts.beat) {
@@ -451341,6 +451390,7 @@ async function createBuildPlan(opts) {
451341
451390
  const mode = opts.mode ?? config4.config.build.mode;
451342
451391
  const imageQuality = opts.imageQuality ?? config4.config.build.imageQuality ?? "hd";
451343
451392
  const imageSize2 = opts.imageSize ?? config4.config.build.imageSize ?? "1536x1024";
451393
+ const imageRatio = imageRatioForSize(imageSize2);
451344
451394
  const needsComposer = includeCompose && mode !== "agent" && sourceBeats.some((beat) => !existsSync31(join30(projectDir, `compositions/scene-${beat.id}.html`)));
451345
451395
  const resolved = await resolvePlanProviders({
451346
451396
  projectDir,
@@ -451390,7 +451440,8 @@ async function createBuildPlan(opts) {
451390
451440
  cue: backdropPrompt,
451391
451441
  provider: resolved.image.resolved,
451392
451442
  quality: imageQuality,
451393
- size: imageSize2
451443
+ size: imageSize2,
451444
+ ratio: imageRatio
451394
451445
  }) : null;
451395
451446
  const videoCache = videoPrompt && !videoReference ? videoCacheDescriptor({
451396
451447
  beatId: beat.id,
@@ -451484,7 +451535,8 @@ async function createBuildPlan(opts) {
451484
451535
  }
451485
451536
  }
451486
451537
  if (narration?.willGenerate) noteProviderNeed(resolved.narration, "Narration");
451487
- if (backdrop?.willGenerate) noteProviderNeed(resolved.image, "Backdrop generation");
451538
+ if (backdrop?.willGenerate && isSupportedBuildImageProvider(resolved.image.resolved))
451539
+ noteProviderNeed(resolved.image, "Backdrop generation");
451488
451540
  if (video?.willGenerate) noteProviderNeed(resolved.video, "Video generation");
451489
451541
  if (music?.willGenerate) noteProviderNeed(resolved.music, "Music generation");
451490
451542
  if (!compositionExists) missing.add("compositions");
@@ -451506,23 +451558,35 @@ async function createBuildPlan(opts) {
451506
451558
  };
451507
451559
  });
451508
451560
  providerResolution.push(...providerResolutionsForPlan(resolved, beats, opts, includeAssets));
451561
+ if (includeAssets && !opts.skipBackdrop && !isSupportedBuildImageProvider(resolved.image.resolved)) {
451562
+ const unsupportedBackdropBeats = beats.filter(
451563
+ (beat) => isBuildGeneratedBackdropPlan(beat.assets.backdrop)
451564
+ );
451565
+ for (const beat of unsupportedBackdropBeats) {
451566
+ validationIssues.push({
451567
+ severity: "error",
451568
+ code: "UNSUPPORTED_BUILD_IMAGE_PROVIDER",
451569
+ beatId: beat.id,
451570
+ message: `Build backdrop generation supports openai, gemini, and grok. Beat "${beat.id}" resolves image provider "${resolved.image.resolved}"; rerun with one of those or replace the backdrop cue with a project asset path.`
451571
+ });
451572
+ }
451573
+ if (unsupportedBackdropBeats.length > 0) {
451574
+ const beatFlag = opts.beat ? ` --beat ${opts.beat}` : "";
451575
+ retryWith.push(
451576
+ `vibe build ${projectDir}${beatFlag} --stage assets --image-provider openai --json`
451577
+ );
451578
+ }
451579
+ }
451580
+ const validationOk = !validationIssues.some((issue) => issue.severity === "error");
451509
451581
  if (!existsSync31(join30(projectDir, config4.config.composition.entry))) {
451510
451582
  missing.add("root-composition");
451511
- if (validation3.ok) retryWith.push(`vibe build ${projectDir} --stage sync --json`);
451583
+ if (validationOk) retryWith.push(`vibe build ${projectDir} --stage sync --json`);
451512
451584
  }
451513
451585
  if (config4.legacy) {
451514
451586
  warnings.push(
451515
451587
  `Using legacy ${config4.source}; write ${projectDir}/vibe.config.json to use the TO-BE project contract.`
451516
451588
  );
451517
451589
  }
451518
- if (resolved.image.resolved !== "openai" && beats.some((beat) => {
451519
- const backdrop = beat.assets.backdrop;
451520
- return backdrop && !["referenced-asset", "invalid-reference", "stage-skipped"].includes(backdrop.reason);
451521
- }) && !opts.skipBackdrop) {
451522
- warnings.push(
451523
- `Image provider "${resolved.image.resolved}" is not supported by build assets yet; use --image-provider openai.`
451524
- );
451525
- }
451526
451590
  if (!validation3.ok) {
451527
451591
  retryWith.push(
451528
451592
  `vibe storyboard validate ${projectDir} --json`,
@@ -451533,7 +451597,7 @@ async function createBuildPlan(opts) {
451533
451597
  projectDir,
451534
451598
  config: config4,
451535
451599
  stage,
451536
- status: validation3.ok ? "ready" : "invalid",
451600
+ status: validationOk ? "ready" : "invalid",
451537
451601
  currentStage: stage,
451538
451602
  mode,
451539
451603
  beat: opts.beat ?? null,
@@ -451545,8 +451609,8 @@ async function createBuildPlan(opts) {
451545
451609
  warnings,
451546
451610
  retryWith,
451547
451611
  validation: {
451548
- ok: validation3.ok,
451549
- issues: validation3.issues
451612
+ ok: validationOk,
451613
+ issues: validationIssues
451550
451614
  }
451551
451615
  });
451552
451616
  }
@@ -451573,6 +451637,15 @@ function finalizeBuildPlan(plan) {
451573
451637
  retryWith: unique2(plan.retryWith)
451574
451638
  };
451575
451639
  }
451640
+ function isBuildGeneratedBackdropPlan(asset) {
451641
+ if (!asset || asset.kind !== "backdrop") return false;
451642
+ return !["referenced-asset", "invalid-reference", "stage-skipped"].includes(asset.reason);
451643
+ }
451644
+ function isSupportedBuildImageProvider(provider) {
451645
+ return SUPPORTED_BUILD_IMAGE_PROVIDERS.includes(
451646
+ provider
451647
+ );
451648
+ }
451576
451649
  function nextCommandsForPlan(plan) {
451577
451650
  if (plan.status === "invalid") return unique2(plan.retryWith);
451578
451651
  const commands = [];
@@ -451872,7 +451945,7 @@ function loadPlanEnv(projectDir) {
451872
451945
  dir = dirname18(dir);
451873
451946
  }
451874
451947
  }
451875
- var import_dotenv2, BACKDROP_COST_USD, VIDEO_COST_USD, MUSIC_COST_USD, ELEVENLABS_NARRATION_COST_USD, COMPOSE_COST_USD;
451948
+ var import_dotenv2, BACKDROP_COST_USD, VIDEO_COST_USD, MUSIC_COST_USD, ELEVENLABS_NARRATION_COST_USD, COMPOSE_COST_USD, SUPPORTED_BUILD_IMAGE_PROVIDERS;
451876
451949
  var init_build_plan = __esm({
451877
451950
  "../cli/src/commands/_shared/build-plan.ts"() {
451878
451951
  "use strict";
@@ -451891,6 +451964,7 @@ var init_build_plan = __esm({
451891
451964
  MUSIC_COST_USD = 0.5;
451892
451965
  ELEVENLABS_NARRATION_COST_USD = 0.05;
451893
451966
  COMPOSE_COST_USD = 0.06;
451967
+ SUPPORTED_BUILD_IMAGE_PROVIDERS = ["openai", "gemini", "grok"];
451894
451968
  }
451895
451969
  });
451896
451970
 
@@ -451916,22 +451990,35 @@ function applySuggestion(project, suggestion) {
451916
451990
  if (clipIds.length === 0) return false;
451917
451991
  const clipId = clipIds[0];
451918
451992
  switch (type) {
451919
- case "trim":
451920
- if (params.newDuration) {
451921
- return project.trimClipEnd(clipId, params.newDuration);
451993
+ case "trim": {
451994
+ const newDuration = params.newDuration;
451995
+ if (typeof newDuration === "number") {
451996
+ return project.trimClipEnd(clipId, newDuration);
451922
451997
  }
451923
451998
  break;
451924
- case "add-effect":
451925
- if (params.effectType) {
451999
+ }
452000
+ case "add-effect": {
452001
+ const effectType = params.effectType;
452002
+ if (typeof effectType === "string") {
452003
+ const startTime = typeof params.startTime === "number" ? params.startTime : 0;
452004
+ const duration = typeof params.duration === "number" ? params.duration : 1;
452005
+ const rawEffectParams = params.effectParams && typeof params.effectParams === "object" ? params.effectParams : {};
452006
+ const effectParams = {};
452007
+ for (const [k, v] of Object.entries(rawEffectParams)) {
452008
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
452009
+ effectParams[k] = v;
452010
+ }
452011
+ }
451926
452012
  const effect = project.addEffect(clipId, {
451927
- type: params.effectType,
451928
- startTime: params.startTime || 0,
451929
- duration: params.duration || 1,
451930
- params: params.effectParams || {}
452013
+ type: effectType,
452014
+ startTime,
452015
+ duration,
452016
+ params: effectParams
451931
452017
  });
451932
452018
  return effect !== null;
451933
452019
  }
451934
452020
  break;
452021
+ }
451935
452022
  case "delete":
451936
452023
  return project.removeClip(clipId);
451937
452024
  }
@@ -453526,6 +453613,7 @@ function isActiveStatus(status) {
453526
453613
  }
453527
453614
  function providerStatusCommand(record) {
453528
453615
  if (record.jobType === "generate-video") {
453616
+ if (record.provider !== "runway" && record.provider !== "kling") return void 0;
453529
453617
  const type = record.provider === "kling" && record.providerTaskType ? ` --type ${record.providerTaskType}` : "";
453530
453618
  return `vibe generate video-status ${record.providerTaskId} -p ${record.provider}${type} --json`;
453531
453619
  }
@@ -454625,19 +454713,18 @@ async function dispatchBackdrop(beat, ctx) {
454625
454713
  if (reference) return referencePrimitiveOutcome("backdrop", beat, ctx, reference);
454626
454714
  const prompt3 = stringOrUndefined4(beat.cues?.backdrop);
454627
454715
  if (!prompt3) return { status: "no-cue" };
454628
- if (ctx.imageProvider !== "openai") {
454629
- const error = `image provider "${ctx.imageProvider}" not yet supported (use openai)`;
454630
- ctx.onProgress({ type: "backdrop-failed", beatId: beat.id, error });
454631
- return { status: "failed", error };
454632
- }
454633
454716
  const rel = `assets/backdrop-${beat.id}.png`;
454634
454717
  const abs = join33(ctx.projectDir, rel);
454718
+ const size = ctx.imageSize ?? "1536x1024";
454719
+ const ratio = imageRatioForSize(size);
454720
+ const metadataOptions = { quality: ctx.imageQuality, size, ratio };
454635
454721
  const cache = backdropCacheDescriptor({
454636
454722
  beatId: beat.id,
454637
454723
  cue: prompt3,
454638
454724
  provider: ctx.imageProvider,
454639
454725
  quality: ctx.imageQuality,
454640
- size: ctx.imageSize ?? "1536x1024"
454726
+ size,
454727
+ ratio
454641
454728
  });
454642
454729
  const metadataPath = assetMetadataPath("backdrop", beat.id);
454643
454730
  if (existsSync35(abs) && !ctx.force) {
@@ -454648,7 +454735,7 @@ async function dispatchBackdrop(beat, ctx) {
454648
454735
  beatId: beat.id,
454649
454736
  cue: prompt3,
454650
454737
  provider: ctx.imageProvider,
454651
- options: { quality: ctx.imageQuality, size: ctx.imageSize ?? "1536x1024" },
454738
+ options: metadataOptions,
454652
454739
  cacheKey: cache.key
454653
454740
  })) {
454654
454741
  ctx.onProgress({ type: "backdrop-cached", beatId: beat.id, path: rel });
@@ -454673,7 +454760,7 @@ async function dispatchBackdrop(beat, ctx) {
454673
454760
  beatId: beat.id,
454674
454761
  cue: prompt3,
454675
454762
  provider: ctx.imageProvider,
454676
- options: { quality: ctx.imageQuality, size: ctx.imageSize ?? "1536x1024" },
454763
+ options: metadataOptions,
454677
454764
  cacheKey: cache.key,
454678
454765
  canonicalPath: rel,
454679
454766
  cachePath: cache.path
@@ -454689,27 +454776,14 @@ async function dispatchBackdrop(beat, ctx) {
454689
454776
  freshness: "fresh"
454690
454777
  };
454691
454778
  }
454692
- loadSceneBuildEnv(ctx.projectDir);
454693
- const apiKey = await getApiKeyFromConfig("openai", { cwd: ctx.projectDir }) ?? process.env.OPENAI_API_KEY ?? "";
454694
- if (!apiKey) {
454695
- const error = "OPENAI_API_KEY not set \u2014 cannot dispatch backdrop";
454696
- ctx.onProgress({ type: "backdrop-failed", beatId: beat.id, error });
454697
- return { status: "failed", error };
454698
- }
454699
- const provider = new OpenAIImageProvider();
454700
- await provider.initialize({ apiKey });
454701
- const result = await provider.generateImage(prompt3, {
454702
- model: "gpt-image-2",
454703
- size: ctx.imageSize,
454704
- quality: ctx.imageQuality
454705
- });
454706
- if (!result.success || !result.images?.[0]?.base64) {
454707
- const error = result.error ?? "no image data returned";
454779
+ const generated = await generateBackdropImage(prompt3, ctx, ratio);
454780
+ if (!generated.success) {
454781
+ const error = generated.error;
454708
454782
  ctx.onProgress({ type: "backdrop-failed", beatId: beat.id, error });
454709
454783
  return { status: "failed", error };
454710
454784
  }
454711
454785
  await mkdir12(dirname20(abs), { recursive: true });
454712
- const buffer = Buffer.from(result.images[0].base64, "base64");
454786
+ const buffer = generated.buffer;
454713
454787
  await writeFile19(abs, buffer);
454714
454788
  await mkdir12(dirname20(cacheAbs), { recursive: true });
454715
454789
  await writeFile19(cacheAbs, buffer);
@@ -454718,8 +454792,8 @@ async function dispatchBackdrop(beat, ctx) {
454718
454792
  kind: "backdrop",
454719
454793
  beatId: beat.id,
454720
454794
  cue: prompt3,
454721
- provider: "openai",
454722
- options: { quality: ctx.imageQuality, size: ctx.imageSize ?? "1536x1024" },
454795
+ provider: ctx.imageProvider,
454796
+ options: metadataOptions,
454723
454797
  cacheKey: cache.key,
454724
454798
  canonicalPath: rel,
454725
454799
  cachePath: cache.path
@@ -454728,18 +454802,75 @@ async function dispatchBackdrop(beat, ctx) {
454728
454802
  type: "backdrop-generated",
454729
454803
  beatId: beat.id,
454730
454804
  path: rel,
454731
- provider: "openai"
454805
+ provider: ctx.imageProvider
454732
454806
  });
454733
454807
  return {
454734
454808
  status: "generated",
454735
454809
  path: rel,
454736
- provider: "openai",
454810
+ provider: ctx.imageProvider,
454737
454811
  cachePath: cache.path,
454738
454812
  cacheKey: cache.key,
454739
454813
  metadataPath,
454740
454814
  freshness: "fresh"
454741
454815
  };
454742
454816
  }
454817
+ async function generateBackdropImage(prompt3, ctx, ratio) {
454818
+ loadSceneBuildEnv(ctx.projectDir);
454819
+ const keyInfo = imageProviderKeyInfo(ctx.imageProvider);
454820
+ const apiKey = await getApiKeyFromConfig(keyInfo.configKey, { cwd: ctx.projectDir }) ?? process.env[keyInfo.envVar] ?? "";
454821
+ if (!apiKey) {
454822
+ return {
454823
+ success: false,
454824
+ error: `${keyInfo.envVar} not set \u2014 cannot dispatch backdrop with ${ctx.imageProvider}`
454825
+ };
454826
+ }
454827
+ if (ctx.imageProvider === "openai") {
454828
+ const provider2 = new OpenAIImageProvider();
454829
+ await provider2.initialize({ apiKey });
454830
+ const result2 = await provider2.generateImage(prompt3, {
454831
+ model: "gpt-image-2",
454832
+ size: ctx.imageSize,
454833
+ quality: ctx.imageQuality
454834
+ });
454835
+ return imageBufferFromResult(result2);
454836
+ }
454837
+ if (ctx.imageProvider === "gemini") {
454838
+ const provider2 = new GeminiProvider();
454839
+ await provider2.initialize({ apiKey });
454840
+ const result2 = await provider2.generateImage(prompt3, {
454841
+ model: "flash",
454842
+ aspectRatio: ratio
454843
+ });
454844
+ return imageBufferFromResult(result2);
454845
+ }
454846
+ const provider = new GrokProvider();
454847
+ await provider.initialize({ apiKey });
454848
+ const result = await provider.generateImage(prompt3, {
454849
+ aspectRatio: ratio,
454850
+ n: 1
454851
+ });
454852
+ return imageBufferFromResult(result);
454853
+ }
454854
+ async function imageBufferFromResult(result) {
454855
+ const image = result.images?.[0];
454856
+ if (!result.success || !image) {
454857
+ return { success: false, error: result.error ?? "no image data returned" };
454858
+ }
454859
+ if (image.base64) return { success: true, buffer: Buffer.from(image.base64, "base64") };
454860
+ if (image.url) {
454861
+ const response = await fetch(image.url);
454862
+ if (!response.ok) {
454863
+ return { success: false, error: `failed to download image: HTTP ${response.status}` };
454864
+ }
454865
+ return { success: true, buffer: Buffer.from(await response.arrayBuffer()) };
454866
+ }
454867
+ return { success: false, error: "no image data returned" };
454868
+ }
454869
+ function imageProviderKeyInfo(provider) {
454870
+ if (provider === "gemini") return { configKey: "google", envVar: "GOOGLE_API_KEY" };
454871
+ if (provider === "grok") return { configKey: "xai", envVar: "XAI_API_KEY" };
454872
+ return { configKey: "openai", envVar: "OPENAI_API_KEY" };
454873
+ }
454743
454874
  async function dispatchVideo(beat, ctx) {
454744
454875
  const reference = assetReferenceForBeat(ctx.projectDir, "video", beat);
454745
454876
  if (reference) return referencePrimitiveOutcome("video", beat, ctx, reference);
@@ -462757,12 +462888,13 @@ async function prompt2(question) {
462757
462888
  });
462758
462889
  });
462759
462890
  }
462760
- var ttyStream;
462891
+ var ttyStream, ANSI_RE;
462761
462892
  var init_tty = __esm({
462762
462893
  "../cli/src/utils/tty.ts"() {
462763
462894
  "use strict";
462764
462895
  init_open_url();
462765
462896
  ttyStream = null;
462897
+ ANSI_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-?]*[ -/]*[@-~]`, "g");
462766
462898
  }
462767
462899
  });
462768
462900
 
@@ -470125,7 +470257,10 @@ async function executeSuggestEdit(options) {
470125
470257
  }
470126
470258
  return { success: true, suggestions };
470127
470259
  } catch (error) {
470128
- return { success: false, error: `Suggest failed: ${error instanceof Error ? error.message : String(error)}` };
470260
+ return {
470261
+ success: false,
470262
+ error: `Suggest failed: ${error instanceof Error ? error.message : String(error)}`
470263
+ };
470129
470264
  }
470130
470265
  }
470131
470266
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibeframe/mcp-server",
3
- "version": "0.102.0",
3
+ "version": "0.103.1",
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/core": "0.102.0",
61
- "@vibeframe/cli": "0.102.0"
60
+ "@vibeframe/cli": "0.103.1",
61
+ "@vibeframe/core": "0.103.1"
62
62
  },
63
63
  "engines": {
64
64
  "node": ">=20"