@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.
@@ -51300,6 +51300,76 @@ function pickOutputPath(data) {
51300
51300
  return typeof candidate === "string" ? candidate : void 0;
51301
51301
  }
51302
51302
 
51303
+ // src/tools/_shared/elicit.ts
51304
+ var NARRATION_CHOICES = ["kokoro", "elevenlabs"];
51305
+ var BACKDROP_CHOICES = ["skip", "openai"];
51306
+ function planBuildElicitation(args) {
51307
+ const assetsWillRun = args.stage === void 0 || args.stage === "all" || args.stage === "assets";
51308
+ if (!assetsWillRun) return null;
51309
+ const properties = {};
51310
+ const required = [];
51311
+ const narrationUndecided = !args.skipNarration && (args.ttsProvider === void 0 || args.ttsProvider === "auto");
51312
+ if (narrationUndecided) {
51313
+ properties.narration = {
51314
+ type: "string",
51315
+ title: "Narration voice-over",
51316
+ description: "Which TTS engine narrates the video?",
51317
+ enum: [...NARRATION_CHOICES],
51318
+ enumNames: [
51319
+ "Kokoro \u2014 free, runs locally on this machine",
51320
+ "ElevenLabs \u2014 cloud TTS, uses your ElevenLabs credits"
51321
+ ]
51322
+ };
51323
+ required.push("narration");
51324
+ }
51325
+ if (args.skipBackdrop === void 0 && args.imageProvider === void 0) {
51326
+ properties.backdrop_images = {
51327
+ type: "string",
51328
+ title: "Backdrop images",
51329
+ description: "Generate AI background images for each scene?",
51330
+ enum: [...BACKDROP_CHOICES],
51331
+ enumNames: [
51332
+ "Skip \u2014 free, pure typographic scenes",
51333
+ "OpenAI \u2014 paid image generation (roughly $1-3 per video)"
51334
+ ]
51335
+ };
51336
+ required.push("backdrop_images");
51337
+ }
51338
+ if (args.maxCostUsd === void 0) {
51339
+ properties.max_cost_usd = {
51340
+ type: "number",
51341
+ title: "Max provider spend (USD)",
51342
+ description: "Abort before any paid provider call when the estimate exceeds this cap. Leave empty for no cap.",
51343
+ minimum: 0
51344
+ };
51345
+ }
51346
+ if (Object.keys(properties).length === 0) return null;
51347
+ return {
51348
+ message: "VibeFrame is about to build this video. Choose how the assets are generated:",
51349
+ requestedSchema: { type: "object", properties, required }
51350
+ };
51351
+ }
51352
+ function applyElicitationAnswers(args, content) {
51353
+ if (!content) return args;
51354
+ const next = { ...args };
51355
+ const narration = content.narration;
51356
+ if (typeof narration === "string" && NARRATION_CHOICES.includes(narration)) {
51357
+ next.ttsProvider = narration;
51358
+ }
51359
+ const backdrop = content.backdrop_images;
51360
+ if (backdrop === "skip") {
51361
+ next.skipBackdrop = true;
51362
+ } else if (backdrop === "openai") {
51363
+ next.skipBackdrop = false;
51364
+ next.imageProvider = "openai";
51365
+ }
51366
+ const cap = content.max_cost_usd;
51367
+ if (typeof cap === "number" && Number.isFinite(cap) && cap >= 0) {
51368
+ next.maxCostUsd = cap;
51369
+ }
51370
+ return next;
51371
+ }
51372
+
51303
51373
  // src/commands/_shared/visual-styles.ts
