@pixerate/editor 0.230.0 → 0.231.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7141,6 +7141,50 @@ var ImageEditorController = class {
7141
7141
  const enc = encodeSurface(surface);
7142
7142
  return enc ? enc.url : null;
7143
7143
  }
7144
+ maskedImageCache = /* @__PURE__ */ new WeakMap();
7145
+ /**
7146
+ * A pixel layer's own pixels with its raster and vector masks applied, cropped to what shows: a
7147
+ * PNG data URL and its document bounds, or `null` for an unknown or non-pixel layer, or when
7148
+ * nothing shows. Opacity, blending, filters and effects are left out, as in `getLayerDataURL`.
7149
+ * Use it for a masked layer, whose stored pixels (a whole copy, for Separate Subject's subject)
7150
+ * are not what it shows.
7151
+ */
7152
+ getMaskedLayerImage(id) {
7153
+ const layer = this.getLayer(id);
7154
+ if (!layer || layer.type !== "pixel") return null;
7155
+ const surface = this.surfaceOf(layer);
7156
+ const cached = this.maskedImageCache.get(layer);
7157
+ if (cached && cached.surface === surface) return cached.image;
7158
+ const b = this.getLayerBounds(id);
7159
+ let image = null;
7160
+ if (b) {
7161
+ const content = { ...layer, visible: true, opacity: 1, blend: "normal" };
7162
+ delete content.clipped;
7163
+ delete content.fillOpacity;
7164
+ delete content.effects;
7165
+ delete content.filters;
7166
+ const data = this.compositor.composite([content], b, this.compositorSources());
7167
+ let x0 = b.width, y0 = b.height, x1 = -1, y1 = -1;
7168
+ for (let y = 0; y < b.height; y++) {
7169
+ for (let x = 0; x < b.width; x++) {
7170
+ if (!data[(y * b.width + x) * 4 + 3]) continue;
7171
+ if (x < x0) x0 = x;
7172
+ if (x > x1) x1 = x;
7173
+ if (y < y0) y0 = y;
7174
+ if (y > y1) y1 = y;
7175
+ }
7176
+ }
7177
+ if (x1 >= 0) {
7178
+ const w = x1 - x0 + 1;
7179
+ const h = y1 - y0 + 1;
7180
+ const out = new Uint8ClampedArray(w * h * 4);
7181
+ for (let y = 0; y < h; y++) out.set(data.subarray(((y0 + y) * b.width + x0) * 4, ((y0 + y) * b.width + x0 + w) * 4), y * w * 4);
7182
+ image = { url: pngDataUrl(w, h, out, 4), bounds: { x: b.x + x0, y: b.y + y0, width: w, height: h } };
7183
+ }
7184
+ }
7185
+ this.maskedImageCache.set(layer, { surface, image });
7186
+ return image;
7187
+ }
7144
7188
  /**
7145
7189
  * Composites the layer stack in document space without a canvas (annotation layers need one
7146
7190
  * and are left out): `rect` (default: the canvas) as RGBA, straight alpha. Crop, rotation and
@@ -20820,7 +20864,8 @@ function extractNormalizedLayerItems(controller, fallbackImageUrl = "") {
20820
20864
  const imgW = state.imageDimensions?.width || 1;
20821
20865
  const imgH = state.imageDimensions?.height || 1;
20822
20866
  return ctrlLayers.map((l) => {
20823
- const bounds = controller.getLayerBounds(l.id) || {
20867
+ const masked = l.type === "pixel" && (l.mask || l.vectorMask) ? controller.getMaskedLayerImage(l.id) : null;
20868
+ const bounds = masked?.bounds || controller.getLayerBounds(l.id) || {
20824
20869
  x: 0,
20825
20870
  y: 0,
20826
20871
  width: imgW,
@@ -20828,7 +20873,7 @@ function extractNormalizedLayerItems(controller, fallbackImageUrl = "") {
20828
20873
  };
20829
20874
  const sLayer = sLayerMap.get(l.id);
20830
20875
  const assetKey = sLayer?.asset;
20831
- const layerDataUrl = assetKey && assets[assetKey] || assets[l.id] || (sLayer?.source === "document" ? fallbackImageUrl : "");
20876
+ const layerDataUrl = masked?.url || assetKey && assets[assetKey] || assets[l.id] || (sLayer?.source === "document" ? fallbackImageUrl : "");
20832
20877
  return {
20833
20878
  id: l.id,
20834
20879
  name: l.name || "Untitled Layer",
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12;
2
2
 
3
- var _chunkA57ZQDNNcjs = require('../chunk-A57ZQDNN.cjs');
3
+ var _chunk5T3H7CGGcjs = require('../chunk-5T3H7CGG.cjs');
4
4
 
5
5
 
6
6
 
@@ -3213,7 +3213,7 @@ function timeLapseVideo(frameCount, width, height, fps, holdMs, name = "Time-lap
3213
3213
  }
3214
3214
  const video = { version: 1, name, width: w, height: h, fps, background: "#000000", assets, tracks: [{ id: "v1", kind: "video", clips }] };
3215
3215
  const durationMs = frameCount ? clips[clips.length - 1].start + clips[clips.length - 1].duration : 0;
3216
- return { video, ffmpeg: _chunkA57ZQDNNcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3216
+ return { video, ffmpeg: _chunk5T3H7CGGcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3217
3217
  }
3218
3218
  async function buildTimeLapse(source, target, options = {}) {
3219
3219
  const maxSide = Math.max(32, Math.min(4096, Math.round(_nullishCoalesce(options.maxSide, () => ( 720)))));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  toVideoFfmpeg
3
- } from "../chunk-ONNNNGNS.js";
3
+ } from "../chunk-CSM5T6SE.js";
4
4
  import {
5
5
  deserializeLayers,
6
6
  exportPsd,
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Agent tools for provider camera moves on video clips (see `VideoClipCamera`): list the moves
3
+ * by role, set one on a clip (baked into its transform keys) and clear it. They ride on the video
4
+ * effects tool provider (`createVideoEffectsToolProvider`).
5
+ */
6
+ import type { EffectToolContext } from '../effects/tools.cjs';
7
+ import type { AgentTool } from '../tools/registry.cjs';
8
+ import type { VideoEditorController } from './controller.cjs';
9
+ /** The video camera move tools (see the module comment). */
10
+ export declare function videoCameraMoveTools(controller: VideoEditorController, ctx: EffectToolContext): AgentTool[];
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Agent tools for provider camera moves on video clips (see `VideoClipCamera`): list the moves
3
+ * by role, set one on a clip (baked into its transform keys) and clear it. They ride on the video
4
+ * effects tool provider (`createVideoEffectsToolProvider`).
5
+ */
6
+ import type { EffectToolContext } from '../effects/tools.js';
7
+ import type { AgentTool } from '../tools/registry.js';
8
+ import type { VideoEditorController } from './controller.js';
9
+ /** The video camera move tools (see the module comment). */
10
+ export declare function videoCameraMoveTools(controller: VideoEditorController, ctx: EffectToolContext): AgentTool[];
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Provider camera moves on video clips (see `VideoClipCamera` and `@pixerate/editor/effects`).
3
+ * A clip is the shot: a `transition` move (`in`) moves the camera from `from` to `framing` from
4
+ * the clip's start, and a `hold` move (`during`) plays across the rest of the clip. The moves are
5
+ * baked into the clip's x, y, scale and rotation keys with `sampleEffectCameraMove` at the
6
+ * project's frame rate, keeping a cut's two keys (a jump), so nothing downstream needs the
7
+ * provider. The camera looks at the clip's picture as its own transform places it.
8
+ */
9
+ import type { CameraMoveRole, CameraMoveSpec, CameraStage, CameraView, EffectProvider } from '../effects/types.cjs';
10
+ import type { VideoCameraFraming, VideoClip, VideoClipCamera, VideoProject, VideoTransform } from './types.cjs';
11
+ /** The view that shows `framing` of a `stage`-sized frame (see `VideoCameraFraming`). */
12
+ export declare function videoCameraView(framing: VideoCameraFraming | undefined, stage: CameraStage): CameraView;
13
+ /**
14
+ * The clip transform that shows `view` of a picture placed by `base`: the picture's centre goes
15
+ * where the camera puts it (turned by the view's roll round the frame's centre), its scale times
16
+ * the zoom, its rotation plus the roll. Tilt, turn and blur have no place in a clip transform.
17
+ */
18
+ export declare function videoTransformOfView(view: CameraView, base: VideoClipCamera['base'], stage: CameraStage): Required<VideoClipCamera['base']>;
19
+ /** What baking a clip's camera moves gave: its transform with the keys, and notes on what could not be kept. */
20
+ export interface VideoCameraBake {
21
+ transform: VideoTransform;
22
+ /** Ms from the clip's start of each move's cut, when it has one. */
23
+ cuts: number[];
24
+ /** When each move plays (clip ms). */
25
+ windows: {
26
+ in?: {
27
+ start: number;
28
+ end: number;
29
+ };
30
+ during?: {
31
+ start: number;
32
+ end: number;
33
+ };
34
+ };
35
+ notes: string[];
36
+ }
37
+ /** The clip's transform as plain numbers, for a camera's `base` (refusing keyed fields, which a camera would replace). */
38
+ export declare function videoCameraBase(clip: VideoClip): VideoClipCamera['base'];
39
+ /**
40
+ * Bakes a clip's camera moves (its `camera`) into transform keys at the project's frame rate:
41
+ * `in` from the clip's start over its `ms` (default the move's `durationMs`), then `during`
42
+ * across the rest of the clip. Keys are linear, one per frame, with both keys of a cut kept.
43
+ * Async: the provider samples the moves (`sampleEffectCameraMove`).
44
+ */
45
+ export declare function bakeVideoClipCamera(clip: VideoClip, camera: VideoClipCamera, project: Pick<VideoProject, 'width' | 'height' | 'fps'>, provider: EffectProvider): Promise<VideoCameraBake>;
46
+ /** A clip's camera move for a role as its parts, or undefined. */
47
+ export declare function videoClipCameraMove(clip: Pick<VideoClip, 'camera'> | undefined, role: CameraMoveRole): Exclude<CameraMoveSpec, string> | undefined;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Provider camera moves on video clips (see `VideoClipCamera` and `@pixerate/editor/effects`).
3
+ * A clip is the shot: a `transition` move (`in`) moves the camera from `from` to `framing` from
4
+ * the clip's start, and a `hold` move (`during`) plays across the rest of the clip. The moves are
5
+ * baked into the clip's x, y, scale and rotation keys with `sampleEffectCameraMove` at the
6
+ * project's frame rate, keeping a cut's two keys (a jump), so nothing downstream needs the
7
+ * provider. The camera looks at the clip's picture as its own transform places it.
8
+ */
9
+ import type { CameraMoveRole, CameraMoveSpec, CameraStage, CameraView, EffectProvider } from '../effects/types.js';
10
+ import type { VideoCameraFraming, VideoClip, VideoClipCamera, VideoProject, VideoTransform } from './types.js';
11
+ /** The view that shows `framing` of a `stage`-sized frame (see `VideoCameraFraming`). */
12
+ export declare function videoCameraView(framing: VideoCameraFraming | undefined, stage: CameraStage): CameraView;
13
+ /**
14
+ * The clip transform that shows `view` of a picture placed by `base`: the picture's centre goes
15
+ * where the camera puts it (turned by the view's roll round the frame's centre), its scale times
16
+ * the zoom, its rotation plus the roll. Tilt, turn and blur have no place in a clip transform.
17
+ */
18
+ export declare function videoTransformOfView(view: CameraView, base: VideoClipCamera['base'], stage: CameraStage): Required<VideoClipCamera['base']>;
19
+ /** What baking a clip's camera moves gave: its transform with the keys, and notes on what could not be kept. */
20
+ export interface VideoCameraBake {
21
+ transform: VideoTransform;
22
+ /** Ms from the clip's start of each move's cut, when it has one. */
23
+ cuts: number[];
24
+ /** When each move plays (clip ms). */
25
+ windows: {
26
+ in?: {
27
+ start: number;
28
+ end: number;
29
+ };
30
+ during?: {
31
+ start: number;
32
+ end: number;
33
+ };
34
+ };
35
+ notes: string[];
36
+ }
37
+ /** The clip's transform as plain numbers, for a camera's `base` (refusing keyed fields, which a camera would replace). */
38
+ export declare function videoCameraBase(clip: VideoClip): VideoClipCamera['base'];
39
+ /**
40
+ * Bakes a clip's camera moves (its `camera`) into transform keys at the project's frame rate:
41
+ * `in` from the clip's start over its `ms` (default the move's `durationMs`), then `during`
42
+ * across the rest of the clip. Keys are linear, one per frame, with both keys of a cut kept.
43
+ * Async: the provider samples the moves (`sampleEffectCameraMove`).
44
+ */
45
+ export declare function bakeVideoClipCamera(clip: VideoClip, camera: VideoClipCamera, project: Pick<VideoProject, 'width' | 'height' | 'fps'>, provider: EffectProvider): Promise<VideoCameraBake>;
46
+ /** A clip's camera move for a role as its parts, or undefined. */
47
+ export declare function videoClipCameraMove(clip: Pick<VideoClip, 'camera'> | undefined, role: CameraMoveRole): Exclude<CameraMoveSpec, string> | undefined;
@@ -6,7 +6,7 @@ export declare function videoClipKeyframes(clip: VideoClip): {
6
6
  keys: ReturnType<typeof videoKeysOf>;
7
7
  }[];
