@vibeframe/cli 0.109.2 → 0.111.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 CHANGED
@@ -67838,6 +67838,82 @@ var init_long_poll = __esm({
67838
67838
  }
67839
67839
  });
67840
67840
 
67841
+ // src/tools/_shared/elicit.ts
67842
+ function planBuildElicitation(args) {
67843
+ const assetsWillRun = args.stage === void 0 || args.stage === "all" || args.stage === "assets";
67844
+ if (!assetsWillRun) return null;
67845
+ const properties = {};
67846
+ const required = [];
67847
+ const narrationUndecided = !args.skipNarration && (args.ttsProvider === void 0 || args.ttsProvider === "auto");
67848
+ if (narrationUndecided) {
67849
+ properties.narration = {
67850
+ type: "string",
67851
+ title: "Narration voice-over",
67852
+ description: "Which TTS engine narrates the video?",
67853
+ enum: [...NARRATION_CHOICES],
67854
+ enumNames: [
67855
+ "Kokoro \u2014 free, runs locally on this machine",
67856
+ "ElevenLabs \u2014 cloud TTS, uses your ElevenLabs credits"
67857
+ ]
67858
+ };
67859
+ required.push("narration");
67860
+ }
67861
+ if (args.skipBackdrop === void 0 && args.imageProvider === void 0) {
67862
+ properties.backdrop_images = {
67863
+ type: "string",
67864
+ title: "Backdrop images",
67865
+ description: "Generate AI background images for each scene?",
67866
+ enum: [...BACKDROP_CHOICES],
67867
+ enumNames: [
67868
+ "Skip \u2014 free, pure typographic scenes",
67869
+ "OpenAI \u2014 paid image generation (roughly $1-3 per video)"
67870
+ ]
67871
+ };
67872
+ required.push("backdrop_images");
67873
+ }
67874
+ if (args.maxCostUsd === void 0) {
67875
+ properties.max_cost_usd = {
67876
+ type: "number",
67877
+ title: "Max provider spend (USD)",
67878
+ description: "Abort before any paid provider call when the estimate exceeds this cap. Leave empty for no cap.",
67879
+ minimum: 0
67880
+ };
67881
+ }
67882
+ if (Object.keys(properties).length === 0) return null;
67883
+ return {
67884
+ message: "VibeFrame is about to build this video. Choose how the assets are generated:",
67885
+ requestedSchema: { type: "object", properties, required }
67886
+ };
67887
+ }
67888
+ function applyElicitationAnswers(args, content) {
67889
+ if (!content) return args;
67890
+ const next = { ...args };
67891
+ const narration = content.narration;
67892
+ if (typeof narration === "string" && NARRATION_CHOICES.includes(narration)) {
67893
+ next.ttsProvider = narration;
67894
+ }
67895
+ const backdrop = content.backdrop_images;
67896
+ if (backdrop === "skip") {
67897
+ next.skipBackdrop = true;
67898
+ } else if (backdrop === "openai") {
67899
+ next.skipBackdrop = false;
67900
+ next.imageProvider = "openai";
67901
+ }
67902
+ const cap = content.max_cost_usd;
67903
+ if (typeof cap === "number" && Number.isFinite(cap) && cap >= 0) {
67904
+ next.maxCostUsd = cap;
67905
+ }
67906
+ return next;
67907
+ }
67908
+ var NARRATION_CHOICES, BACKDROP_CHOICES;
67909
+ var init_elicit = __esm({
67910
+ "src/tools/_shared/elicit.ts"() {
67911
+ "use strict";
67912
+ NARRATION_CHOICES = ["kokoro", "elevenlabs"];
67913
+ BACKDROP_CHOICES = ["skip", "openai"];
67914
+ }
67915
+ });
67916
+
67841
67917
  // src/tools/manifest/scene.ts
67842
67918
  import { resolve as resolve75, relative as relative12 } from "node:path";