51304
51374
  var STYLES = [
51305
51375
  {
@@ -53103,6 +53173,8 @@ var sceneStylesTool = defineTool({
53103
53173
  name: "scene_list_styles",
53104
53174
  category: "scene",
53105
53175
  cost: "free",
53176
+ title: "List Visual Styles",
53177
+ annotations: { readOnly: true, openWorld: false },
53106
53178
  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.",
53107
53179
  schema: sceneStylesSchema,
53108
53180
  async execute(args) {
@@ -53164,6 +53236,8 @@ var sceneInitTool = defineTool({
53164
53236
  name: "init",
53165
53237
  category: "scene",
53166
53238
  cost: "free",
53239
+ title: "Initialize Video Project",
53240
+ annotations: { readOnly: false, destructive: false, idempotent: true, openWorld: false },
53167
53241
  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.",
53168
53242
  schema: sceneInitSchema,
53169
53243
  async execute(args, ctx) {
@@ -53214,6 +53288,8 @@ var sceneAddTool = defineTool({
53214
53288
  name: "scene_add",
53215
53289
  category: "scene",
53216
53290
  cost: "low",
53291
+ title: "Add Scene from Preset",
53292
+ annotations: { readOnly: false, openWorld: true },
53217
53293
  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.",
53218
53294
  schema: sceneAddSchema,
53219
53295
  async execute(args, ctx) {
@@ -53292,6 +53368,8 @@ var sceneLintTool = defineTool({
53292
53368
  name: "scene_lint",
53293
53369
  category: "scene",
53294
53370
  cost: "free",
53371
+ title: "Lint Scene Compositions",
53372
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
53295
53373
  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.",
53296
53374
  schema: sceneLintSchema,
53297
53375
  async execute(args, ctx) {
@@ -53329,6 +53407,8 @@ var sceneRepairTool = defineTool({
53329
53407
  name: "scene_repair",
53330
53408
  category: "scene",
53331
53409
  cost: "free",
53410
+ title: "Repair Scene Compositions",
53411
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
53332
53412
  description: "Apply deterministic mechanical scene repairs. Currently uses the safe lint auto-fix allow-list and never performs semantic creative rewrites.",
53333
53413
  schema: sceneRepairSchema,
53334
53414
  async execute(args, ctx) {
@@ -53409,6 +53489,8 @@ var sceneRenderTool = defineTool({
53409
53489
  name: "render",
53410
53490
  category: "scene",
53411
53491
  cost: "free",
53492
+ title: "Render Video to MP4",
53493
+ annotations: { readOnly: false, openWorld: false },
53412
53494
  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.",
53413
53495
  schema: sceneRenderSchema,
53414
53496
  async execute(args, ctx) {
@@ -53538,9 +53620,34 @@ var sceneBuildTool = defineTool({
53538
53620
  name: "build",
53539
53621
  category: "scene",
53540
53622
  cost: "high",
53541
- 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.",
53623
+ title: "Build Video from Storyboard",
53624
+ annotations: { readOnly: false, openWorld: true },
53625
+ 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.",
53542
53626
  schema: sceneBuildSchema,
53543
53627
  async execute(args, ctx) {
53628
+ let warnings;
53629
+ if (ctx.surface === "mcp" && ctx.elicit) {
53630
+ const form = planBuildElicitation(args);
53631
+ if (form) {
53632
+ const outcome = await ctx.elicit(form).catch(() => null);
53633
+ if (outcome === null) {
53634
+ warnings = ["Asset-choice elicitation failed or timed out; proceeding with defaults."];
53635
+ } else if (outcome.action === "accept") {
53636
+ args = applyElicitationAnswers(args, outcome.content);
53637
+ } else {
53638
+ return {
53639
+ success: false,
53640
+ error: "Build cancelled \u2014 the user declined the asset choices.",
53641
+ data: {
53642
+ cancelled: true,
53643
+ retryWith: [
53644
+ `build { projectDir: "${args.projectDir ?? "."}", ttsProvider: "kokoro", skipBackdrop: true }`
53645
+ ]
53646
+ }
53647
+ };
53648
+ }
53649
+ }
53650
+ }
53544
53651
  const projectDir = args.projectDir ? resolve26(ctx.workingDirectory, args.projectDir) : ctx.workingDirectory;
53545
53652
  const runBuild = (report) => executeSceneBuild({
53546
53653
  projectDir,
@@ -53568,7 +53675,9 @@ var sceneBuildTool = defineTool({
53568
53675
  ctx.onProgress?.({ message: update.message ?? update.stage });
53569
53676
  report(update);
53570
53677
  }
53571
- }).then(mapBuildResultToToolResult);
53678
+ }).then(mapBuildResultToToolResult).then(
53679
+ (result) => warnings === void 0 ? result : { ...result, data: { ...result.data, elicitationWarnings: warnings } }
53680
+ );
53572
53681
  if (ctx.surface !== "mcp") {
53573
53682
  return runBuild(() => void 0);
53574
53683
  }
@@ -53595,6 +53704,8 @@ var sceneInstallSkillTool = defineTool({
53595
53704
  name: "scene_install_skill",
53596
53705
  category: "scene",
53597
53706
  cost: "free",
53707
+ title: "Install Hyperframes Skill",
53708
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
53598
53709
  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.",
53599
53710
  schema: sceneInstallSkillSchema,
53600
53711
  async execute(args, ctx) {
@@ -53641,6 +53752,8 @@ var sceneComposePromptsTool = defineTool({
53641
53752
  name: "scene_compose_prompts",
53642
53753
  category: "scene",
53643
53754
  cost: "free",
53755
+ title: "Get Scene Authoring Prompts",
53756
+ annotations: { readOnly: true, openWorld: false },
53644
53757
  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.",
53645
53758
  schema: sceneComposePromptsSchema,
53646
53759
  async execute(args, ctx) {
@@ -53683,6 +53796,8 @@ var sceneSubmitTool = defineTool({
53683
53796
  name: "scene_submit",
53684
53797
  category: "scene",
53685
53798
  cost: "free",
53799
+ title: "Submit Scene HTML",
53800
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
53686
53801
  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.",
53687
53802
  schema: sceneSubmitSchema,
53688
53803
  async execute(args, ctx) {
@@ -53724,6 +53839,8 @@ var audioTranscribeTool = defineTool({
53724
53839
  name: "audio_transcribe",
53725
53840
  category: "audio",
53726
53841
  cost: "low",
53842
+ title: "Transcribe Audio",
53843
+ annotations: { readOnly: false, openWorld: true },
53727
53844
  description: "Transcribe audio using OpenAI Whisper. Outputs text, SRT, or VTT. Requires OPENAI_API_KEY.",
53728
53845
  schema: external_exports.object({
53729
53846
  audioPath: external_exports.string().describe("Input audio file path"),
@@ -53753,6 +53870,8 @@ var audioIsolateTool = defineTool({
53753
53870
  name: "audio_isolate",
53754
53871
  category: "audio",
53755
53872
  cost: "low",
53873
+ title: "Isolate Vocals from Audio",
53874
+ annotations: { readOnly: false, openWorld: true },
53756
53875
  description: "Isolate vocals from audio using ElevenLabs. Requires ELEVENLABS_API_KEY.",
53757
53876
  schema: external_exports.object({
53758
53877
  audioPath: external_exports.string().describe("Input audio file path"),
@@ -53772,6 +53891,8 @@ var audioVoiceCloneTool = defineTool({
53772
53891
  name: "audio_clone_voice",
53773
53892
  category: "audio",
53774
53893
  cost: "low",
53894
+ title: "Clone Voice from Samples",
53895
+ annotations: { readOnly: false, destructive: false, openWorld: true },
53775
53896
  description: "Clone a voice from audio samples using ElevenLabs. Requires ELEVENLABS_API_KEY.",
53776
53897
  schema: external_exports.object({
53777
53898
  samplePaths: external_exports.array(external_exports.string()).describe("Audio sample file paths (1-25 files)"),
@@ -53793,6 +53914,8 @@ var audioDubTool = defineTool({
53793
53914
  name: "audio_dub",
53794
53915
  category: "audio",
53795
53916
  cost: "high",
53917
+ title: "Dub Audio to Another Language",
53918
+ annotations: { readOnly: false, openWorld: true },
53796
53919
  description: "Dub audio/video to another language (transcribe + translate + TTS). Requires OPENAI_API_KEY, ANTHROPIC_API_KEY, ELEVENLABS_API_KEY.",
53797
53920
  schema: external_exports.object({
53798
53921
  mediaPath: external_exports.string().describe("Input media file (video or audio)"),
@@ -53823,6 +53946,8 @@ var audioDuckTool = defineTool({
53823
53946
  name: "audio_duck",
53824
53947
  category: "audio",
53825
53948
  cost: "free",
53949
+ title: "Duck Background Music",
53950
+ annotations: { readOnly: false, openWorld: false },
53826
53951
  description: "Auto-duck background music when voice is present using FFmpeg sidechain compression. Free, no API key needed.",
53827
53952
  schema: external_exports.object({
53828
53953
  musicPath: external_exports.string().describe("Background music file path"),
@@ -54119,6 +54244,8 @@ var editSilenceCutTool = defineTool({
54119
54244
  name: "edit_silence_cut",
54120
54245
  category: "edit",
54121
54246
  cost: "free",
54247
+ title: "Cut Silence from Video",
54248
+ annotations: { readOnly: false, openWorld: true },
54122
54249
  description: "Remove silent segments from a video using FFmpeg or Gemini AI detection. No API key needed for FFmpeg mode.",
54123
54250
  schema: external_exports.object({
54124
54251
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54149,6 +54276,8 @@ var editCaptionTool = defineTool({
54149
54276
  name: "edit_caption",
54150
54277
  category: "edit",
54151
54278
  cost: "low",
54279
+ title: "Burn Captions into Video",
54280
+ annotations: { readOnly: false, openWorld: true },
54152
54281
  description: "Transcribe audio and burn styled captions into video. Requires OPENAI_API_KEY for Whisper transcription.",
54153
54282
  schema: external_exports.object({
54154
54283
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54173,6 +54302,8 @@ var editFadeTool = defineTool({
54173
54302
  name: "edit_fade",
54174
54303
  category: "edit",
54175
54304
  cost: "free",
54305
+ title: "Apply Fade Effects",
54306
+ annotations: { readOnly: false, openWorld: false },
54176
54307
  description: "Apply fade in/out effects to video and/or audio. No API key needed.",
54177
54308
  schema: external_exports.object({
54178
54309
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54196,6 +54327,8 @@ var editNoiseReduceTool = defineTool({
54196
54327
  name: "edit_noise_reduce",
54197
54328
  category: "edit",
54198
54329
  cost: "free",
54330
+ title: "Reduce Audio Noise",
54331
+ annotations: { readOnly: false, openWorld: false },
54199
54332
  description: "Reduce audio/video noise using FFmpeg filters. No API key needed.",
54200
54333
  schema: external_exports.object({
54201
54334
  inputPath: external_exports.string().describe("Path to the input media file"),
@@ -54217,6 +54350,8 @@ var editJumpCutTool = defineTool({
54217
54350
  name: "edit_jump_cut",
54218
54351
  category: "edit",
54219
54352
  cost: "low",
54353
+ title: "Remove Filler Words",
54354
+ annotations: { readOnly: false, openWorld: true },
54220
54355
  description: "Remove filler words (um, uh, like, etc.) from video using Whisper transcription. Requires OPENAI_API_KEY.",
54221
54356
  schema: external_exports.object({
54222
54357
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54240,6 +54375,8 @@ var editTextOverlayTool = defineTool({
54240
54375
  name: "edit_text_overlay",
54241
54376
  category: "edit",
54242
54377
  cost: "free",
54378
+ title: "Overlay Static Text",
54379
+ annotations: { readOnly: false, openWorld: false },
54243
54380
  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.",
54244
54381
  schema: external_exports.object({
54245
54382
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54266,6 +54403,8 @@ var editMotionOverlayTool = defineTool({
54266
54403
  name: "edit_motion_overlay",
54267
54404
  category: "edit",
54268
54405
  cost: "low",
54406
+ title: "Apply Motion Graphics Overlay",
54407
+ annotations: { readOnly: false, openWorld: true },
54269
54408
  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.",
54270
54409
  schema: external_exports.object({
54271
54410
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54302,6 +54441,8 @@ var editTranslateSrtTool = defineTool({
54302
54441
  name: "edit_translate_srt",
54303
54442
  category: "edit",
54304
54443
  cost: "low",
54444
+ title: "Translate SRT Subtitles",
54445
+ annotations: { readOnly: false, openWorld: true },
54305
54446
  description: "Translate SRT subtitle files using Claude or OpenAI. Requires ANTHROPIC_API_KEY or OPENAI_API_KEY.",
54306
54447
  schema: external_exports.object({
54307
54448
  srtPath: external_exports.string().describe("Path to the input SRT file"),
@@ -54324,6 +54465,8 @@ var editGradeTool = defineTool({
54324
54465
  name: "edit_grade",
54325
54466
  category: "edit",
54326
54467
  cost: "low",
54468
+ title: "Apply Color Grading",
54469
+ annotations: { readOnly: false, openWorld: true },
54327
54470
  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).",
54328
54471
  schema: external_exports.object({
54329
54472
  videoPath: external_exports.string().describe("Input video file path"),
@@ -54346,6 +54489,8 @@ var editSpeedRampTool = defineTool({
54346
54489
  name: "edit_speed_ramp",
54347
54490
  category: "edit",
54348
54491
  cost: "low",
54492
+ title: "Apply Content-Aware Speed Ramping",
54493
+ annotations: { readOnly: false, openWorld: true },
54349
54494
  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.",
54350
54495
  schema: external_exports.object({
54351
54496
  videoPath: external_exports.string().describe("Input video file path (must have audio)"),
@@ -54370,6 +54515,8 @@ var editReframeTool = defineTool({
54370
54515
  name: "edit_reframe",
54371
54516
  category: "edit",
54372
54517
  cost: "free",
54518
+ title: "Reframe Video Aspect Ratio",
54519
+ annotations: { readOnly: false, openWorld: false },
54373
54520
  description: "Auto-reframe video to a different aspect ratio using smart cropping. Free (FFmpeg only).",
54374
54521
  schema: external_exports.object({
54375
54522
  videoPath: external_exports.string().describe("Input video file path"),
@@ -54392,6 +54539,8 @@ var editInterpolateTool = defineTool({
54392
54539
  name: "edit_interpolate",
54393
54540
  category: "edit",
54394
54541
  cost: "free",
54542
+ title: "Create Slow Motion with Frame Interpolation",
54543
+ annotations: { readOnly: false, openWorld: false },
54395
54544
  description: "Create slow motion with AI frame interpolation using FFmpeg minterpolate. Free, no API key needed.",
54396
54545
  schema: external_exports.object({
54397
54546
  videoPath: external_exports.string().describe("Input video file path"),
@@ -54414,6 +54563,8 @@ var editUpscaleTool = defineTool({
54414
54563
  name: "edit_upscale",
54415
54564
  category: "edit",
54416
54565
  cost: "free",
54566
+ title: "Upscale Video Resolution",
54567
+ annotations: { readOnly: false, openWorld: false },
54417
54568
  description: "Upscale video resolution using FFmpeg (Lanczos scaling). Free, no API key needed.",
54418
54569
  schema: external_exports.object({
54419
54570
  videoPath: external_exports.string().describe("Input video file path"),
@@ -54435,6 +54586,8 @@ var editAnimatedCaptionTool = defineTool({
54435
54586
  name: "edit_animated_caption",
54436
54587
  category: "edit",
54437
54588
  cost: "low",
54589
+ title: "Add Animated Captions",
54590
+ annotations: { readOnly: false, openWorld: true },
54438
54591
  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.",
54439
54592
  schema: external_exports.object({
54440
54593
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -54467,6 +54620,8 @@ var editImageTool = defineTool({
54467
54620
  name: "edit_image",
54468
54621
  category: "edit",
54469
54622
  cost: "low",
54623
+ title: "Edit Image with AI",
54624
+ annotations: { readOnly: false, openWorld: true },
54470
54625
  description: "Edit image(s) using Gemini (Nano Banana). Provide image paths and an edit prompt. Requires GOOGLE_API_KEY.",
54471
54626
  schema: external_exports.object({
54472
54627
  imagePaths: external_exports.array(external_exports.string()).describe("Input image file path(s)"),
@@ -54490,6 +54645,8 @@ var editFillGapsTool = defineTool({
54490
54645
  name: "edit_fill_gaps",
54491
54646
  category: "edit",
54492
54647
  cost: "high",
54648
+ title: "Fill Timeline Gaps with AI Video",
54649
+ annotations: { readOnly: false, openWorld: true },
54493
54650
  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).",
54494
54651
  schema: external_exports.object({
54495
54652
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -55972,6 +56129,8 @@ var inspectProjectTool = defineTool({
55972
56129
  name: "inspect_project",
55973
56130
  category: "analyze",
55974
56131
  cost: "free",
56132
+ title: "Inspect Project",
56133
+ annotations: { readOnly: false, openWorld: false },
55975
56134
  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.",
55976
56135
  schema: external_exports.object({
55977
56136
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION2),
@@ -56006,6 +56165,8 @@ var inspectRenderTool = defineTool({
56006
56165
  name: "inspect_render",
56007
56166
  category: "analyze",
56008
56167
  cost: "low",
56168
+ title: "Inspect Render",
56169
+ annotations: { readOnly: false, openWorld: false },
56009
56170
  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.",
56010
56171
  schema: external_exports.object({
56011
56172
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION2),
@@ -56070,6 +56231,8 @@ var analyzeMediaTool = defineTool({
56070
56231
  name: "inspect_media",
56071
56232
  category: "analyze",
56072
56233
  cost: "low",
56234
+ title: "Inspect Media with AI",
56235
+ annotations: { readOnly: true, openWorld: true },
56073
56236
  description: "Analyze media (image, video, or YouTube URL) using Gemini AI. Requires GOOGLE_API_KEY.",
56074
56237
  schema: external_exports.object({
56075
56238
  source: external_exports.string().describe("Path to image/video or YouTube URL"),
@@ -56098,6 +56261,8 @@ var analyzeVideoTool = defineTool({
56098
56261
  name: "inspect_video",
56099
56262
  category: "analyze",
56100
56263
  cost: "low",
56264
+ title: "Inspect Video with AI",
56265
+ annotations: { readOnly: true, openWorld: true },
56101
56266
  description: "Analyze video content using Gemini AI with temporal understanding. Requires GOOGLE_API_KEY.",
56102
56267
  schema: external_exports.object({
56103
56268
  source: external_exports.string().describe("Path to video file"),
@@ -56126,6 +56291,8 @@ var analyzeReviewTool = defineTool({
56126
56291
  name: "inspect_review",
56127
56292
  category: "analyze",
56128
56293
  cost: "low",
56294
+ title: "Review Video with AI",
56295
+ annotations: { readOnly: false, openWorld: true },
56129
56296
  description: "AI video review: analyzes quality, suggests fixes, and optionally auto-applies them. Requires GOOGLE_API_KEY.",
56130
56297
  schema: external_exports.object({
56131
56298
  videoPath: external_exports.string().describe("Path to the video file to review"),
@@ -56154,6 +56321,8 @@ var analyzeSuggestTool = defineTool({
56154
56321
  name: "inspect_suggest",
56155
56322
  category: "analyze",
56156
56323
  cost: "low",
56324
+ title: "Suggest Edits with AI",
56325
+ annotations: { readOnly: false, openWorld: true },
56157
56326
  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.",
56158
56327
  schema: external_exports.object({
56159
56328
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -56201,6 +56370,8 @@ var generateMotionTool = defineTool({
56201
56370
  name: "generate_motion",
56202
56371
  category: "generate",
56203
56372
  cost: "low",
56373
+ title: "Generate Motion Graphics",
56374
+ annotations: { readOnly: false, openWorld: true },
56204
56375
  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).",
56205
56376
  schema: external_exports.object({
56206
56377
  description: external_exports.string().describe("Description of the motion graphic to generate"),
@@ -56240,6 +56411,8 @@ var generateSpeechTool = defineTool({
56240
56411
  name: "generate_speech",
56241
56412
  category: "generate",
56242
56413
  cost: "low",
56414
+ title: "Generate Speech Audio",
56415
+ annotations: { readOnly: false, openWorld: true },
56243
56416
  description: "Generate speech from text using ElevenLabs TTS. Requires ELEVENLABS_API_KEY.",
56244
56417
  schema: external_exports.object({
56245
56418
  text: external_exports.string().describe("Text to convert to speech"),
@@ -56260,6 +56433,8 @@ var generateNarrationTool = defineTool({
56260
56433
  name: "generate_narration",
56261
56434
  category: "generate",
56262
56435
  cost: "low",
56436
+ title: "Generate Narration Audio",
56437
+ annotations: { readOnly: false, openWorld: true },
56263
56438
  description: "Generate narration from text using ElevenLabs TTS. Product-facing alias for generate_speech. Requires ELEVENLABS_API_KEY.",
56264
56439
  schema: external_exports.object({
56265
56440
  text: external_exports.string().describe("Narration text to convert to speech"),
@@ -56284,6 +56459,8 @@ var generateSoundEffectTool = defineTool({
56284
56459
  name: "generate_sound_effect",
56285
56460
  category: "generate",
56286
56461
  cost: "low",
56462
+ title: "Generate Sound Effect",
56463
+ annotations: { readOnly: false, openWorld: true },
56287
56464
  description: "Generate sound effects using ElevenLabs. Requires ELEVENLABS_API_KEY.",
56288
56465
  schema: external_exports.object({
56289
56466
  prompt: external_exports.string().describe("Description of the sound effect"),
@@ -56305,6 +56482,8 @@ var generateMusicTool = defineTool({
56305
56482
  name: "generate_music",
56306
56483
  category: "generate",
56307
56484
  cost: "low",
56485
+ title: "Generate Music",
56486
+ annotations: { readOnly: false, openWorld: true },
56308
56487
  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.",
56309
56488
  schema: external_exports.object({
56310
56489
  prompt: external_exports.string().describe("Description of the music to generate"),
@@ -56350,6 +56529,8 @@ var generateMusicStatusTool = defineTool({
56350
56529
  name: "generate_music_status",
56351
56530
  category: "generate",
56352
56531
  cost: "free",
56532
+ title: "Check Music Generation Status",
56533
+ annotations: { readOnly: true, openWorld: true },
56353
56534
  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.",
56354
56535
  schema: external_exports.object({
56355
56536
  taskId: external_exports.string().describe("Task ID returned from generate_music")
@@ -56373,6 +56554,8 @@ var generateImageTool = defineTool({
56373
56554
  name: "generate_image",
56374
56555
  category: "generate",
56375
56556
  cost: "low",
56557
+ title: "Generate Image",
56558
+ annotations: { readOnly: false, openWorld: true },
56376
56559
  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).",
56377
56560
  schema: external_exports.object({
56378
56561
  prompt: external_exports.string().describe("Image description prompt"),
@@ -56406,6 +56589,8 @@ var generateStoryboardTool = defineTool({
56406
56589
  name: "generate_storyboard",
56407
56590
  category: "generate",
56408
56591
  cost: "low",
56592
+ title: "Generate Storyboard",
56593
+ annotations: { readOnly: false, openWorld: true },
56409
56594
  description: "Generate a video storyboard from text content using Claude. Returns scene segments with descriptions, visuals, and narration. Requires ANTHROPIC_API_KEY.",
56410
56595
  schema: external_exports.object({
56411
56596
  content: external_exports.string().describe("Text content to analyze (script, article, etc.)"),
@@ -56429,6 +56614,8 @@ var generateBackgroundTool = defineTool({
56429
56614
  name: "generate_background",
56430
56615
  category: "generate",
56431
56616
  cost: "low",
56617
+ title: "Generate Background Image",
56618
+ annotations: { readOnly: false, openWorld: true },
56432
56619
  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.",
56433
56620
  schema: external_exports.object({
56434
56621
  description: external_exports.string().describe("Background description / image prompt."),
@@ -56453,6 +56640,8 @@ var generateThumbnailTool = defineTool({
56453
56640
  name: "generate_thumbnail",
56454
56641
  category: "generate",
56455
56642
  cost: "low",
56643
+ title: "Generate Thumbnail",
56644
+ annotations: { readOnly: false, openWorld: true },
56456
56645
  description: "Extract the best thumbnail frame from a video using Gemini AI analysis. Requires GOOGLE_API_KEY.",
56457
56646
  schema: external_exports.object({
56458
56647
  videoPath: external_exports.string().describe("Path to the video file"),
@@ -56474,6 +56663,8 @@ var generateVideoTool = defineTool({
56474
56663
  name: "generate_video",
56475
56664
  category: "generate",
56476
56665
  cost: "high",
56666
+ title: "Generate Video",
56667
+ annotations: { readOnly: false, openWorld: true },
56477
56668
  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.",
56478
56669
  schema: external_exports.object({
56479
56670
  prompt: external_exports.string().describe("Text prompt describing the video"),
@@ -56535,6 +56726,8 @@ var generateVideoStatusTool = defineTool({
56535
56726
  name: "generate_video_status",
56536
56727
  category: "generate",
56537
56728
  cost: "free",
56729
+ title: "Check Video Generation Status",
56730
+ annotations: { readOnly: false, openWorld: true },
56538
56731
  description: "Check video generation status for Grok, Runway, Kling, or Veo tasks.",
56539
56732
  schema: external_exports.object({
56540
56733
  taskId: external_exports.string().describe("Task ID from video generation"),
@@ -56565,6 +56758,8 @@ var generateVideoCancelTool = defineTool({
56565
56758
  name: "generate_video_cancel",
56566
56759
  category: "generate",
56567
56760
  cost: "free",
56761
+ title: "Cancel Video Generation",
56762
+ annotations: { readOnly: false, openWorld: true },
56568
56763
  description: "Cancel a Runway video generation task.",
56569
56764
  schema: external_exports.object({
56570
56765
  taskId: external_exports.string().describe("Task ID to cancel")
@@ -56583,6 +56778,8 @@ var generateVideoExtendTool = defineTool({
56583
56778
  name: "generate_video_extend",
56584
56779
  category: "generate",
56585
56780
  cost: "high",
56781
+ title: "Extend Generated Video",
56782
+ annotations: { readOnly: false, openWorld: true },
56586
56783
  description: "Extend video duration using Kling or Veo. Requires the video/operation ID from a previous generation.",
56587
56784
  schema: external_exports.object({
56588
56785
  videoId: external_exports.string().describe("Video ID (Kling) or operation name (Veo)"),
@@ -56984,6 +57181,8 @@ var storyboardListTool = defineTool({
56984
57181
  name: "storyboard_list",
56985
57182
  category: "storyboard",
56986
57183
  cost: "free",
57184
+ title: "List Storyboard Beats",
57185
+ annotations: { readOnly: true, openWorld: false },
56987
57186
  description: "List beats, ids, durations, and cue blocks from a project's STORYBOARD.md.",
56988
57187
  schema: projectDirSchema,
56989
57188
  async execute(args, ctx) {
@@ -57010,6 +57209,8 @@ var storyboardValidateTool = defineTool({
57010
57209
  name: "storyboard_validate",
57011
57210
  category: "storyboard",
57012
57211
  cost: "free",
57212
+ title: "Validate Storyboard",
57213
+ annotations: { readOnly: true, openWorld: false },
57013
57214
  description: "Validate STORYBOARD.md beat ids and cue blocks.",
57014
57215
  schema: projectDirSchema,
57015
57216
  async execute(args, ctx) {
@@ -57040,6 +57241,8 @@ var storyboardGetTool = defineTool({
57040
57241
  name: "storyboard_get",
57041
57242
  category: "storyboard",
57042
57243
  cost: "free",
57244
+ title: "Get Storyboard Beat",
57245
+ annotations: { readOnly: true, openWorld: false },
57043
57246
  description: "Return one STORYBOARD.md beat as structured data.",
57044
57247
  schema: external_exports.object({
57045
57248
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -57062,6 +57265,8 @@ var storyboardSetTool = defineTool({
57062
57265
  name: "storyboard_set",
57063
57266
  category: "storyboard",
57064
57267
  cost: "free",
57268
+ title: "Set Storyboard Cue",
57269
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
57065
57270
  description: "Set or unset one cue on one beat in STORYBOARD.md.",
57066
57271
  schema: external_exports.object({
57067
57272
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -57098,6 +57303,8 @@ var storyboardMoveTool = defineTool({
57098
57303
  name: "storyboard_move",
57099
57304
  category: "storyboard",
57100
57305
  cost: "free",
57306
+ title: "Reorder Storyboard Beat",
57307
+ annotations: { readOnly: false, openWorld: false },
57101
57308
  description: "Move one beat after another beat in STORYBOARD.md.",
57102
57309
  schema: external_exports.object({
57103
57310
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -57128,6 +57335,8 @@ var storyboardReviseTool = defineTool({
57128
57335
  name: "storyboard_revise",
57129
57336
  category: "storyboard",
57130
57337
  cost: "low",
57338
+ title: "Revise Storyboard with AI",
57339
+ annotations: { readOnly: false, openWorld: true },
57131
57340
  description: "Revise an existing STORYBOARD.md from a natural-language request. Reads project context, validates the revised storyboard, and writes unless dryRun is true.",
57132
57341
  schema: external_exports.object({
57133
57342
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -57159,6 +57368,8 @@ var planTool = defineTool({
57159
57368
  name: "plan",
57160
57369
  category: "storyboard",
57161
57370
  cost: "free",
57371
+ title: "Plan Build Cost and Stages",
57372
+ annotations: { readOnly: true, openWorld: false },
57162
57373
  description: "Read STORYBOARD.md and return the build plan, missing artifacts, provider needs, and estimated cost.",
57163
57374
  schema: external_exports.object({
57164
57375
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION3),
@@ -58856,6 +59067,8 @@ var pipelineHighlightsTool = defineTool({
58856
59067
  name: "remix_highlights",
58857
59068
  category: "pipeline",
58858
59069
  cost: "low",
59070
+ title: "Extract Video Highlights",
59071
+ annotations: { readOnly: false, openWorld: true },
58859
59072
  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).",
58860
59073
  schema: external_exports.object({
58861
59074
  media: external_exports.string().describe("Path to the input video file"),
@@ -58889,6 +59102,8 @@ var pipelineAutoShortsTool = defineTool({
58889
59102
  name: "remix_auto_shorts",
58890
59103
  category: "pipeline",
58891
59104
  cost: "medium",
59105
+ title: "Generate Auto Shorts",
59106
+ annotations: { readOnly: false, openWorld: true },
58892
59107
  description: "Automatically generate short-form content (Reels/TikTok/Shorts) from a longer video. Same API key requirements as remix_highlights.",
58893
59108
  schema: external_exports.object({
58894
59109
  video: external_exports.string().describe("Path to the input video file"),
@@ -58926,6 +59141,8 @@ var pipelineRunTool = defineTool({
58926
59141
  name: "run",
58927
59142
  category: "pipeline",
58928
59143
  cost: "very-high",
59144
+ title: "Run YAML Pipeline",
59145
+ annotations: { readOnly: false, openWorld: true },
58929
59146
  surfaces: ["mcp"],
58930
59147
  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.",
58931
59148
  schema: external_exports.object({
@@ -59005,6 +59222,8 @@ var pipelineRegenerateSceneTool = defineTool({
59005
59222
  name: "remix_regenerate_scene",
59006
59223
  category: "pipeline",
59007
59224
  cost: "high",
59225
+ title: "Regenerate Storyboard Scenes",
59226
+ annotations: { readOnly: false, openWorld: true },
59008
59227
  description: "Regenerate specific scenes against an existing storyboard.{yaml,json} on disk. Can regenerate video, image, or narration independently.",
59009
59228
  schema: external_exports.object({
59010
59229
  projectDir: external_exports.string().describe("Path to the project output directory containing storyboard.json"),
@@ -59041,6 +59260,8 @@ var detectScenesTool = defineTool({
59041
59260
  name: "detect_scenes",
59042
59261
  category: "detect",
59043
59262
  cost: "free",
59263
+ title: "Detect Scene Cuts",
59264
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
59044
59265
  description: "Detect scene changes in video using FFmpeg. No API key needed.",
59045
59266
  schema: external_exports.object({
59046
59267
  videoPath: external_exports.string().describe("Path to the input video file"),
@@ -59065,6 +59286,8 @@ var detectSilenceTool = defineTool({
59065
59286
  name: "detect_silence",
59066
59287
  category: "detect",
59067
59288
  cost: "free",
59289
+ title: "Detect Silence Periods",
59290
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
59068
59291
  description: "Detect silence periods in audio/video using FFmpeg. No API key needed.",
59069
59292
  schema: external_exports.object({
59070
59293
  mediaPath: external_exports.string().describe("Path to the audio/video file"),
@@ -59086,6 +59309,8 @@ var detectBeatsTool = defineTool({
59086
59309
  name: "detect_beats",
59087
59310
  category: "detect",
59088
59311
  cost: "free",
59312
+ title: "Detect Audio Beats",
59313
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
59089
59314
  description: "Detect beats in audio for music sync using FFmpeg loudness analysis. No API key needed.",
59090
59315
  schema: external_exports.object({
59091
59316
  audioPath: external_exports.string().describe("Path to the audio file"),
@@ -59147,6 +59372,8 @@ var timelineCreateTool = defineTool({
59147
59372
  name: "timeline_create",
59148
59373
  category: "timeline",
59149
59374
  cost: "free",
59375
+ title: "Create Timeline",
59376
+ annotations: { readOnly: false, openWorld: false },
59150
59377
  description: "Create a low-level timeline JSON file for FFmpeg-style editing",
59151
59378
  schema: external_exports.object({
59152
59379
  name: external_exports.string().describe("Timeline name or directory path"),
@@ -59177,6 +59404,8 @@ var timelineInfoTool = defineTool({
59177
59404
  name: "timeline_info",
59178
59405
  category: "timeline",
59179
59406
  cost: "free",
59407
+ title: "Get Timeline Info",
59408
+ annotations: { readOnly: true, openWorld: false },
59180
59409
  description: "Get information about a timeline JSON file. Legacy *.vibe.json files are supported.",
59181
59410
  schema: external_exports.object({
59182
59411
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
@@ -59204,6 +59433,8 @@ var timelineAddSourceTool = defineTool({
59204
59433
  name: "timeline_add_source",
59205
59434
  category: "timeline",
59206
59435
  cost: "free",
59436
+ title: "Add Source to Timeline",
59437
+ annotations: { readOnly: false, openWorld: false },
59207
59438
  description: "Add a media source (video, audio, image) to the timeline",
59208
59439
  schema: external_exports.object({
59209
59440
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59229,6 +59460,8 @@ var timelineAddClipTool = defineTool({
59229
59460
  name: "timeline_add_clip",
59230
59461
  category: "timeline",
59231
59462
  cost: "free",
59463
+ title: "Add Clip to Timeline",
59464
+ annotations: { readOnly: false, openWorld: false },
59232
59465
  description: "Add a clip to the timeline from an existing source",
59233
59466
  schema: external_exports.object({
59234
59467
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59260,6 +59493,8 @@ var timelineSplitClipTool = defineTool({
59260
59493
  name: "timeline_split_clip",
59261
59494
  category: "timeline",
59262
59495
  cost: "free",
59496
+ title: "Split Clip",
59497
+ annotations: { readOnly: false, openWorld: false },
59263
59498
  description: "Split a clip at a specific time",
59264
59499
  schema: external_exports.object({
59265
59500
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59278,6 +59513,8 @@ var timelineTrimClipTool = defineTool({
59278
59513
  name: "timeline_trim_clip",
59279
59514
  category: "timeline",
59280
59515
  cost: "free",
59516
+ title: "Trim Clip",
59517
+ annotations: { readOnly: false, openWorld: false },
59281
59518
  description: "Trim a clip by adjusting its start or end",
59282
59519
  schema: external_exports.object({
59283
59520
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59297,6 +59534,8 @@ var timelineMoveClipTool = defineTool({
59297
59534
  name: "timeline_move_clip",
59298
59535
  category: "timeline",
59299
59536
  cost: "free",
59537
+ title: "Move Clip",
59538
+ annotations: { readOnly: false, openWorld: false },
59300
59539
  description: "Move a clip to a new position or track",
59301
59540
  schema: external_exports.object({
59302
59541
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59319,6 +59558,8 @@ var timelineDeleteClipTool = defineTool({
59319
59558
  name: "timeline_delete_clip",
59320
59559
  category: "timeline",
59321
59560
  cost: "free",
59561
+ title: "Delete Clip",
59562
+ annotations: { readOnly: false, openWorld: false },
59322
59563
  description: "Delete a clip from the timeline",
59323
59564
  schema: external_exports.object({
59324
59565
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59335,6 +59576,8 @@ var timelineDuplicateClipTool = defineTool({
59335
59576
  name: "timeline_duplicate_clip",
59336
59577
  category: "timeline",
59337
59578
  cost: "free",
59579
+ title: "Duplicate Clip",
59580
+ annotations: { readOnly: false, openWorld: false },
59338
59581
  description: "Duplicate a clip on the timeline (optionally at a new start time)",
59339
59582
  schema: external_exports.object({
59340
59583
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59353,6 +59596,8 @@ var timelineAddEffectTool = defineTool({
59353
59596
  name: "timeline_add_effect",
59354
59597
  category: "timeline",
59355
59598
  cost: "free",
59599
+ title: "Add Effect to Clip",
59600
+ annotations: { readOnly: false, openWorld: false },
59356
59601
  description: "Add an effect to a clip",
59357
59602
  schema: external_exports.object({
59358
59603
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59379,6 +59624,8 @@ var timelineAddTrackTool = defineTool({
59379
59624
  name: "timeline_add_track",
59380
59625
  category: "timeline",
59381
59626
  cost: "free",
59627
+ title: "Add Track to Timeline",
59628
+ annotations: { readOnly: false, openWorld: false },
59382
59629
  description: "Add a new track to the timeline",
59383
59630
  schema: external_exports.object({
59384
59631
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -59405,6 +59652,8 @@ var timelineListTool = defineTool({
59405
59652
  name: "timeline_list",
59406
59653
  category: "timeline",
59407
59654
  cost: "free",
59655
+ title: "List Timeline Contents",
59656
+ annotations: { readOnly: true, openWorld: false },
59408
59657
  description: "List all sources, tracks, and clips in a project",
59409
59658
  schema: external_exports.object({
59410
59659
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
@@ -59446,6 +59695,8 @@ var projectCreateTool = defineTool({
59446
59695
  name: "project_create",
59447
59696
  category: "project",
59448
59697
  cost: "free",
59698
+ title: "Create Project",
59699
+ annotations: { readOnly: false, openWorld: false },
59449
59700
  description: "Deprecated alias for creating low-level timeline state. Prefer timeline_create.",
59450
59701
  schema: external_exports.object({
59451
59702
  name: external_exports.string().describe("Project name"),
@@ -59470,6 +59721,8 @@ var projectInfoTool = defineTool({
59470
59721
  name: "project_info",
59471
59722
  category: "project",
59472
59723
  cost: "free",
59724
+ title: "Get Project Info",
59725
+ annotations: { readOnly: true, openWorld: false },
59473
59726
  description: "Deprecated alias for timeline_info. Legacy *.vibe.json files remain supported.",
59474
59727
  schema: external_exports.object({
59475
59728
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file")
@@ -60356,6 +60609,8 @@ var exportVideoTool = defineTool({
60356
60609
  name: "export_video",
60357
60610
  category: "export",
60358
60611
  cost: "free",
60612
+ title: "Export Timeline to Video",
60613
+ annotations: { readOnly: false, openWorld: false },
60359
60614
  description: "Export a VibeFrame timeline to a video file (MP4, WebM, or MOV). Requires FFmpeg.",
60360
60615
  schema: external_exports.object({
60361
60616
  projectPath: external_exports.string().describe("Path to timeline.json, a timeline directory, or a legacy *.vibe.json file"),
@@ -60446,6 +60701,8 @@ var fsListTool = defineTool({
60446
60701
  name: "fs_list",
60447
60702
  category: "agent-only",
60448
60703
  cost: "free",
60704
+ title: "List Files",
60705
+ annotations: { readOnly: true, openWorld: false },
60449
60706
  surfaces: ["agent"],
60450
60707
  description: "List files and directories in a path",
60451
60708
  schema: external_exports.object({
@@ -60479,6 +60736,8 @@ var fsReadTool = defineTool({
60479
60736
  name: "fs_read",
60480
60737
  category: "agent-only",
60481
60738
  cost: "free",
60739
+ title: "Read File",
60740
+ annotations: { readOnly: true, openWorld: false },
60482
60741
  surfaces: ["agent"],
60483
60742
  description: "Read contents of a text file",
60484
60743
  schema: external_exports.object({
@@ -60501,6 +60760,8 @@ var fsWriteTool = defineTool({
60501
60760
  name: "fs_write",
60502
60761
  category: "agent-only",
60503
60762
  cost: "free",
60763
+ title: "Write File",
60764
+ annotations: { readOnly: false, openWorld: false },
60504
60765
  surfaces: ["agent"],
60505
60766
  description: "Write content to a file",
60506
60767
  schema: external_exports.object({
@@ -60521,6 +60782,8 @@ var fsExistsTool = defineTool({
60521
60782
  name: "fs_exists",
60522
60783
  category: "agent-only",
60523
60784
  cost: "free",
60785
+ title: "Check Path Exists",
60786
+ annotations: { readOnly: true, openWorld: false },
60524
60787
  surfaces: ["agent"],
60525
60788
  description: "Check if a file or directory exists",
60526
60789
  schema: external_exports.object({
@@ -60542,6 +60805,8 @@ var batchImportTool = defineTool({
60542
60805
  name: "batch_import",
60543
60806
  category: "agent-only",
60544
60807
  cost: "free",
60808
+ title: "Batch Import Media",
60809
+ annotations: { readOnly: false, openWorld: false },
60545
60810
  surfaces: ["agent"],
60546
60811
  description: "Import multiple media files from a directory into a project. Scans directory for video, audio, and image files.",
60547
60812
  schema: external_exports.object({
@@ -60611,6 +60876,8 @@ var batchConcatTool = defineTool({
60611
60876
  name: "batch_concat",
60612
60877
  category: "agent-only",
60613
60878
  cost: "free",
60879
+ title: "Batch Concatenate Sources",
60880
+ annotations: { readOnly: false, openWorld: false },
60614
60881
  surfaces: ["agent"],
60615
60882
  description: "Concatenate multiple sources into sequential clips on the timeline",
60616
60883
  schema: external_exports.object({
@@ -60680,6 +60947,8 @@ var batchApplyEffectTool = defineTool({
60680
60947
  name: "batch_apply_effect",
60681
60948
  category: "agent-only",
60682
60949
  cost: "free",
60950
+ title: "Batch Apply Effect",
60951
+ annotations: { readOnly: false, openWorld: false },
60683
60952
  surfaces: ["agent"],
60684
60953
  description: "Apply an effect to multiple clips at once",
60685
60954
  schema: external_exports.object({
@@ -60736,6 +61005,8 @@ var timelineClearTool = defineTool({
60736
61005
  name: "timeline_clear",
60737
61006
  category: "agent-only",
60738
61007
  cost: "free",
61008
+ title: "Clear Timeline",
61009
+ annotations: { readOnly: false, openWorld: false },
60739
61010
  surfaces: ["agent"],
60740
61011
  description: "Clear timeline contents (remove clips, tracks, or sources)",
60741
61012
  schema: external_exports.object({
@@ -60810,6 +61081,8 @@ var projectSetTool = defineTool({
60810
61081
  name: "project_set",
60811
61082
  category: "agent-only",
60812
61083
  cost: "free",
61084
+ title: "Update Project Settings",
61085
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
60813
61086
  surfaces: ["agent"],
60814
61087
  description: "Update timeline settings (name, aspect ratio, frame rate)",
60815
61088
  schema: external_exports.object({
@@ -60855,6 +61128,8 @@ var projectOpenTool = defineTool({
60855
61128
  name: "project_open",
60856
61129
  category: "agent-only",
60857
61130
  cost: "free",
61131
+ title: "Open Project",
61132
+ annotations: { readOnly: false, idempotent: true, openWorld: false },
60858
61133
  surfaces: ["agent"],
60859
61134
  description: "Open an existing project and set it as the current context",
60860
61135
  schema: external_exports.object({
@@ -60893,6 +61168,8 @@ var projectSaveTool = defineTool({
60893
61168
  name: "project_save",
60894
61169
  category: "agent-only",
60895
61170
  cost: "free",
61171
+ title: "Save Project",
61172
+ annotations: { readOnly: false, openWorld: false },
60896
61173
  surfaces: ["agent"],
60897
61174
  description: "Save the current project (uses ctx.agent.projectPath if no path given)",
60898
61175
  schema: external_exports.object({
@@ -60927,6 +61204,8 @@ var exportAudioTool = defineTool({
60927
61204
  name: "export_audio",
60928
61205
  category: "agent-only",
60929
61206
  cost: "free",
61207
+ title: "Export Audio",
61208
+ annotations: { readOnly: false, openWorld: false },
60930
61209
  surfaces: ["agent"],
60931
61210
  description: "Export audio track from a project. Not implemented \u2014 use export_video then strip audio with FFmpeg.",
60932
61211
  schema: external_exports.object({
@@ -60945,6 +61224,8 @@ var exportSubtitlesTool = defineTool({
60945
61224
  name: "export_subtitles",
60946
61225
  category: "agent-only",
60947
61226
  cost: "free",
61227
+ title: "Export Subtitles",
61228
+ annotations: { readOnly: false, openWorld: false },
60948
61229
  surfaces: ["agent"],
60949
61230
  description: "Export subtitles from transcription. Not implemented \u2014 use audio_transcribe to generate subtitles from audio.",
60950
61231
  schema: external_exports.object({
@@ -60963,6 +61244,8 @@ var mediaInfoTool = defineTool({
60963
61244
  name: "media_info",
60964
61245
  category: "agent-only",
60965
61246
  cost: "free",
61247
+ title: "Get Media Info",
61248
+ annotations: { readOnly: true, openWorld: false },
60966
61249
  surfaces: ["agent"],
60967
61250
  description: "Get information about a media file (duration, resolution, codec, etc.)",
60968
61251
  schema: external_exports.object({
@@ -61047,6 +61330,8 @@ var mediaCompressTool = defineTool({
61047
61330
  name: "media_compress",
61048
61331
  category: "agent-only",
61049
61332
  cost: "free",
61333
+ title: "Compress Media",
61334
+ annotations: { readOnly: false, openWorld: false },
61050
61335
  surfaces: ["agent"],
61051
61336
  description: "Compress a video or audio file using FFmpeg",
61052
61337
  schema: external_exports.object({
@@ -61108,6 +61393,8 @@ var mediaConvertTool = defineTool({
61108
61393
  name: "media_convert",
61109
61394
  category: "agent-only",
61110
61395
  cost: "free",
61396
+ title: "Convert Media",
61397
+ annotations: { readOnly: false, openWorld: false },
61111
61398
  surfaces: ["agent"],
61112
61399
  description: "Convert media file to a different format using FFmpeg",
61113
61400
  schema: external_exports.object({
@@ -61155,6 +61442,8 @@ var mediaConcatTool = defineTool({
61155
61442
  name: "media_concat",
61156
61443
  category: "agent-only",
61157
61444
  cost: "free",
61445
+ title: "Concatenate Media Files",
61446
+ annotations: { readOnly: false, openWorld: false },
61158
61447
  surfaces: ["agent"],
61159
61448
  description: "Concatenate multiple media files into one using FFmpeg",
61160
61449
  schema: external_exports.object({
@@ -61691,6 +61980,8 @@ var guideTool = defineTool({
61691
61980
  name: "guide",
61692
61981
  category: "agent",
61693
61982
  cost: "free",
61983
+ title: "Load Workflow Guide",
61984
+ annotations: { readOnly: true, openWorld: false },
61694
61985
  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.",
61695
61986
  schema: guideSchema,
61696
61987
  async execute(args) {
@@ -61726,6 +62017,8 @@ var statusJobTool = defineTool({
61726
62017
  name: "status_job",
61727
62018
  category: "status",
61728
62019
  cost: "free",
62020
+ title: "Check Job Status",
62021
+ annotations: { readOnly: false, destructive: false, openWorld: true },
61729
62022
  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).",
61730
62023
  schema: external_exports.object({
61731
62024
  jobId: external_exports.string().describe("Local job id returned by a no-wait command."),
@@ -61761,6 +62054,8 @@ var statusProjectTool = defineTool({
61761
62054
  name: "status_project",
61762
62055
  category: "status",
61763
62056
  cost: "free",
62057
+ title: "Check Project Status",
62058
+ annotations: { readOnly: false, destructive: false, openWorld: true },
61764
62059
  description: "Summarize build-report.json, review-report.json, and local async job records for a VibeFrame project.",
61765
62060
  schema: external_exports.object({
61766
62061
  projectDir: external_exports.string().optional().describe(PROJECT_DIR_DESCRIPTION4),