goatedit-mcp 1.1.5 → 1.1.7

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.
@@ -19179,6 +19179,8 @@ var TEXT_STYLE_PROPS = {
19179
19179
  textShadowColor: str("Drop shadow colour."),
19180
19180
  lineHeight: num("Line advance as a multiple of the line height. Defaults to 1.2."),
19181
19181
  letterSpacing: num("Extra tracking in pixels @1080p."),
19182
+ captionStyle: str("A caption look from the editor's library, applied first so the other style fields here adjust it: purpleLuxuryScript, cyanBlueprint, greenCapital, goldScriptGala, violetChrome, iceCrystal, podcastFame, whiteFlowGrid, blackPlate, extrudedPop, yellowHit, slantedRedDesculpa, redHeroEditorial, orangeHooksHero, creamHero, blackHero, splitSerif, magazineStack, goldSerifAccent, ivoryElegance, roseGoldSerif, sageSerif, midnightSerif, champagneSerif. It brings its own fonts, layout and text animation."),
19183
+ wordSpacing: num("Space between words as a fraction of the font size. Default 0.26; editorial captions with wide gaps use about 1.6."),
19182
19184
  textUnderline: bool("Underline the text."),
19183
19185
  textShadowBlur: num("Drop shadow softness in pixels @1080p. 0 is a hard shadow."),
19184
19186
  textShadowOffsetX: num("Drop shadow offset to the right, pixels @1080p."),
@@ -19194,7 +19196,13 @@ var TEXT_STYLE_PROPS = {
19194
19196
  textSticker: { type: "string", enum: ["ghost", "arrow", "pen", "star", "flame"], description: "Small sticker drawn beside the accent word." },
19195
19197
  textLayoutMode: { type: "string", enum: ["side-grid", "luxury-stack", "editorial-hero", "slanted-red", "double-hero"], description: "Editorial layout engine for multi-word titles." },
19196
19198
  posX: num("Horizontal position as a fraction of the frame, 0..1. 0.5 is centre."),
19197
- posY: num("Vertical position as a fraction of the frame, 0..1. 0.5 is centre.")
19199
+ posY: num("Vertical position as a fraction of the frame, 0..1. 0.5 is centre."),
19200
+ path: {
19201
+ type: ["object", "null"],
19202
+ description: "Set the text along a curve instead of in a block: { points: [[x, y], ...] (fractions of the frame, at least two; anchors without handles are smoothed into a curve through them, and points may lie outside 0..1 so a ribbon runs off the frame), ribbonColor? (paints a band along the path behind the letters), ribbonWidth? (px @1080p, default 380), waveLength? (px between wave crests, default 900), waveSpeed? (crests per second, default 0.5) }. The clip's position moves the whole path. null returns the text to a block. Text animations do not apply along a path; animate pathOffset and pathWave with set_keyframes (as textPathOffset / textPathWave) instead."
19203
+ },
19204
+ pathOffset: num("Where the middle of the text sits along its path, 0 at the start, 1 at the end (default 0.5). Below 0 or above 1 runs the words off the ends, so keyframing it from -0.3 to 0.5 slides a word in along its ribbon."),
19205
+ pathWave: num("Height of the wave travelling down the path, px @1080p (default 0, flat). It bends the ribbon and the letters together.")
19198
19206
  };
19199
19207
  var BASE_TOOLS = [
19200
19208
  {
@@ -19546,6 +19554,7 @@ var BASE_TOOLS = [
19546
19554
  type: "object",
19547
19555
  properties: {
19548
19556
  text: str("The text to display."),
19557
+ name: str("The layer's name in the timeline. Defaults to the text itself."),
19549
19558
  duration: num("How long the card stays on screen, in seconds."),
19550
19559
  startTime: num("Where it starts on the timeline, in seconds. Defaults to 0."),
19551
19560
  trackId: str("Target video track. Defaults to the topmost one that is free across the card\u2019s span, creating a new track above everything if none is free."),
@@ -19641,16 +19650,18 @@ var BASE_TOOLS = [
19641
19650
  inputSchema: {
19642
19651
  type: "object",
19643
19652
  properties: {
19644
- shape: { type: "string", enum: ["sphere", "torus", "capsule", "box", "cylinder", "cone", "blob"], description: "sphere (ball), torus (ring), capsule (pill), box (block), cylinder (can), cone, blob." },
19645
- color: str('Colour when there is no gradient, "#rrggbb". Defaults to near-white.'),
19653
+ shape: { type: "string", enum: ["sphere", "torus", "capsule", "box", "cylinder", "cone", "blob", "pile"], description: `sphere (ball), torus (ring), capsule (pill), box (block), cylinder (can), cone, blob, or pile: many balls that burst from the middle and settle in a heap over 3 seconds (its "Burst" animation, which then holds still; delay it with the model3d effect's animOffset, slow it with animSpeed).` },
19654
+ color: str('A solid colour, "#rrggbb". Given on its own it turns any gradient off. Defaults to near-white.'),
19646
19655
  gradient: { type: "string", enum: ["none", "around", "vertical", "diagonal"], description: 'Paint `colors` across the shape: "around" runs round its axis (the rainbow ring), "vertical" top to bottom, "diagonal" corner to corner. The gradient is in the mesh, so it turns with the shape and shows through glass.' },
19647
- colors: { type: "array", items: { type: "string" }, description: '2\u20136 "#rrggbb" colours, spread evenly, for the gradient. Repeat the first at the end for a seamless "around".' },
19656
+ colors: { type: "array", items: { type: "string" }, description: '2\u20136 "#rrggbb" colours, spread evenly, for the gradient. "around" closes back on the first colour by itself. For a pile, 1\u20136 colours the balls take turns from.' },
19648
19657
  roughness: num("0 mirror-smooth \u2026 1 chalky. Defaults to 0.22 (glossy plastic)."),
19649
19658
  metalness: num("0 plastic \u2026 1 metal. Defaults to 0."),
19650
19659
  proportion: num("Ring: tube thickness as a share of its radius, 0.05\u20130.9. Pill, can, cone: length against width, 0\u20134. Blob: lumpiness, 0\u20131."),
19651
19660
  size: { type: "array", items: { type: "number" }, description: "Block only: [width, height, depth], relative, 0.1\u20134 each." },
19652
19661
  round: num("Block only: edge rounding, 0 sharp \u2026 1 fully round."),
19653
- seed: num("Blob only: which blob; the same seed is the same shape."),
19662
+ seed: num("Blob: which blob. Pile: how the balls fall. The same seed gives the same result."),
19663
+ count: num("Pile only: how many balls, 3\u2013150. Defaults to 40."),
19664
+ arrange: { type: "string", enum: ["heap", "burst"], description: 'Pile only: "heap" (default) \u2014 the balls fall and settle in a heap; "burst" \u2014 they fly out every way and hang in the air in a wide cloud, for an explosion of balls around something.' },
19654
19665
  material: str("A look by name: Original (default, the colour above), Chrome, Gold, Glass, Clay, Toon, Plastic, Matte, Iridescent, Wireframe, X-Ray Glow, Hologram, Crystal, Holographic, Candy Paint, Pearl."),
19655
19666
  rotateX: num("Starting tilt, degrees."),
19656
19667
  rotateY: num("Starting turn, degrees."),
@@ -19672,16 +19683,18 @@ var BASE_TOOLS = [
19672
19683
  type: "object",
19673
19684
  properties: {
19674
19685
  clipId: CLIP_ID,
19675
- shape: { type: "string", enum: ["sphere", "torus", "capsule", "box", "cylinder", "cone", "blob"], description: "sphere (ball), torus (ring), capsule (pill), box (block), cylinder (can), cone, blob." },
19676
- color: str('Colour when there is no gradient, "#rrggbb". Defaults to near-white.'),
19686
+ shape: { type: "string", enum: ["sphere", "torus", "capsule", "box", "cylinder", "cone", "blob", "pile"], description: `sphere (ball), torus (ring), capsule (pill), box (block), cylinder (can), cone, blob, or pile: many balls that burst from the middle and settle in a heap over 3 seconds (its "Burst" animation, which then holds still; delay it with the model3d effect's animOffset, slow it with animSpeed).` },
19687
+ color: str('A solid colour, "#rrggbb". Given on its own it turns any gradient off. Defaults to near-white.'),
19677
19688
  gradient: { type: "string", enum: ["none", "around", "vertical", "diagonal"], description: 'Paint `colors` across the shape: "around" runs round its axis (the rainbow ring), "vertical" top to bottom, "diagonal" corner to corner. The gradient is in the mesh, so it turns with the shape and shows through glass.' },
19678
- colors: { type: "array", items: { type: "string" }, description: '2\u20136 "#rrggbb" colours, spread evenly, for the gradient. Repeat the first at the end for a seamless "around".' },
19689
+ colors: { type: "array", items: { type: "string" }, description: '2\u20136 "#rrggbb" colours, spread evenly, for the gradient. "around" closes back on the first colour by itself. For a pile, 1\u20136 colours the balls take turns from.' },
19679
19690
  roughness: num("0 mirror-smooth \u2026 1 chalky. Defaults to 0.22 (glossy plastic)."),
19680
19691
  metalness: num("0 plastic \u2026 1 metal. Defaults to 0."),
19681
19692
  proportion: num("Ring: tube thickness as a share of its radius, 0.05\u20130.9. Pill, can, cone: length against width, 0\u20134. Blob: lumpiness, 0\u20131."),
19682
19693
  size: { type: "array", items: { type: "number" }, description: "Block only: [width, height, depth], relative, 0.1\u20134 each." },
19683
19694
  round: num("Block only: edge rounding, 0 sharp \u2026 1 fully round."),
19684
- seed: num("Blob only: which blob; the same seed is the same shape.")
19695
+ seed: num("Blob: which blob. Pile: how the balls fall. The same seed gives the same result."),
19696
+ count: num("Pile only: how many balls, 3\u2013150. Defaults to 40."),
19697
+ arrange: { type: "string", enum: ["heap", "burst"], description: 'Pile only: "heap" (default) \u2014 the balls fall and settle in a heap; "burst" \u2014 they fly out every way and hang in the air in a wide cloud, for an explosion of balls around something.' }
19685
19698
  },
19686
19699
  required: ["clipId"]
19687
19700
  },
@@ -19775,24 +19788,101 @@ var BASE_TOOLS = [
19775
19788
  },
19776
19789
  {
19777
19790
  name: "join_scenes",
19778
- description: "Join two scenes at a cut so the edit flows instead of cutting: push (one camera move across a shared canvas \u2014 the outgoing scene speeds out and the incoming arrives at the same speed, so the cut falls mid-motion), zoomThrough (push into one element of the outgoing scene until it fills the frame; the incoming scene opens out of it), or matchCut (a layer of the incoming scene starts exactly where a layer of the outgoing one was \u2014 position, size, turn, through parents, 3D models included \u2014 then settles into its own place). push and zoomThrough add a camera null per side and parent that side's top-level clips to it, so every layer stays editable and the camera's keyframes can be tuned afterwards. at is the cut: outgoing clips end there and incoming clips start there.",
19791
+ description: "Join two scenes at a cut so the edit flows instead of cutting: push (one camera move across a shared canvas \u2014 the outgoing scene speeds out and the incoming arrives at the same speed, so the cut falls mid-motion), zoomThrough (push into one element of the outgoing scene until it fills the frame; the incoming scene opens out of it), or morph (every pair of layers at once, Smart Animate style: each incoming layer starts on the drawn pixels of its outgoing partner \u2014 a tag inside a full-frame snippet counts as the tag \u2014 and stretches and slides into place, pairs staggered left to right), or matchCut (a layer of the incoming scene starts exactly where a layer of the outgoing one was \u2014 position, size, turn, through parents, 3D models included \u2014 then settles into its own place). push and zoomThrough add a camera null per side and parent that side's top-level clips to it, so every layer stays editable and the camera's keyframes can be tuned afterwards. at is the cut: outgoing clips end there and incoming clips start there.",
19779
19792
  inputSchema: {
19780
19793
  type: "object",
19781
19794
  properties: {
19782
19795
  at: num("The cut time in seconds."),
19783
- type: { type: "string", enum: ["push", "zoomThrough", "matchCut"], description: "Which join." },
19796
+ type: { type: "string", enum: ["auto", "push", "zoomThrough", "matchCut", "morph"], description: "Which join. auto picks one from what is on each side: morph when incoming layers are named after outgoing ones and not animated yet, a push in the outgoing scene's own direction when it is already moving into the cut, a zoom through one small element near the middle, else a push \u2014 and says why in `picked`." },
19784
19797
  duration: num("Seconds the move takes on each side of the cut. Default 0.4."),
19785
19798
  direction: { type: "string", enum: ["left", "right", "up", "down"], description: "push: which way the picture travels. Default left." },
19786
19799
  clipId: str("zoomThrough: the element of the outgoing scene to fly into."),
19787
19800
  zoom: num("zoomThrough: how far in the outgoing camera goes. Default: until the element overfills the frame."),
19788
19801
  inZoom: num("zoomThrough: scale the incoming scene opens from. Default 1.8."),
19789
19802
  fromClipId: str("matchCut: the outgoing layer to match."),
19790
- toClipId: str("matchCut: the incoming layer that takes its place.")
19803
+ toClipId: str("matchCut: the incoming layer that takes its place."),
19804
+ pairs: {
19805
+ type: "array",
19806
+ items: { type: "object" },
19807
+ description: 'morph: [{ from, to }] clip ids \u2014 each incoming layer starts on its outgoing partner. Omit to pair automatically: layers whose names end in the same word ("S2 tag New" \u2192 "S2 block New"), then the rest left to right. Full-frame grounds are left out.'
19808
+ },
19809
+ stagger: num("morph: seconds between one pair starting and the next, left to right. Default 0.04.")
19791
19810
  },
19792
19811
  required: ["at", "type"]
19793
19812
  },
19794
19813
  method: "joinScenes"
19795
19814
  },
19815
+ {
19816
+ name: "animate_clip",
19817
+ description: "Give one layer a named move from the motion recipe library, already eased, timed and overshot by the motion principles, relative to where the layer rests (it lands on its own position and scale). Entrances: fadeIn, fadeUp, popIn, slideIn, maskReveal (wiped on behind a soft edge), riseFromLine (rises from behind its own baseline \u2014 the title reveal), blurIn (2D only), zoomIn, dropIn (falls, squashes, springs back), growIn (lines and bars), spinIn. Exits (end on the clip's last frame, or `delay` before it): fadeOut, slideOut (pulls back first, then away), popOut, maskHide, blurOut. Between them: hold (a slow drift after landing, so nothing freezes). Through the whole clip: drift (slow push-in for grounds), float (gentle bob). Overshoots are real damped springs. Don't use on text clips: text animates with set_text_animation. An entrance replaces the keys in its own window only, so an entrance and an exit stack. Prefer animate_scene for a whole scene.",
19818
+ inputSchema: {
19819
+ type: "object",
19820
+ properties: {
19821
+ clipId: str("The layer to animate."),
19822
+ recipe: {
19823
+ type: "string",
19824
+ enum: ["fadeIn", "fadeUp", "popIn", "slideIn", "maskReveal", "riseFromLine", "blurIn", "zoomIn", "dropIn", "growIn", "spinIn", "fadeOut", "slideOut", "popOut", "maskHide", "blurOut", "hold", "drift", "float"],
19825
+ description: "The move."
19826
+ },
19827
+ style: { type: "string", enum: ["smooth", "snappy", "bouncy"], description: "The feel: smooth (no overshoot, 0.6s), snappy (hard ease-out, small overshoot, 0.4s), bouncy (10% overshoot, 0.55s). Default smooth. Use one feel for a whole video." },
19828
+ delay: num("Entrances: seconds into the clip before the move starts. Exits: seconds before the clip ends that the layer is gone, so a group leaves in turn. Default 0."),
19829
+ from: num("hold: clip-relative second the drift starts (where the entrance lands)."),
19830
+ to: num("hold: clip-relative second it ends (where the exit starts). Default the clip end."),
19831
+ depth: num("hold: how much it drifts \u2014 1 for the hero, 0.4\u20130.6 for what sits behind it."),
19832
+ motionBlur: bool("Smear fast travel with a camera-shutter motion blur (2D layers). Draws once where nothing moves."),
19833
+ arc: num("slideIn, slideOut, dropIn: travel on a curve \u2014 how far the path bows toward the middle of the frame, as a fraction of the travel. 0.3 is gentle. For pictures; keep type and bars straight."),
19834
+ anticipate: bool("fadeOut: a small lift the other way before it fades, for big layers."),
19835
+ length: num("Seconds the move takes. Default by style."),
19836
+ direction: { type: "string", enum: ["left", "right", "up", "down"], description: "Which way the layer travels (slideIn, slideOut, maskReveal, maskHide), or the axis growIn grows on." },
19837
+ distance: num("Travel as a fraction of the frame height. Default by style (0.04\u20130.08).")
19838
+ },
19839
+ required: ["clipId", "recipe"]
19840
+ },
19841
+ method: "animateClip"
19842
+ },
19843
+ {
19844
+ name: "animate_scene",
19845
+ description: "Animate a whole scene the way a motion designer would, in one call. Each layer gets a role from what it draws \u2014 ground (covers the frame: a slow drift), hero (the one thing the scene is about: enters first and biggest), support (staggered outward from the hero), text, detail (small marks, popping in last), follower (parented to a picture: arrives a beat after it) \u2014 and a move and start time from its role, its size, the scene's length and the feel, so the scene speaks one motion language. Text always gets a text animation (letters or words), never a block move; pictures get keyframed recipes. Moves travel the way the scene's joins push (flow). With music on the timeline the lead lands on a beat (onBeat). Pictures travel on arcs, type and bars straight. Between the entrance and the exit every picture keeps a slow drift, deeper for the hero (hold). Layers leave last in, first out, the way the next scene comes in; big layers gather before a fade-out. Moves that would cross another layer are swapped for ones that stay in place (note). Layers that already move are left alone unless replace is true. A scene runs between two cuts; at picks it (default the playhead), all does every scene. Returns what each layer got. Follow with lint_motion to join the cuts.",
19846
+ inputSchema: {
19847
+ type: "object",
19848
+ properties: {
19849
+ at: num("A time inside the scene to animate. Default: the playhead."),
19850
+ all: bool("Animate every scene in the sequence."),
19851
+ style: { type: "string", enum: ["smooth", "snappy", "bouncy"], description: "The feel, for every layer. Default smooth." },
19852
+ replace: bool("Re-animate layers that already move, replacing their entrance (and exit if they leave early)."),
19853
+ flow: { type: "string", enum: ["left", "right", "up", "down"], description: "The way moves travel. Default: the way the scene's join camera moves, else up." },
19854
+ pace: num("Spacing of the cascade: 0.6 tight, 1 normal (default), 1.6 loose."),
19855
+ hold: bool("Keep a slow drift on every picture between its entrance and its exit. Default true."),
19856
+ beats: bool("With music on the timeline (beat markers, or audio clips), move the cascade so the lead lands on the nearest beat. Default true."),
19857
+ dryRun: bool("Return the plan without changing anything.")
19858
+ }
19859
+ },
19860
+ method: "animateScene"
19861
+ },
19862
+ {
19863
+ name: "describe_motion",
19864
+ description: "The motion design rules to animate by \u2014 easing curves, durations, stagger, overshoot, hierarchy, holds and reading time, which join to use between scenes \u2014 the same numbers lint_motion checks. Read it before animating a sequence.",
19865
+ inputSchema: { type: "object", properties: {} },
19866
+ method: "describeMotion"
19867
+ },
19868
+ {
19869
+ name: "lint_motion",
19870
+ description: "Check the open sequence's animation the way a motion designer would: still cuts (the picture jumps instead of moving through the change), linear moves (no easing), several layers making the same entrance on one frame (no stagger), moves too fast to follow, and text cut away before it can be read. Each finding has a message and, when the fix is mechanical, `fix`: [method, params] calls to run in order, one call each (run_tools), then lint again. Applying every fix is the one-click polish.",
19871
+ inputSchema: {
19872
+ type: "object",
19873
+ properties: {
19874
+ from: num("Only findings from this time, seconds."),
19875
+ to: num("Only findings up to this time, seconds.")
19876
+ }
19877
+ },
19878
+ method: "lintMotion"
19879
+ },
19880
+ {
19881
+ name: "list_cuts",
19882
+ description: "Every cut in the open sequence \u2014 a time where layers end and others start together \u2014 with what leaves, what arrives, and whether the picture moves through it (a camera move, or layers moving on both sides) or it jumps (a hard cut, a still frame before an entrance, an exit before a still cut). `stillCuts` lists the ones that jump. Read it before joining scenes, and again after.",
19883
+ inputSchema: { type: "object", properties: {} },
19884
+ method: "listCuts"
19885
+ },
19796
19886
  {
19797
19887
  name: "create_3d_object",
19798
19888
  description: "Make a word, a logo or an SVG solid: extruded to a depth with rounded edges and lit like a 3D model, as its own clip with nothing around it (no backdrop), so it floats over whatever is beneath. Give text (drawn in font/weight/color) or mediaFileId of a transparent PNG or an SVG in the bin (a photo needs remove_background first). spins turns it whole times over the clip; rotateX/Y/Z pose it. It is a showcase clip: describe_effect showcase lists its looks (chrome, glass\u2026), lighting and side colour, set with set_clip_effect.",
@@ -20174,9 +20264,11 @@ var BASE_TOOLS = [
20174
20264
  "orbitStartAngle",
20175
20265
  "pathTrimStart",
20176
20266
  "pathTrimEnd",
20177
- "pathTrimOffset"
20267
+ "pathTrimOffset",
20268
+ "textPathOffset",
20269
+ "textPathWave"
20178
20270
  ],
20179
- description: "Property to animate. posX/posY and opacity are 0..1 fractions, rotation is degrees, scaleX/scaleY are multipliers (1 = unchanged), pathTrimEnd 0\u21921 draws a pen stroke on."
20271
+ description: "Property to animate. posX/posY and opacity are 0..1 fractions, rotation is degrees, scaleX/scaleY are multipliers (1 = unchanged), pathTrimEnd 0\u21921 draws a pen stroke on, textPathOffset slides text along its path (0..1) and textPathWave is the height of the wave bending it (px @1080p)."
20180
20272
  },
20181
20273
  keyframes: {
20182
20274
  type: "array",
@@ -20301,12 +20393,21 @@ var BASE_TOOLS = [
20301
20393
  description: "Entrance preset: fadeIn, slideUp, blurIn, typewriter, typewriterCursor, scaleIn, springUp, slideInLeft, slideInRight, riseFade, unfoldDown, unfoldUp, foldFlip, depthPop, wordPop, karaokeHighlight, karaokeScale, springPop, neonGlowPulse, karaokePill, cyberSlant, wipeUp, trackIn, slamIn, elasticPop, squashDrop, glitchIn, tumbleIn, swingIn, flip3D, cinematicRise, stretchIn, bounceDrop, rollIn, maskRise (rises from behind an invisible line), blockReveal (a bar in highlightColor wipes across, then uncovers the text), focusPull (big and blurred, pulling to crisp), whipIn (sideways with a motion smear), scatterSettle (letters scattered up and down drop into line), depthAssemble (letters fly in from scattered depth), decode (letters flicker through random glyphs, then resolve), countUp (the first number in the text counts up to its value, keeping its format, e.g. $787,539.00)."
20302
20394
  },
20303
20395
  unit: { type: "string", enum: ["letter", "word", "line"], description: "What the animation steps through." },
20304
- durationIn: num("Seconds for one unit's entrance to complete."),
20396
+ durationIn: num("Seconds for one unit's entrance to complete. 0 cuts each unit on."),
20305
20397
  stagger: num("Seconds between consecutive units starting. 0 moves them together."),
20398
+ delay: num("Seconds into the clip before the first unit starts. Default 0."),
20306
20399
  distance: num("Slide or offset distance in pixels @1080p, for the slide/spring/unfold presets."),
20307
20400
  highlightColor: str('Highlight colour for the karaoke-style presets and the bar of blockReveal, e.g. "#ff2d55".'),
20308
20401
  order: { type: "string", enum: ["forward", "reverse", "center", "edges", "random"], description: "Which unit goes first. Defaults to reading order." },
20309
20402
  seed: num("Seed for `random` order, so the shuffle stays the same on every render."),
20403
+ syncToWords: bool("Start each unit when its word is spoken (the clip's word timings \u2014 from generate_captions, or passed as wordTimings) instead of on the stagger. With durationIn 0 and fadeIn, words cut on exactly as they are said."),
20404
+ wordTimings: {
20405
+ type: "array",
20406
+ description: "Per-word timings for this clip in clip seconds, [{ text, start, end }], in reading order. Drives syncToWords and the kinetic presets. Replaces any the clip had.",
20407
+ items: { type: "object", properties: { text: { type: "string" }, start: { type: "number" }, end: { type: "number" } }, required: ["text", "start", "end"] }
20408
+ },
20409
+ placeholder: str('Colour of a solid bar drawn where each unit will appear until it enters, e.g. "#111111" \u2014 words waiting their turn as redaction bars. Empty string removes it.'),
20410
+ activeScale: num("Kinetic presets: size of the active word, 1 for no pop (stops it colliding with its neighbours). Defaults per preset, 1.1\u20131.32."),
20310
20411
  remove: bool("Take the animation off, leaving the text to cut on.")
20311
20412
  },
20312
20413
  required: ["clipId"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goatedit-mcp",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "Local MCP server for the GoatEdit video editor: drive your open editor tab from Claude Code or any MCP client",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",