8
8
  export type VideoIssueSeverity = 'error' | 'warning' | 'note';
9
- export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "unknown-duration", "unused-asset", "unused-sequence", "marker-past-end", "missing-target-track", "empty"];
9
+ export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "camera-stale", "unknown-duration", "unused-asset", "unused-sequence", "marker-past-end", "missing-target-track", "empty"];
10
10
  export type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
11
11
  export interface VideoIssue {
12
12
  code: VideoIssueCode;
@@ -6,7 +6,7 @@ export declare function videoClipKeyframes(clip: VideoClip): {
6
6
  keys: ReturnType<typeof videoKeysOf>;
7
7
  }[];
8
8
  export type VideoIssueSeverity = 'error' | 'warning' | 'note';
9
- export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "unknown-duration", "unused-asset", "unused-sequence", "marker-past-end", "missing-target-track", "empty"];
9
+ export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "camera-stale", "unknown-duration", "unused-asset", "unused-sequence", "marker-past-end", "missing-target-track", "empty"];
10
10
  export type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
11
11
  export interface VideoIssue {
12
12
  code: VideoIssueCode;
@@ -12,9 +12,10 @@ import { VideoPreviewPixels } from './scopes.cjs';
12
12
  import type { VideoPreviewScale } from './proxy.cjs';
13
13
  import type { VideoFrameCache } from './frame-cache.cjs';
14
14
  import { type VideoSvgOptions } from './render.cjs';
15
- import type { VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.cjs';
15
+ import type { VideoCameraFraming, VideoClipCamera, VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.cjs';
16
16
  import { EffectsSlot } from '../effects/helpers.cjs';
17
- import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.cjs';
17
+ import { type VideoCameraBake } from './camera.cjs';
18
+ import type { CameraMoveRole, CameraMoveSpec, EffectDescription, EffectProvider, EffectSummary, EffectValue } from '../effects/types.cjs';
18
19
  import { VideoEffectsEngine, type VideoEffectPlace } from './effects.cjs';
19
20
  import { type VideoAnimatable, type VideoKey } from './keyframes.cjs';
20
21
  import { type VideoEditPlan, type VideoEditPlanInput } from './plan.cjs';
@@ -50,6 +51,19 @@ export interface VideoEditorOptions {
50
51
  effects?: EffectProvider | null;
51
52
  }
52
53
  /** What `applyClipEffect` and the other effect edits return: the edit result plus what they made or changed. */
54
+ /** What setting or clearing a clip's camera move did: its camera now, the keys baked per property, any cuts and when each move plays (clip ms). */
55
+ export type VideoCameraMoveResult = {
56
+ ok: true;
57
+ clip: string;
58
+ camera: VideoClipCamera | null;
59
+ keys: Record<'x' | 'y' | 'scale' | 'rotation', number>;
60
+ cuts: number[];
61
+ windows: VideoCameraBake['windows'];
62
+ notes: string[];
63
+ } | {
64
+ ok: false;
65
+ error: string;
66
+ };
53
67
  export type VideoEffectEditResult = (VideoEditResult & {
54
68
  ok: true;
55
69
  clip: string;
@@ -272,6 +286,27 @@ export declare class VideoEditorController {
272
286
  }, options?: {
273
287
  merge?: string;
274
288
  }): Promise<VideoEffectEditResult>;
289
+ /** The provider's camera moves for a role (`transition` into a clip, `hold` while it plays), or all of them. Empty without camera support. */
290
+ cameraMoves(role?: CameraMoveRole): Promise<EffectSummary[]>;
291
+ private cameraClip;
292
+ private cameraEdit;
293
+ /**
294
+ * Sets the camera move a clip plays into (`transition`: from `from` to `framing` from the
295
+ * clip's start) or while it holds (`hold`: across the rest of the clip at `framing`), and bakes
296
+ * the clip's moves into its x, y, scale and rotation keys at the project's frame rate, keeping a
297
+ * cut's two keys. The move is checked first (role, preset, values; a preset's values and a move
298
+ * in's length are written out). A clip whose transform is keyed by hand is refused. One undo step.
299
+ */
300
+ setClipCameraMove(clip: string, role: CameraMoveRole, spec: CameraMoveSpec, options?: {
301
+ from?: VideoCameraFraming | null;
302
+ framing?: VideoCameraFraming | null;
303
+ merge?: string;
304
+ }): Promise<VideoCameraMoveResult>;
305
+ /**
306
+ * Removes a clip's camera move for a role and bakes what is left (which needs the provider);
307
+ * with no move left the transform goes back to what it was before the moves. One undo step.
308
+ */
309
+ clearClipCameraMove(clip: string, role: CameraMoveRole): Promise<VideoCameraMoveResult>;
275
310
  /** Removes an effect from a clip's stack (works without a provider, so placeholders can be cleared). One undo step. */
276
311
  removeClipEffect(clip: string, instance: string): VideoEffectEditResult;
277
312
  /**
@@ -12,9 +12,10 @@ import { VideoPreviewPixels } from './scopes.js';
12
12
  import type { VideoPreviewScale } from './proxy.js';
13
13
  import type { VideoFrameCache } from './frame-cache.js';
14
14
  import { type VideoSvgOptions } from './render.js';
15
- import type { VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.js';
15
+ import type { VideoCameraFraming, VideoClipCamera, VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.js';
16
16
  import { EffectsSlot } from '../effects/helpers.js';
17
- import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.js';
17
+ import { type VideoCameraBake } from './camera.js';
18
+ import type { CameraMoveRole, CameraMoveSpec, EffectDescription, EffectProvider, EffectSummary, EffectValue } from '../effects/types.js';
18
19
  import { VideoEffectsEngine, type VideoEffectPlace } from './effects.js';
19
20
  import { type VideoAnimatable, type VideoKey } from './keyframes.js';
20
21
  import { type VideoEditPlan, type VideoEditPlanInput } from './plan.js';
@@ -50,6 +51,19 @@ export interface VideoEditorOptions {
50
51
  effects?: EffectProvider | null;
51
52
  }
52
53
  /** What `applyClipEffect` and the other effect edits return: the edit result plus what they made or changed. */
54
+ /** What setting or clearing a clip's camera move did: its camera now, the keys baked per property, any cuts and when each move plays (clip ms). */
55
+ export type VideoCameraMoveResult = {
56
+ ok: true;
57
+ clip: string;
58
+ camera: VideoClipCamera | null;
59
+ keys: Record<'x' | 'y' | 'scale' | 'rotation', number>;
60
+ cuts: number[];
61
+ windows: VideoCameraBake['windows'];
62
+ notes: string[];
63
+ } | {
64
+ ok: false;
65
+ error: string;
66
+ };
53
67
  export type VideoEffectEditResult = (VideoEditResult & {
54
68
  ok: true;
55
69
  clip: string;
@@ -272,6 +286,27 @@ export declare class VideoEditorController {
272
286
  }, options?: {
273
287
  merge?: string;
274
288
  }): Promise<VideoEffectEditResult>;
289
+ /** The provider's camera moves for a role (`transition` into a clip, `hold` while it plays), or all of them. Empty without camera support. */
290
+ cameraMoves(role?: CameraMoveRole): Promise<EffectSummary[]>;
291
+ private cameraClip;
292
+ private cameraEdit;
293
+ /**
294
+ * Sets the camera move a clip plays into (`transition`: from `from` to `framing` from the
295
+ * clip's start) or while it holds (`hold`: across the rest of the clip at `framing`), and bakes
296
+ * the clip's moves into its x, y, scale and rotation keys at the project's frame rate, keeping a
297
+ * cut's two keys. The move is checked first (role, preset, values; a preset's values and a move
298
+ * in's length are written out). A clip whose transform is keyed by hand is refused. One undo step.
299
+ */
300
+ setClipCameraMove(clip: string, role: CameraMoveRole, spec: CameraMoveSpec, options?: {
301
+ from?: VideoCameraFraming | null;
302
+ framing?: VideoCameraFraming | null;
303
+ merge?: string;
304
+ }): Promise<VideoCameraMoveResult>;
305
+ /**
306
+ * Removes a clip's camera move for a role and bakes what is left (which needs the provider);
307
+ * with no move left the transform goes back to what it was before the moves. One undo step.
308
+ */
309
+ clearClipCameraMove(clip: string, role: CameraMoveRole): Promise<VideoCameraMoveResult>;
275
310
  /** Removes an effect from a clip's stack (works without a provider, so placeholders can be cleared). One undo step. */
276
311
  removeClipEffect(clip: string, instance: string): VideoEffectEditResult;
277
312
  /**
@@ -2,7 +2,8 @@
2
2
  * Agent tools for provider effects in the video editor: the shared effect tools
3
3
  * (`search_effects`, `describe_effect`, `list_applied_effects`, `apply_effect`, `update_effect`,
4
4
  * `remove_effect`) on clips, plus `add_video_effect_clip`, `set_video_effect_transition` and
5
- * `set_video_effect_keyframes`.
5
+ * `set_video_effect_keyframes`, and the camera move tools (`list_video_camera_moves`,
6
+ * `set_clip_camera_move`, `clear_clip_camera_move`).
6
7
  */
7
8
  import { type AppliedEffectInfo } from '../effects/tools.cjs';
8
9
  import type { AgentToolProvider } from '../tools/registry.cjs';
@@ -2,7 +2,8 @@
2
2
  * Agent tools for provider effects in the video editor: the shared effect tools
3
3
  * (`search_effects`, `describe_effect`, `list_applied_effects`, `apply_effect`, `update_effect`,
4
4
  * `remove_effect`) on clips, plus `add_video_effect_clip`, `set_video_effect_transition` and
5
- * `set_video_effect_keyframes`.
5
+ * `set_video_effect_keyframes`, and the camera move tools (`list_video_camera_moves`,
6
+ * `set_clip_camera_move`, `clear_clip_camera_move`).
6
7
  */
7
8
  import { type AppliedEffectInfo } from '../effects/tools.js';
8
9
  import type { AgentToolProvider } from '../tools/registry.js';