67843
67919
  function summariseLint(result) {
@@ -67976,6 +68052,7 @@ var init_scene2 = __esm({
67976
68052
  init_zod();
67977
68053
  init_define_tool();
67978
68054
  init_long_poll();
68055
+ init_elicit();
67979
68056
  init_visual_styles();
67980
68057
  init_scene_project();
67981
68058
  init_scene();
@@ -68003,6 +68080,8 @@ var init_scene2 = __esm({
68003
68080
  name: "scene_list_styles",
68004
68081
  category: "scene",
68005
68082
  cost: "free",
68083
+ title: "List Visual Styles",
68084
+ annotations: { readOnly: true, openWorld: false },
68006
68085
  description: "List the 8 vendored visual identities available for `init --visual-style` (Swiss Pulse, Data Drift, \u2026) or, when `name` is provided, return the full DESIGN.md hard-gate body for one style. The DESIGN.md content is what the LLM uses as a non-negotiable visual rulebook during compose-scenes-with-skills.",
68007
68086
  schema: sceneStylesSchema,
68008
68087
  async execute(args) {
@@ -68064,6 +68143,8 @@ var init_scene2 = __esm({
68064
68143
  name: "init",
68065
68144
  category: "scene",
68066
68145
  cost: "free",
68146
+ title: "Initialize Video Project",
68147
+ annotations: { readOnly: false, destructive: false, idempotent: true, openWorld: false },
68067
68148
  description: "Scaffold a new VibeFrame video scene project. Supports minimal, agent, and full profiles; full includes the current HTML render backend metadata. Idempotent: re-running keeps user-authored files and merges backend config instead of overwriting. No API keys required.",
68068
68149
  schema: sceneInitSchema,
68069
68150
  async execute(args, ctx) {
@@ -68114,6 +68195,8 @@ var init_scene2 = __esm({
68114
68195
  name: "scene_add",
68115
68196
  category: "scene",
68116
68197
  cost: "low",
68198
+ title: "Add Scene from Preset",
68199
+ annotations: { readOnly: false, openWorld: true },
68117
68200
  description: "Add a single scene to an existing scene project. Optionally generates narration audio (ElevenLabs) and/or a backdrop image (Gemini/OpenAI), then emits compositions/scene-<id>.html with a paused GSAP timeline and splices a clip reference into the root index.html. Use skipAudio:true and skipImage:true for text-only scenes that need no API calls.",
68118
68201
  schema: sceneAddSchema,
68119
68202
  async execute(args, ctx) {
@@ -68171,6 +68254,8 @@ var init_scene2 = __esm({
68171
68254
  name: "scene_lint",
68172
68255
  category: "scene",
68173
68256
  cost: "free",
68257
+ title: "Lint Scene Compositions",
68258
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
68174
68259
  description: "Validate every scene file in a project against the public Hyperframes lint rules (in-process, no Chrome required). Returns errors, warnings, and info findings per file. Optional fix:true mechanically repairs `timed_element_missing_clip_class` only \u2014 other issues surface with fixHints.",
68175
68260
  schema: sceneLintSchema,
68176
68261
  async execute(args, ctx) {
@@ -68208,6 +68293,8 @@ var init_scene2 = __esm({
68208
68293
  name: "scene_repair",
68209
68294
  category: "scene",
68210
68295
  cost: "free",
68296
+ title: "Repair Scene Compositions",
68297
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
68211
68298
  description: "Apply deterministic mechanical scene repairs. Currently uses the safe lint auto-fix allow-list and never performs semantic creative rewrites.",
68212
68299
  schema: sceneRepairSchema,
68213
68300
  async execute(args, ctx) {
@@ -68244,6 +68331,8 @@ var init_scene2 = __esm({
68244
68331
  name: "render",
68245
68332
  category: "scene",
68246
68333
  cost: "free",
68334
+ title: "Render Video to MP4",
68335
+ annotations: { readOnly: false, openWorld: false },
68247
68336
  description: "Render a scene project to MP4/WebM/MOV via the Hyperframes producer. Requires Chrome installed locally. Output defaults to renders/<projectName>-<isoStamp>.<format>. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking render. Emits MCP progress notifications when the client supplies a progressToken.",
68248
68337
  schema: sceneRenderSchema,
68249
68338
  async execute(args, ctx) {
@@ -68309,9 +68398,34 @@ var init_scene2 = __esm({
68309
68398
  name: "build",
68310
68399
  category: "scene",
68311
68400
  cost: "high",
68312
- description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking build. Emits MCP progress notifications when the client supplies a progressToken.",
68401
+ title: "Build Video from Storyboard",
68402
+ annotations: { readOnly: false, openWorld: true },
68403
+ description: "v0.60 one-shot orchestrator: read STORYBOARD.md per-beat YAML cues (narration / backdrop / duration), dispatch TTS + image generation per beat, compose scene HTML via the compose-scenes-with-skills pipeline, then render to MP4. Use this instead of chaining init + scene_add + render manually. Caches by SHA256 of (DESIGN.md + cue body) so re-runs are idempotent and cheap. Long runs: over MCP, calls exceeding ~45s return immediately with { promoted: true, jobId, status: 'running' } \u2014 poll status_job every 15-30s until completed/failed instead of re-invoking build. Emits MCP progress notifications when the client supplies a progressToken. When the MCP host supports elicitation, unspecified asset choices (narration provider, backdrop images, cost cap) are confirmed with the user via a form before the build starts.",
68313
68404
  schema: sceneBuildSchema,
68314
68405
  async execute(args, ctx) {
68406
+ let warnings;
68407
+ if (ctx.surface === "mcp" && ctx.elicit) {
68408
+ const form = planBuildElicitation(args);
68409
+ if (form) {
68410
+ const outcome = await ctx.elicit(form).catch(() => null);
68411
+ if (outcome === null) {
68412
+ warnings = ["Asset-choice elicitation failed or timed out; proceeding with defaults."];
68413
+ } else if (outcome.action === "accept") {
68414
+ args = applyElicitationAnswers(args, outcome.content);
68415
+ } else {
68416
+ return {
68417
+ success: false,
68418
+ error: "Build cancelled \u2014 the user declined the asset choices.",
68419
+ data: {
68420
+ cancelled: true,
68421
+ retryWith: [
68422
+ `build { projectDir: "${args.projectDir ?? "."}", ttsProvider: "kokoro", skipBackdrop: true }`
68423
+ ]
68424
+ }
68425
+ };
68426
+ }
68427
+ }
68428
+ }
68315
68429
  const projectDir = args.projectDir ? resolve75(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
68316
68430
  const runBuild = (report) => executeSceneBuild({
68317
68431
  projectDir,
@@ -68339,7 +68453,9 @@ var init_scene2 = __esm({
68339
68453
  ctx.onProgress?.({ message: update.message ?? update.stage });
68340
68454
  report(update);
68341
68455
  }
68342
- }).then(mapBuildResultToToolResult);
68456
+ }).then(mapBuildResultToToolResult).then(
68457
+ (result) => warnings === void 0 ? result : { ...result, data: { ...result.data, elicitationWarnings: warnings } }
68458
+ );
68343
68459
  if (ctx.surface !== "mcp") {
68344
68460
  return runBuild(() => void 0);
68345
68461
  }
@@ -68366,6 +68482,8 @@ var init_scene2 = __esm({
68366
68482
  name: "scene_install_skill",
68367
68483
  category: "scene",
68368
68484
  cost: "free",
68485
+ title: "Install Hyperframes Skill",
68486
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
68369
68487
  description: "Install the vendored Hyperframes skill bundle into a scene project so the host agent (Claude Code, Cursor, Codex, Aider) can read framework rules + house style directly. Writes a universal SKILL.md + references/ at the project root, plus per-host layouts (.claude/skills/hyperframes/ for Claude Code, .cursor/rules/hyperframes.mdc for Cursor) when those hosts are detected. Phase H1 of the agentic-native composer plan \u2014 once installed, the host agent itself can author scene HTML using the rules instead of relying on vibe's internal LLM call.",
68370
68488
  schema: sceneInstallSkillSchema,
68371
68489
  async execute(args, ctx) {
@@ -68412,6 +68530,8 @@ var init_scene2 = __esm({
68412
68530
  name: "scene_compose_prompts",
68413
68531
  category: "scene",
68414
68532
  cost: "free",
68533
+ title: "Get Scene Authoring Prompts",
68534
+ annotations: { readOnly: true, openWorld: false },
68415
68535
  description: "Emit the per-beat compose plan for the host agent to author scene HTML itself. Reads STORYBOARD.md + DESIGN.md and returns each beat's outputPath + userPrompt + cues + body, plus references to the project's SKILL.md (Hyperframes rules) and DESIGN.md (visual identity). The host agent writes each compositions/scene-<id>.html file directly \u2014 VibeFrame makes NO LLM call here. Hosts that cannot write files (e.g. Claude Desktop) submit each authored beat with scene_submit instead. Pairs with scene_install_skill (Phase H1). Phase H2 of the agentic-native composer plan; the internal-LLM batch path (build) remains as a fallback for non-agent contexts.",
68416
68536
  schema: sceneComposePromptsSchema,
68417
68537
  async execute(args, ctx) {
@@ -68454,6 +68574,8 @@ var init_scene2 = __esm({
68454
68574
  name: "scene_submit",
68455
68575
  category: "scene",
68456
68576
  cost: "free",
68577
+ title: "Submit Scene HTML",
68578
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
68457
68579
  description: "Submit host-authored Hyperframes scene HTML for one beat. Validates with the same lint as the batch composer and writes compositions/scene-<id>.html on pass; on lint errors it returns the findings WITHOUT writing so you can fix and resubmit. This completes agent-mode compose for hosts that cannot write files (e.g. Claude Desktop): build (mode agent) \u2192 needs-author plan \u2192 author each beat from its composePrompts userPrompt \u2192 scene_submit per beat \u2192 build (stage sync) \u2192 render. No internal LLM call \u2014 the submitting agent is the composer.",
68458
68580
  schema: sceneSubmitSchema,
68459
68581
  async execute(args, ctx) {
@@ -68503,6 +68625,8 @@ var init_audio2 = __esm({
68503
68625
  name: "audio_transcribe",
68504
68626
  category: "audio",
68505
68627
  cost: "low",
68628
+ title: "Transcribe Audio",
68629
+ annotations: { readOnly: false, openWorld: true },
68506
68630
  description: "Transcribe audio using OpenAI Whisper. Outputs text, SRT, or VTT. Requires OPENAI_API_KEY.",
68507
68631
  schema: external_exports.object({
68508
68632
  audioPath: external_exports.string().describe("Input audio file path"),
@@ -68532,6 +68656,8 @@ var init_audio2 = __esm({
68532
68656
  name: "audio_isolate",
68533
68657
  category: "audio",
68534
68658
  cost: "low",
68659
+ title: "Isolate Vocals from Audio",
68660
+ annotations: { readOnly: false, openWorld: true },
68535
68661
  description: "Isolate vocals from audio using ElevenLabs. Requires ELEVENLABS_API_KEY.",
68536
68662
  schema: external_exports.object({
68537
68663
  audioPath: external_exports.string().describe("Input audio file path"),
@@ -68551,6 +68677,8 @@ var init_audio2 = __esm({
68551
68677
  name: "audio_clone_voice",
68552
68678
  category: "audio",
68553
68679
  cost: "low",
68680
+ title: "Clone Voice from Samples",
68681
+ annotations: { readOnly: false, destructive: false, openWorld: true },
68554
68682
  description: "Clone a voice from audio samples using ElevenLabs. Requires ELEVENLABS_API_KEY.",
68555
68683
  schema: external_exports.object({
68556
68684
  samplePaths: external_exports.array(external_exports.string()).describe("Audio sample file paths (1-25 files)"),
@@ -68572,6 +68700,8 @@ var init_audio2 = __esm({
68572
68700
  name: "audio_dub",
68573
68701
  category: "audio",
68574
68702
  cost: "high",
68703
+ title: "Dub Audio to Another Language",
68704
+ annotations: { readOnly: false, openWorld: true },
68575
68705
  description: "Dub audio/video to another language (transcribe + translate + TTS). Requires OPENAI_API_KEY, ANTHROPIC_API_KEY, ELEVENLABS_API_KEY.",
68576
68706
  schema: external_exports.object({
68577
68707
  mediaPath: external_exports.string().describe("Input media file (video or audio)"),
@@ -68602,6 +68732,8 @@ var init_audio2 = __esm({
68602
68732
  name: "audio_duck",
68603
68733
  category: "audio",
68604
68734
  cost: "free",
68735
+ title: "Duck Background Music",
68736
+ annotations: { readOnly: false, openWorld: false },
68605
68737
  description: "Auto-duck background music when voice is present using FFmpeg sidechain compression. Free, no API key needed.",
68606
68738
  schema: external_exports.object({
68607
68739
  musicPath: external_exports.string().describe("Background music file path"),
@@ -68647,6 +68779,8 @@ var init_edit = __esm({
68647
68779
  name: "edit_silence_cut",
68648
68780
  category: "edit",
68649
68781
  cost: "free",
68782
+ title: "Cut Silence from Video",
68783
+ annotations: { readOnly: false, openWorld: true },
68650
68784
  description: "Remove silent segments from a video using FFmpeg or Gemini AI detection. No API key needed for FFmpeg mode.",
68651
68785
  schema: external_exports.object({
68652
68786
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68677,6 +68811,8 @@ var init_edit = __esm({
68677
68811
  name: "edit_caption",
68678
68812
  category: "edit",
68679
68813
  cost: "low",
68814
+ title: "Burn Captions into Video",
68815
+ annotations: { readOnly: false, openWorld: true },
68680
68816
  description: "Transcribe audio and burn styled captions into video. Requires OPENAI_API_KEY for Whisper transcription.",
68681
68817
  schema: external_exports.object({
68682
68818
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68701,6 +68837,8 @@ var init_edit = __esm({
68701
68837
  name: "edit_fade",
68702
68838
  category: "edit",
68703
68839
  cost: "free",
68840
+ title: "Apply Fade Effects",
68841
+ annotations: { readOnly: false, openWorld: false },
68704
68842
  description: "Apply fade in/out effects to video and/or audio. No API key needed.",
68705
68843
  schema: external_exports.object({
68706
68844
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68724,6 +68862,8 @@ var init_edit = __esm({
68724
68862
  name: "edit_noise_reduce",
68725
68863
  category: "edit",
68726
68864
  cost: "free",
68865
+ title: "Reduce Audio Noise",
68866
+ annotations: { readOnly: false, openWorld: false },
68727
68867
  description: "Reduce audio/video noise using FFmpeg filters. No API key needed.",
68728
68868
  schema: external_exports.object({
68729
68869
  inputPath: external_exports.string().describe("Path to the input media file"),
@@ -68745,6 +68885,8 @@ var init_edit = __esm({
68745
68885
  name: "edit_jump_cut",
68746
68886
  category: "edit",
68747
68887
  cost: "low",
68888
+ title: "Remove Filler Words",
68889
+ annotations: { readOnly: false, openWorld: true },
68748
68890
  description: "Remove filler words (um, uh, like, etc.) from video using Whisper transcription. Requires OPENAI_API_KEY.",
68749
68891
  schema: external_exports.object({
68750
68892
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68768,6 +68910,8 @@ var init_edit = __esm({
68768
68910
  name: "edit_text_overlay",
68769
68911
  category: "edit",
68770
68912
  cost: "free",
68913
+ title: "Overlay Static Text",
68914
+ annotations: { readOnly: false, openWorld: false },
68771
68915
  description: "Apply simple static text burn-in on video using FFmpeg drawtext. No API key needed. For designed or animated overlays, use edit_motion_overlay.",
68772
68916
  schema: external_exports.object({
68773
68917
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68794,6 +68938,8 @@ var init_edit = __esm({
68794
68938
  name: "edit_motion_overlay",
68795
68939
  category: "edit",
68796
68940
  cost: "low",
68941
+ title: "Apply Motion Graphics Overlay",
68942
+ annotations: { readOnly: false, openWorld: true },
68797
68943
  description: "Apply designed motion graphics overlays to an existing video. Generates Remotion overlays from a prompt, or overlays a user-provided .json/.lottie animation via the Hyperframes renderer.",
68798
68944
  schema: external_exports.object({
68799
68945
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68830,6 +68976,8 @@ var init_edit = __esm({
68830
68976
  name: "edit_translate_srt",
68831
68977
  category: "edit",
68832
68978
  cost: "low",
68979
+ title: "Translate SRT Subtitles",
68980
+ annotations: { readOnly: false, openWorld: true },
68833
68981
  description: "Translate SRT subtitle files using Claude or OpenAI. Requires ANTHROPIC_API_KEY or OPENAI_API_KEY.",
68834
68982
  schema: external_exports.object({
68835
68983
  srtPath: external_exports.string().describe("Path to the input SRT file"),
@@ -68852,6 +69000,8 @@ var init_edit = __esm({
68852
69000
  name: "edit_grade",
68853
69001
  category: "edit",
68854
69002
  cost: "low",
69003
+ title: "Apply Color Grading",
69004
+ annotations: { readOnly: false, openWorld: true },
68855
69005
  description: "Apply AI-generated color grading using Claude + FFmpeg. Use preset for free built-in grades, or style for custom AI-generated grades (needs ANTHROPIC_API_KEY).",
68856
69006
  schema: external_exports.object({
68857
69007
  videoPath: external_exports.string().describe("Input video file path"),
@@ -68874,6 +69024,8 @@ var init_edit = __esm({
68874
69024
  name: "edit_speed_ramp",
68875
69025
  category: "edit",
68876
69026
  cost: "low",
69027
+ title: "Apply Content-Aware Speed Ramping",
69028
+ annotations: { readOnly: false, openWorld: true },
68877
69029
  description: "Apply content-aware speed ramping. Analyzes speech with Whisper, plans speed changes with Claude, applies with FFmpeg. Requires OPENAI_API_KEY + ANTHROPIC_API_KEY.",
68878
69030
  schema: external_exports.object({
68879
69031
  videoPath: external_exports.string().describe("Input video file path (must have audio)"),
@@ -68898,6 +69050,8 @@ var init_edit = __esm({
68898
69050
  name: "edit_reframe",
68899
69051
  category: "edit",
68900
69052
  cost: "free",
69053
+ title: "Reframe Video Aspect Ratio",
69054
+ annotations: { readOnly: false, openWorld: false },
68901
69055
  description: "Auto-reframe video to a different aspect ratio using smart cropping. Free (FFmpeg only).",
68902
69056
  schema: external_exports.object({
68903
69057
  videoPath: external_exports.string().describe("Input video file path"),
@@ -68920,6 +69074,8 @@ var init_edit = __esm({
68920
69074
  name: "edit_interpolate",
68921
69075
  category: "edit",
68922
69076
  cost: "free",
69077
+ title: "Create Slow Motion with Frame Interpolation",
69078
+ annotations: { readOnly: false, openWorld: false },
68923
69079
  description: "Create slow motion with AI frame interpolation using FFmpeg minterpolate. Free, no API key needed.",
68924
69080
  schema: external_exports.object({
68925
69081
  videoPath: external_exports.string().describe("Input video file path"),
@@ -68942,6 +69098,8 @@ var init_edit = __esm({
68942
69098
  name: "edit_upscale",
68943
69099
  category: "edit",
68944
69100
  cost: "free",
69101
+ title: "Upscale Video Resolution",
69102
+ annotations: { readOnly: false, openWorld: false },
68945
69103
  description: "Upscale video resolution using FFmpeg (Lanczos scaling). Free, no API key needed.",
68946
69104
  schema: external_exports.object({
68947
69105
  videoPath: external_exports.string().describe("Input video file path"),
@@ -68963,6 +69121,8 @@ var init_edit = __esm({
68963
69121
  name: "edit_animated_caption",
68964
69122
  category: "edit",
68965
69123
  cost: "low",
69124
+ title: "Add Animated Captions",
69125
+ annotations: { readOnly: false, openWorld: true },
68966
69126
  description: "Add animated word-by-word captions (TikTok/Reels style). Supports highlight, bounce, pop-in, neon, karaoke-sweep, typewriter styles. Requires OPENAI_API_KEY for Whisper.",
68967
69127
  schema: external_exports.object({
68968
69128
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -68995,6 +69155,8 @@ var init_edit = __esm({
68995
69155
  name: "edit_image",
68996
69156
  category: "edit",
68997
69157
  cost: "low",
69158
+ title: "Edit Image with AI",
69159
+ annotations: { readOnly: false, openWorld: true },
68998
69160
  description: "Edit image(s) using Gemini (Nano Banana). Provide image paths and an edit prompt. Requires GOOGLE_API_KEY.",
68999
69161
  schema: external_exports.object({
69000
69162
  imagePaths: external_exports.array(external_exports.string()).describe("Input image file path(s)"),
@@ -69018,6 +69180,8 @@ var init_edit = __esm({
69018
69180
  name: "edit_fill_gaps",
69019
69181
  category: "edit",
69020
69182
  cost: "high",
69183
+ title: "Fill Timeline Gaps with AI Video",
69184
+ annotations: { readOnly: false, openWorld: true },
69021
69185
  description: "Fill timeline gaps with AI-generated video using Kling image-to-video. Detects empty regions in a project's timeline, extracts the last frame of the preceding clip, and generates a continuation video. Requires KLING_API_KEY and IMGBB_API_KEY (image hosting for Kling).",
69022
69186
  schema: external_exports.object({
69023
69187
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -69142,6 +69306,8 @@ var init_inspect = __esm({
69142
69306
  name: "inspect_project",
69143
69307
  category: "analyze",
69144
69308
  cost: "free",
69309
+ title: "Inspect Project",
69310
+ annotations: { readOnly: false, openWorld: false },
69145
69311
  description: "Local project inspection: checks STORYBOARD.md, DESIGN.md, config, build-report, scene lint, composition files, and referenced assets. Writes review-report.json by default.",
69146
69312
  schema: external_exports.object({
69147
69313
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION2),
@@ -69176,6 +69342,8 @@ var init_inspect = __esm({
69176
69342
  name: "inspect_render",
69177
69343
  category: "analyze",
69178
69344
  cost: "low",
69345
+ title: "Inspect Render",
69346
+ annotations: { readOnly: false, openWorld: false },
69179
69347
  description: "Render inspection: runs cheap local video checks by default, optionally adds Gemini AI review with ai: true, and writes review-report.json by default.",
69180
69348
  schema: external_exports.object({
69181
69349
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION2),
@@ -69240,6 +69408,8 @@ var init_inspect = __esm({
69240
69408
  name: "inspect_media",
69241
69409
  category: "analyze",
69242
69410
  cost: "low",
69411
+ title: "Inspect Media with AI",
69412
+ annotations: { readOnly: true, openWorld: true },
69243
69413
  description: "Analyze media (image, video, or YouTube URL) using Gemini AI. Requires GOOGLE_API_KEY.",
69244
69414
  schema: external_exports.object({
69245
69415
  source: external_exports.string().describe("Path to image/video or YouTube URL"),
@@ -69268,6 +69438,8 @@ var init_inspect = __esm({
69268
69438
  name: "inspect_video",
69269
69439
  category: "analyze",
69270
69440
  cost: "low",
69441
+ title: "Inspect Video with AI",
69442
+ annotations: { readOnly: true, openWorld: true },
69271
69443
  description: "Analyze video content using Gemini AI with temporal understanding. Requires GOOGLE_API_KEY.",
69272
69444
  schema: external_exports.object({
69273
69445
  source: external_exports.string().describe("Path to video file"),
@@ -69296,6 +69468,8 @@ var init_inspect = __esm({
69296
69468
  name: "inspect_review",
69297
69469
  category: "analyze",
69298
69470
  cost: "low",
69471
+ title: "Review Video with AI",
69472
+ annotations: { readOnly: false, openWorld: true },
69299
69473
  description: "AI video review: analyzes quality, suggests fixes, and optionally auto-applies them. Requires GOOGLE_API_KEY.",
69300
69474
  schema: external_exports.object({
69301
69475
  videoPath: external_exports.string().describe("Path to the video file to review"),
@@ -69324,6 +69498,8 @@ var init_inspect = __esm({
69324
69498
  name: "inspect_suggest",
69325
69499
  category: "analyze",
69326
69500
  cost: "low",
69501
+ title: "Suggest Edits with AI",
69502
+ annotations: { readOnly: false, openWorld: true },
69327
69503
  description: "Get natural-language edit suggestions for a project from Gemini. Returns suggestions array with type/confidence/clipIds. With `apply: true`, applies the first suggestion in place. Requires GOOGLE_API_KEY.",
69328
69504
  schema: external_exports.object({
69329
69505
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -69379,6 +69555,8 @@ var init_generate2 = __esm({
69379
69555
  name: "generate_motion",
69380
69556
  category: "generate",
69381
69557
  cost: "low",
69558
+ title: "Generate Motion Graphics",
69559
+ annotations: { readOnly: false, openWorld: true },
69382
69560
  description: "Generate standalone motion graphics using Claude or Gemini + Remotion. For overlays on an existing video, prefer edit_motion_overlay. Requires ANTHROPIC_API_KEY (Claude) or GOOGLE_API_KEY (Gemini).",
69383
69561
  schema: external_exports.object({
69384
69562
  description: external_exports.string().describe("Description of the motion graphic to generate"),
@@ -69418,6 +69596,8 @@ var init_generate2 = __esm({
69418
69596
  name: "generate_speech",
69419
69597
  category: "generate",
69420
69598
  cost: "low",
69599
+ title: "Generate Speech Audio",
69600
+ annotations: { readOnly: false, openWorld: true },
69421
69601
  description: "Generate speech from text using ElevenLabs TTS. Requires ELEVENLABS_API_KEY.",
69422
69602
  schema: external_exports.object({
69423
69603
  text: external_exports.string().describe("Text to convert to speech"),
@@ -69438,6 +69618,8 @@ var init_generate2 = __esm({
69438
69618
  name: "generate_narration",
69439
69619
  category: "generate",
69440
69620
  cost: "low",
69621
+ title: "Generate Narration Audio",
69622
+ annotations: { readOnly: false, openWorld: true },
69441
69623
  description: "Generate narration from text using ElevenLabs TTS. Product-facing alias for generate_speech. Requires ELEVENLABS_API_KEY.",
69442
69624
  schema: external_exports.object({
69443
69625
  text: external_exports.string().describe("Narration text to convert to speech"),
@@ -69462,6 +69644,8 @@ var init_generate2 = __esm({
69462
69644
  name: "generate_sound_effect",
69463
69645
  category: "generate",
69464
69646
  cost: "low",
69647
+ title: "Generate Sound Effect",
69648
+ annotations: { readOnly: false, openWorld: true },
69465
69649
  description: "Generate sound effects using ElevenLabs. Requires ELEVENLABS_API_KEY.",
69466
69650
  schema: external_exports.object({
69467
69651
  prompt: external_exports.string().describe("Description of the sound effect"),
@@ -69483,6 +69667,8 @@ var init_generate2 = __esm({
69483
69667
  name: "generate_music",
69484
69668
  category: "generate",
69485
69669
  cost: "low",
69670
+ title: "Generate Music",
69671
+ annotations: { readOnly: false, openWorld: true },
69486
69672
  description: "Generate background music from text prompt. ElevenLabs (default, up to 10min) or Replicate MusicGen (max 30s). Requires ELEVENLABS_API_KEY or REPLICATE_API_TOKEN.",
69487
69673
  schema: external_exports.object({
69488
69674
  prompt: external_exports.string().describe("Description of the music to generate"),
@@ -69528,6 +69714,8 @@ var init_generate2 = __esm({
69528
69714
  name: "generate_music_status",
69529
69715
  category: "generate",
69530
69716
  cost: "free",
69717
+ title: "Check Music Generation Status",
69718
+ annotations: { readOnly: true, openWorld: true },
69531
69719
  description: "Check Replicate music generation task status. `generate_music` returns a task id; this tool polls it until the audio URL is ready. Requires REPLICATE_API_TOKEN.",
69532
69720
  schema: external_exports.object({
69533
69721
  taskId: external_exports.string().describe("Task ID returned from generate_music")
@@ -69551,6 +69739,8 @@ var init_generate2 = __esm({
69551
69739
  name: "generate_image",
69552
69740
  category: "generate",
69553
69741
  cost: "low",
69742
+ title: "Generate Image",
69743
+ annotations: { readOnly: false, openWorld: true },
69554
69744
  description: "Generate an image using AI. Supports Gemini (free), OpenAI GPT Image, or Grok Imagine. Requires GOOGLE_API_KEY (Gemini), OPENAI_API_KEY (OpenAI), or XAI_API_KEY (Grok).",
69555
69745
  schema: external_exports.object({
69556
69746
  prompt: external_exports.string().describe("Image description prompt"),
@@ -69584,6 +69774,8 @@ var init_generate2 = __esm({
69584
69774
  name: "generate_storyboard",
69585
69775
  category: "generate",
69586
69776
  cost: "low",
69777
+ title: "Generate Storyboard",
69778
+ annotations: { readOnly: false, openWorld: true },
69587
69779
  description: "Generate a video storyboard from text content using Claude. Returns scene segments with descriptions, visuals, and narration. Requires ANTHROPIC_API_KEY.",
69588
69780
  schema: external_exports.object({
69589
69781
  content: external_exports.string().describe("Text content to analyze (script, article, etc.)"),
@@ -69607,6 +69799,8 @@ var init_generate2 = __esm({
69607
69799
  name: "generate_background",
69608
69800
  category: "generate",
69609
69801
  cost: "low",
69802
+ title: "Generate Background Image",
69803
+ annotations: { readOnly: false, openWorld: true },
69610
69804
  description: "Generate a cinematic backdrop image (OpenAI gpt-image-2 / DALL\xB7E variant tuned for video backgrounds). Returns the image URL and, when `output` is provided, downloads the PNG to disk. Requires OPENAI_API_KEY.",
69611
69805
  schema: external_exports.object({
69612
69806
  description: external_exports.string().describe("Background description / image prompt."),
@@ -69631,6 +69825,8 @@ var init_generate2 = __esm({
69631
69825
  name: "generate_thumbnail",
69632
69826
  category: "generate",
69633
69827
  cost: "low",
69828
+ title: "Generate Thumbnail",
69829
+ annotations: { readOnly: false, openWorld: true },
69634
69830
  description: "Extract the best thumbnail frame from a video using Gemini AI analysis. Requires GOOGLE_API_KEY.",
69635
69831
  schema: external_exports.object({
69636
69832
  videoPath: external_exports.string().describe("Path to the video file"),
@@ -69652,6 +69848,8 @@ var init_generate2 = __esm({
69652
69848
  name: "generate_video",
69653
69849
  category: "generate",
69654
69850
  cost: "high",
69851
+ title: "Generate Video",
69852
+ annotations: { readOnly: false, openWorld: true },
69655
69853
  description: "Generate video using AI. Supports Seedance 2.0 via fal.ai, Grok, Kling, Runway, and Veo. Requires FAL_API_KEY, XAI_API_KEY, KLING_API_KEY, RUNWAY_API_SECRET, or GOOGLE_API_KEY.",
69656
69854
  schema: external_exports.object({
69657
69855
  prompt: external_exports.string().describe("Text prompt describing the video"),
@@ -69713,6 +69911,8 @@ var init_generate2 = __esm({
69713
69911
  name: "generate_video_status",
69714
69912
  category: "generate",
69715
69913
  cost: "free",
69914
+ title: "Check Video Generation Status",
69915
+ annotations: { readOnly: false, openWorld: true },
69716
69916
  description: "Check video generation status for Grok, Runway, Kling, or Veo tasks.",
69717
69917
  schema: external_exports.object({
69718
69918
  taskId: external_exports.string().describe("Task ID from video generation"),
@@ -69743,6 +69943,8 @@ var init_generate2 = __esm({
69743
69943
  name: "generate_video_cancel",
69744
69944
  category: "generate",
69745
69945
  cost: "free",
69946
+ title: "Cancel Video Generation",
69947
+ annotations: { readOnly: false, openWorld: true },
69746
69948
  description: "Cancel a Runway video generation task.",
69747
69949
  schema: external_exports.object({
69748
69950
  taskId: external_exports.string().describe("Task ID to cancel")
@@ -69761,6 +69963,8 @@ var init_generate2 = __esm({
69761
69963
  name: "generate_video_extend",
69762
69964
  category: "generate",
69763
69965
  cost: "high",
69966
+ title: "Extend Generated Video",
69967
+ annotations: { readOnly: false, openWorld: true },
69764
69968
  description: "Extend video duration using Kling or Veo. Requires the video/operation ID from a previous generation.",
69765
69969
  schema: external_exports.object({
69766
69970
  videoId: external_exports.string().describe("Video ID (Kling) or operation name (Veo)"),
@@ -69836,6 +70040,8 @@ var init_storyboard2 = __esm({
69836
70040
  name: "storyboard_list",
69837
70041
  category: "storyboard",
69838
70042
  cost: "free",
70043
+ title: "List Storyboard Beats",
70044
+ annotations: { readOnly: true, openWorld: false },
69839
70045
  description: "List beats, ids, durations, and cue blocks from a project's STORYBOARD.md.",
69840
70046
  schema: projectDirSchema,
69841
70047
  async execute(args, ctx) {
@@ -69862,6 +70068,8 @@ var init_storyboard2 = __esm({
69862
70068
  name: "storyboard_validate",
69863
70069
  category: "storyboard",
69864
70070
  cost: "free",
70071
+ title: "Validate Storyboard",
70072
+ annotations: { readOnly: true, openWorld: false },
69865
70073
  description: "Validate STORYBOARD.md beat ids and cue blocks.",
69866
70074
  schema: projectDirSchema,
69867
70075
  async execute(args, ctx) {
@@ -69892,6 +70100,8 @@ var init_storyboard2 = __esm({
69892
70100
  name: "storyboard_get",
69893
70101
  category: "storyboard",
69894
70102
  cost: "free",
70103
+ title: "Get Storyboard Beat",
70104
+ annotations: { readOnly: true, openWorld: false },
69895
70105
  description: "Return one STORYBOARD.md beat as structured data.",
69896
70106
  schema: external_exports.object({
69897
70107
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -69914,6 +70124,8 @@ var init_storyboard2 = __esm({
69914
70124
  name: "storyboard_set",
69915
70125
  category: "storyboard",
69916
70126
  cost: "free",
70127
+ title: "Set Storyboard Cue",
70128
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
69917
70129
  description: "Set or unset one cue on one beat in STORYBOARD.md.",
69918
70130
  schema: external_exports.object({
69919
70131
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -69950,6 +70162,8 @@ var init_storyboard2 = __esm({
69950
70162
  name: "storyboard_move",
69951
70163
  category: "storyboard",
69952
70164
  cost: "free",
70165
+ title: "Reorder Storyboard Beat",
70166
+ annotations: { readOnly: false, openWorld: false },
69953
70167
  description: "Move one beat after another beat in STORYBOARD.md.",
69954
70168
  schema: external_exports.object({
69955
70169
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -69980,6 +70194,8 @@ var init_storyboard2 = __esm({
69980
70194
  name: "storyboard_revise",
69981
70195
  category: "storyboard",
69982
70196
  cost: "low",
70197
+ title: "Revise Storyboard with AI",
70198
+ annotations: { readOnly: false, openWorld: true },
69983
70199
  description: "Revise an existing STORYBOARD.md from a natural-language request. Reads project context, validates the revised storyboard, and writes unless dryRun is true.",
69984
70200
  schema: external_exports.object({
69985
70201
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -70011,6 +70227,8 @@ var init_storyboard2 = __esm({
70011
70227
  name: "plan",
70012
70228
  category: "storyboard",
70013
70229
  cost: "free",
70230
+ title: "Plan Build Cost and Stages",
70231
+ annotations: { readOnly: true, openWorld: false },
70014
70232
  description: "Read STORYBOARD.md and return the build plan, missing artifacts, provider needs, and estimated cost.",
70015
70233
  schema: external_exports.object({
70016
70234
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -70091,6 +70309,8 @@ var init_remix = __esm({
70091
70309
  name: "remix_highlights",
70092
70310
  category: "pipeline",
70093
70311
  cost: "low",
70312
+ title: "Extract Video Highlights",
70313
+ annotations: { readOnly: false, openWorld: true },
70094
70314
  description: "Extract highlight clips from a longer video using AI analysis. Requires OPENAI_API_KEY+ANTHROPIC_API_KEY or GOOGLE_API_KEY (with --use-gemini).",
70095
70315
  schema: external_exports.object({
70096
70316
  media: external_exports.string().describe("Path to the input video file"),
@@ -70124,6 +70344,8 @@ var init_remix = __esm({
70124
70344
  name: "remix_auto_shorts",
70125
70345
  category: "pipeline",
70126
70346
  cost: "medium",
70347
+ title: "Generate Auto Shorts",
70348
+ annotations: { readOnly: false, openWorld: true },
70127
70349
  description: "Automatically generate short-form content (Reels/TikTok/Shorts) from a longer video. Same API key requirements as remix_highlights.",
70128
70350
  schema: external_exports.object({
70129
70351
  video: external_exports.string().describe("Path to the input video file"),
@@ -70161,6 +70383,8 @@ var init_remix = __esm({
70161
70383
  name: "run",
70162
70384
  category: "pipeline",
70163
70385
  cost: "very-high",
70386
+ title: "Run YAML Pipeline",
70387
+ annotations: { readOnly: false, openWorld: true },
70164
70388
  surfaces: ["mcp"],
70165
70389
  description: "Execute a declarative YAML pipeline (Video as Code). Accepts either a file path or inline YAML. Supports dry-run, resume-from-checkpoint, and budget limits. Cost depends on the steps \u2014 use dryRun: true first to preview.",
70166
70390
  schema: external_exports.object({
@@ -70240,6 +70464,8 @@ var init_remix = __esm({
70240
70464
  name: "remix_regenerate_scene",
70241
70465
  category: "pipeline",
70242
70466
  cost: "high",
70467
+ title: "Regenerate Storyboard Scenes",
70468
+ annotations: { readOnly: false, openWorld: true },
70243
70469
  description: "Regenerate specific scenes against an existing storyboard.{yaml,json} on disk. Can regenerate video, image, or narration independently.",
70244
70470
  schema: external_exports.object({
70245
70471
  projectDir: external_exports.string().describe("Path to the project output directory containing storyboard.json"),
@@ -70284,6 +70510,8 @@ var init_detect2 = __esm({
70284
70510
  name: "detect_scenes",
70285
70511
  category: "detect",
70286
70512
  cost: "free",
70513
+ title: "Detect Scene Cuts",
70514
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
70287
70515
  description: "Detect scene changes in video using FFmpeg. No API key needed.",
70288
70516
  schema: external_exports.object({
70289
70517
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -70308,6 +70536,8 @@ var init_detect2 = __esm({
70308
70536
  name: "detect_silence",
70309
70537
  category: "detect",
70310
70538
  cost: "free",
70539
+ title: "Detect Silence Periods",
70540
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
70311
70541
  description: "Detect silence periods in audio/video using FFmpeg. No API key needed.",
70312
70542
  schema: external_exports.object({
70313
70543
  mediaPath: external_exports.string().describe("Path to the audio/video file"),
@@ -70329,6 +70559,8 @@ var init_detect2 = __esm({
70329
70559
  name: "detect_beats",
70330
70560
  category: "detect",
70331
70561
  cost: "free",
70562
+ title: "Detect Audio Beats",
70563
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
70332
70564
  description: "Detect beats in audio for music sync using FFmpeg loudness analysis. No API key needed.",
70333
70565
  schema: external_exports.object({
70334
70566
  audioPath: external_exports.string().describe("Path to the audio file"),
@@ -70402,6 +70634,8 @@ var init_timeline = __esm({
70402
70634
  name: "timeline_create",
70403
70635
  category: "timeline",
70404
70636
  cost: "free",
70637
+ title: "Create Timeline",
70638
+ annotations: { readOnly: false, openWorld: false },
70405
70639
  description: "Create a low-level timeline JSON file for FFmpeg-style editing",
70406
70640
  schema: external_exports.object({
70407
70641
  name: external_exports.string().describe("Timeline name or directory path"),
@@ -70432,6 +70666,8 @@ var init_timeline = __esm({
70432
70666
  name: "timeline_info",
70433
70667
  category: "timeline",
70434
70668
  cost: "free",
70669
+ title: "Get Timeline Info",
70670
+ annotations: { readOnly: true, openWorld: false },
70435
70671
  description: "Get information about a timeline JSON file. Legacy *.vibe.json files are supported.",
70436
70672
  schema: external_exports.object({
70437
70673
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
@@ -70459,6 +70695,8 @@ var init_timeline = __esm({
70459
70695
  name: "timeline_add_source",
70460
70696
  category: "timeline",
70461
70697
  cost: "free",
70698
+ title: "Add Source to Timeline",
70699
+ annotations: { readOnly: false, openWorld: false },
70462
70700
  description: "Add a media source (video, audio, image) to the timeline",
70463
70701
  schema: external_exports.object({
70464
70702
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70484,6 +70722,8 @@ var init_timeline = __esm({
70484
70722
  name: "timeline_add_clip",
70485
70723
  category: "timeline",
70486
70724
  cost: "free",
70725
+ title: "Add Clip to Timeline",
70726
+ annotations: { readOnly: false, openWorld: false },
70487
70727
  description: "Add a clip to the timeline from an existing source",
70488
70728
  schema: external_exports.object({
70489
70729
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70515,6 +70755,8 @@ var init_timeline = __esm({
70515
70755
  name: "timeline_split_clip",
70516
70756
  category: "timeline",
70517
70757
  cost: "free",
70758
+ title: "Split Clip",
70759
+ annotations: { readOnly: false, openWorld: false },
70518
70760
  description: "Split a clip at a specific time",
70519
70761
  schema: external_exports.object({
70520
70762
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70533,6 +70775,8 @@ var init_timeline = __esm({
70533
70775
  name: "timeline_trim_clip",
70534
70776
  category: "timeline",
70535
70777
  cost: "free",
70778
+ title: "Trim Clip",
70779
+ annotations: { readOnly: false, openWorld: false },
70536
70780
  description: "Trim a clip by adjusting its start or end",
70537
70781
  schema: external_exports.object({
70538
70782
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70552,6 +70796,8 @@ var init_timeline = __esm({
70552
70796
  name: "timeline_move_clip",
70553
70797
  category: "timeline",
70554
70798
  cost: "free",
70799
+ title: "Move Clip",
70800
+ annotations: { readOnly: false, openWorld: false },
70555
70801
  description: "Move a clip to a new position or track",
70556
70802
  schema: external_exports.object({
70557
70803
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70574,6 +70820,8 @@ var init_timeline = __esm({
70574
70820
  name: "timeline_delete_clip",
70575
70821
  category: "timeline",
70576
70822
  cost: "free",
70823
+ title: "Delete Clip",
70824
+ annotations: { readOnly: false, openWorld: false },
70577
70825
  description: "Delete a clip from the timeline",
70578
70826
  schema: external_exports.object({
70579
70827
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70590,6 +70838,8 @@ var init_timeline = __esm({
70590
70838
  name: "timeline_duplicate_clip",
70591
70839
  category: "timeline",
70592
70840
  cost: "free",
70841
+ title: "Duplicate Clip",
70842
+ annotations: { readOnly: false, openWorld: false },
70593
70843
  description: "Duplicate a clip on the timeline (optionally at a new start time)",
70594
70844
  schema: external_exports.object({
70595
70845
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70608,6 +70858,8 @@ var init_timeline = __esm({
70608
70858
  name: "timeline_add_effect",
70609
70859
  category: "timeline",
70610
70860
  cost: "free",
70861
+ title: "Add Effect to Clip",
70862
+ annotations: { readOnly: false, openWorld: false },
70611
70863
  description: "Add an effect to a clip",
70612
70864
  schema: external_exports.object({
70613
70865
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70634,6 +70886,8 @@ var init_timeline = __esm({
70634
70886
  name: "timeline_add_track",
70635
70887
  category: "timeline",
70636
70888
  cost: "free",
70889
+ title: "Add Track to Timeline",
70890
+ annotations: { readOnly: false, openWorld: false },
70637
70891
  description: "Add a new track to the timeline",
70638
70892
  schema: external_exports.object({
70639
70893
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -70660,6 +70914,8 @@ var init_timeline = __esm({
70660
70914
  name: "timeline_list",
70661
70915
  category: "timeline",
70662
70916
  cost: "free",
70917
+ title: "List Timeline Contents",
70918
+ annotations: { readOnly: true, openWorld: false },
70663
70919
  description: "List all sources, tracks, and clips in a project",
70664
70920
  schema: external_exports.object({
70665
70921
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
@@ -70710,6 +70966,8 @@ var init_project2 = __esm({
70710
70966
  name: "project_create",
70711
70967
  category: "project",
70712
70968
  cost: "free",
70969
+ title: "Create Project",
70970
+ annotations: { readOnly: false, openWorld: false },
70713
70971
  description: "Deprecated alias for creating low-level timeline state. Prefer timeline_create.",
70714
70972
  schema: external_exports.object({
70715
70973
  name: external_exports.string().describe("Project name"),
@@ -70734,6 +70992,8 @@ var init_project2 = __esm({
70734
70992
  name: "project_info",
70735
70993
  category: "project",
70736
70994
  cost: "free",
70995
+ title: "Get Project Info",
70996
+ annotations: { readOnly: true, openWorld: false },
70737
70997
  description: "Deprecated alias for timeline_info. Legacy *.vibe.json files remain supported.",
70738
70998
  schema: external_exports.object({
70739
70999
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
@@ -71633,6 +71893,8 @@ var init_export2 = __esm({
71633
71893
  name: "export_video",
71634
71894
  category: "export",
71635
71895
  cost: "free",
71896
+ title: "Export Timeline to Video",
71897
+ annotations: { readOnly: false, openWorld: false },
71636
71898
  description: "Export a VibeFrame timeline to a video file (MP4, WebM, or MOV). Requires FFmpeg.",
71637
71899
  schema: external_exports.object({
71638
71900
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -71732,6 +71994,8 @@ var init_agent_only = __esm({
71732
71994
  name: "fs_list",
71733
71995
  category: "agent-only",
71734
71996
  cost: "free",
71997
+ title: "List Files",
71998
+ annotations: { readOnly: true, openWorld: false },
71735
71999
  surfaces: ["agent"],
71736
72000
  description: "List files and directories in a path",
71737
72001
  schema: external_exports.object({
@@ -71765,6 +72029,8 @@ var init_agent_only = __esm({
71765
72029
  name: "fs_read",
71766
72030
  category: "agent-only",
71767
72031
  cost: "free",
72032
+ title: "Read File",
72033
+ annotations: { readOnly: true, openWorld: false },
71768
72034
  surfaces: ["agent"],
71769
72035
  description: "Read contents of a text file",
71770
72036
  schema: external_exports.object({
@@ -71787,6 +72053,8 @@ var init_agent_only = __esm({
71787
72053
  name: "fs_write",
71788
72054
  category: "agent-only",
71789
72055
  cost: "free",
72056
+ title: "Write File",
72057
+ annotations: { readOnly: false, openWorld: false },
71790
72058
  surfaces: ["agent"],
71791
72059
  description: "Write content to a file",
71792
72060
  schema: external_exports.object({
@@ -71807,6 +72075,8 @@ var init_agent_only = __esm({
71807
72075
  name: "fs_exists",
71808
72076
  category: "agent-only",
71809
72077
  cost: "free",
72078
+ title: "Check Path Exists",
72079
+ annotations: { readOnly: true, openWorld: false },
71810
72080
  surfaces: ["agent"],
71811
72081
  description: "Check if a file or directory exists",
71812
72082
  schema: external_exports.object({
@@ -71828,6 +72098,8 @@ var init_agent_only = __esm({
71828
72098
  name: "batch_import",
71829
72099
  category: "agent-only",
71830
72100
  cost: "free",
72101
+ title: "Batch Import Media",
72102
+ annotations: { readOnly: false, openWorld: false },
71831
72103
  surfaces: ["agent"],
71832
72104
  description: "Import multiple media files from a directory into a project. Scans directory for video, audio, and image files.",
71833
72105
  schema: external_exports.object({
@@ -71897,6 +72169,8 @@ var init_agent_only = __esm({
71897
72169
  name: "batch_concat",
71898
72170
  category: "agent-only",
71899
72171
  cost: "free",
72172
+ title: "Batch Concatenate Sources",
72173
+ annotations: { readOnly: false, openWorld: false },
71900
72174
  surfaces: ["agent"],
71901
72175
  description: "Concatenate multiple sources into sequential clips on the timeline",
71902
72176
  schema: external_exports.object({
@@ -71966,6 +72240,8 @@ var init_agent_only = __esm({
71966
72240
  name: "batch_apply_effect",
71967
72241
  category: "agent-only",
71968
72242
  cost: "free",
72243
+ title: "Batch Apply Effect",
72244
+ annotations: { readOnly: false, openWorld: false },
71969
72245
  surfaces: ["agent"],
71970
72246
  description: "Apply an effect to multiple clips at once",
71971
72247
  schema: external_exports.object({
@@ -72022,6 +72298,8 @@ var init_agent_only = __esm({
72022
72298
  name: "timeline_clear",
72023
72299
  category: "agent-only",
72024
72300
  cost: "free",
72301
+ title: "Clear Timeline",
72302
+ annotations: { readOnly: false, openWorld: false },
72025
72303
  surfaces: ["agent"],
72026
72304
  description: "Clear timeline contents (remove clips, tracks, or sources)",
72027
72305
  schema: external_exports.object({
@@ -72096,6 +72374,8 @@ var init_agent_only = __esm({
72096
72374
  name: "project_set",
72097
72375
  category: "agent-only",
72098
72376
  cost: "free",
72377
+ title: "Update Project Settings",
72378
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
72099
72379
  surfaces: ["agent"],
72100
72380
  description: "Update timeline settings (name, aspect ratio, frame rate)",
72101
72381
  schema: external_exports.object({
@@ -72141,6 +72421,8 @@ var init_agent_only = __esm({
72141
72421
  name: "project_open",
72142
72422
  category: "agent-only",
72143
72423
  cost: "free",
72424
+ title: "Open Project",
72425
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
72144
72426
  surfaces: ["agent"],
72145
72427
  description: "Open an existing project and set it as the current context",
72146
72428
  schema: external_exports.object({
@@ -72179,6 +72461,8 @@ var init_agent_only = __esm({
72179
72461
  name: "project_save",
72180
72462
  category: "agent-only",
72181
72463
  cost: "free",
72464
+ title: "Save Project",
72465
+ annotations: { readOnly: false, openWorld: false },
72182
72466
  surfaces: ["agent"],
72183
72467
  description: "Save the current project (uses ctx.agent.projectPath if no path given)",
72184
72468
  schema: external_exports.object({
@@ -72213,6 +72497,8 @@ var init_agent_only = __esm({
72213
72497
  name: "export_audio",
72214
72498
  category: "agent-only",
72215
72499
  cost: "free",
72500
+ title: "Export Audio",
72501
+ annotations: { readOnly: false, openWorld: false },
72216
72502
  surfaces: ["agent"],
72217
72503
  description: "Export audio track from a project. Not implemented \u2014 use export_video then strip audio with FFmpeg.",
72218
72504
  schema: external_exports.object({
@@ -72231,6 +72517,8 @@ var init_agent_only = __esm({
72231
72517
  name: "export_subtitles",
72232
72518
  category: "agent-only",
72233
72519
  cost: "free",
72520
+ title: "Export Subtitles",
72521
+ annotations: { readOnly: false, openWorld: false },
72234
72522
  surfaces: ["agent"],
72235
72523
  description: "Export subtitles from transcription. Not implemented \u2014 use audio_transcribe to generate subtitles from audio.",
72236
72524
  schema: external_exports.object({
@@ -72249,6 +72537,8 @@ var init_agent_only = __esm({
72249
72537
  name: "media_info",
72250
72538
  category: "agent-only",
72251
72539
  cost: "free",
72540
+ title: "Get Media Info",
72541
+ annotations: { readOnly: true, openWorld: false },
72252
72542
  surfaces: ["agent"],
72253
72543
  description: "Get information about a media file (duration, resolution, codec, etc.)",
72254
72544
  schema: external_exports.object({
@@ -72333,6 +72623,8 @@ Audio:`);
72333
72623
  name: "media_compress",
72334
72624
  category: "agent-only",
72335
72625
  cost: "free",
72626
+ title: "Compress Media",
72627
+ annotations: { readOnly: false, openWorld: false },
72336
72628
  surfaces: ["agent"],
72337
72629
  description: "Compress a video or audio file using FFmpeg",
72338
72630
  schema: external_exports.object({
@@ -72394,6 +72686,8 @@ Audio:`);
72394
72686
  name: "media_convert",
72395
72687
  category: "agent-only",
72396
72688
  cost: "free",
72689
+ title: "Convert Media",
72690
+ annotations: { readOnly: false, openWorld: false },
72397
72691
  surfaces: ["agent"],
72398
72692
  description: "Convert media file to a different format using FFmpeg",
72399
72693
  schema: external_exports.object({
@@ -72441,6 +72735,8 @@ Audio:`);
72441
72735
  name: "media_concat",
72442
72736
  category: "agent-only",
72443
72737
  cost: "free",
72738
+ title: "Concatenate Media Files",
72739
+ annotations: { readOnly: false, openWorld: false },
72444
72740
  surfaces: ["agent"],
72445
72741
  description: "Concatenate multiple media files into one using FFmpeg",
72446
72742
  schema: external_exports.object({
@@ -72541,6 +72837,8 @@ var init_walkthrough = __esm({
72541
72837
  name: "guide",
72542
72838
  category: "agent",
72543
72839
  cost: "free",
72840
+ title: "Load Workflow Guide",
72841
+ annotations: { readOnly: true, openWorld: false },
72544
72842
  description: "Load the step-by-step guide for a vibe workflow (motion overlays, BUILD scene authoring, YAML pipeline authoring, architecture choices). Universal CLI-equivalent of `vibe guide <topic>` and Claude Code's /vibe-* slash commands. Without a topic, returns the guide catalog for discovery.",
72545
72843
  schema: guideSchema,
72546
72844
  async execute(args) {
@@ -72584,6 +72882,8 @@ var init_status = __esm({
72584
72882
  name: "status_job",
72585
72883
  category: "status",
72586
72884
  cost: "free",
72885
+ title: "Check Job Status",
72886
+ annotations: { readOnly: false, destructive: false, openWorld: true },
72587
72887
  description: "Read one local async job record and optionally refresh supported provider status. Supports Runway/Kling video and Replicate music live checks. Also tracks long-running MCP build/render jobs (jobType build/render, provider local): their records are updated in-process \u2014 on completion result.payload carries the full tool result; status 'unknown' means the MCP server restarted mid-job (check build-report.json / render-report.json on disk).",
72588
72888
  schema: external_exports.object({
72589
72889
  jobId: external_exports.string().describe("Local job id returned by a no-wait command."),
@@ -72619,6 +72919,8 @@ var init_status = __esm({
72619
72919
  name: "status_project",
72620
72920
  category: "status",
72621
72921
  cost: "free",
72922
+ title: "Check Project Status",
72923
+ annotations: { readOnly: false, destructive: false, openWorld: true },
72622
72924
  description: "Summarize build-report.json, review-report.json, and local async job records for a VibeFrame project.",
72623
72925
  schema: external_exports.object({
72624
72926
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION4),
@@ -72911,7 +73213,7 @@ init_source();
72911
73213
  // package.json
72912
73214
  var package_default = {
72913
73215
  name: "@vibeframe/cli",
72914
- version: "0.109.2",
73216
+ version: "0.111.0",
72915
73217
  description: "VibeFrame CLI - agentic video workflow runtime",
72916
73218
  private: false,
72917
73219
  license: "MIT",