creavit-studio-mcp 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -8
- package/package.json +1 -1
- package/src/protocol.mjs +1 -1
- package/src/rpcServer.mjs +2 -0
- package/src/tools/browserTools.mjs +103 -9
- package/src/tools/editorTools.mjs +50 -4
- package/src/tools/projectTools.mjs +8 -0
- package/src/tools/systemTools.mjs +2 -2
package/README.md
CHANGED
|
@@ -111,9 +111,15 @@ files directly and work with the app closed.
|
|
|
111
111
|
`creavit_editor_export`, `creavit_editor_history`
|
|
112
112
|
|
|
113
113
|
**Appearance** — `creavit_editor_background_get`,
|
|
114
|
-
`creavit_editor_background_set`, `
|
|
114
|
+
`creavit_editor_background_set`, `creavit_editor_wallpapers`,
|
|
115
|
+
`creavit_editor_wallpaper_set`, `creavit_editor_camera_get`,
|
|
115
116
|
`creavit_editor_camera_set`, `creavit_editor_audio`
|
|
116
117
|
|
|
118
|
+
> Zoom ranges are normally **not** something you add. Creavit Studio records the
|
|
119
|
+
> real mouse clicks and builds its own auto-zoom segments in the editor; use
|
|
120
|
+
> `creavit_editor_add_zoom` only when the user asks for a zoom at a specific
|
|
121
|
+
> moment.
|
|
122
|
+
|
|
117
123
|
**Perspective** — `creavit_editor_perspectives`,
|
|
118
124
|
`creavit_editor_add_perspective`, `creavit_editor_update_perspective`,
|
|
119
125
|
`creavit_editor_remove_perspective`
|
|
@@ -175,6 +181,9 @@ Use the typed tools instead of guessing generic setting keys:
|
|
|
175
181
|
```text
|
|
176
182
|
creavit_editor_background_set type=solid color=#10131a
|
|
177
183
|
creavit_editor_background_set type=gradient gradient={type, direction, colors}
|
|
184
|
+
creavit_editor_wallpapers categories + sample names
|
|
185
|
+
creavit_editor_wallpapers category=macos that category's full list
|
|
186
|
+
creavit_editor_wallpaper_set name=sonoma-dark ready-made CMS wallpaper
|
|
178
187
|
creavit_editor_camera_set settings={visible,size,radius,shadow,mirror,...}
|
|
179
188
|
creavit_editor_audio action=mute
|
|
180
189
|
creavit_project_save
|
|
@@ -204,14 +213,22 @@ composited in.
|
|
|
204
213
|
|
|
205
214
|
### Record a URL walkthrough
|
|
206
215
|
|
|
207
|
-
`creavit_record_url_walkthrough` is the high-level workflow.
|
|
216
|
+
`creavit_record_url_walkthrough` is the high-level, atomic workflow. Use one call
|
|
217
|
+
instead of separate browser/start/interact/stop calls so client round trips and
|
|
218
|
+
retries cannot create gaps or duplicate recordings. By default it opens
|
|
208
219
|
the URL in a frameless site-only capture window (`16:9`, `4:3`, `1:1`, `9:16`,
|
|
209
220
|
or another requested ratio) and waits for the DOM, fonts, and images before
|
|
210
221
|
recording. It then executes ordered semantic actions with the real macOS mouse,
|
|
211
222
|
so the normal Creavit custom-cursor track receives authentic move/click events.
|
|
212
|
-
It trims the timeline to `durationMs`,
|
|
213
|
-
|
|
214
|
-
|
|
223
|
+
It trims the timeline to `durationMs`, optionally covers the whole video with a
|
|
224
|
+
perspective preset, mutes it, and saves it. With `export: true`, the tool starts
|
|
225
|
+
the render in the background and returns promptly; `openExport: true` opens the
|
|
226
|
+
video automatically when rendering finishes, without requiring export UI.
|
|
227
|
+
|
|
228
|
+
It does **not** add zoom ranges: the app records the real clicks and generates
|
|
229
|
+
its own auto-zoom segments in the editor, which land on the actual click times.
|
|
230
|
+
`autoZoom: true` (plus `replaceZooms: true` to wipe the app's own ones) is
|
|
231
|
+
opt-in, for when the user explicitly wants scripted zooms.
|
|
215
232
|
|
|
216
233
|
When the calling agent has inspected the page, it can pass ordered `steps`
|
|
217
234
|
(`scrollPages`, `dwellMs`, `zoom`, `scale`, `x`, `y`, and optionally
|
|
@@ -232,11 +249,13 @@ Example input:
|
|
|
232
249
|
{ "action": "click", "text": "Get Started", "dwellMs": 3000 }
|
|
233
250
|
],
|
|
234
251
|
"controlSystemMouse": true,
|
|
235
|
-
"autoZoom": true,
|
|
236
|
-
"zoomScale": 1.8,
|
|
237
252
|
"perspective": true,
|
|
238
253
|
"perspectiveTemplate": "minimal-tilt",
|
|
239
|
-
"mute": true
|
|
254
|
+
"mute": true,
|
|
255
|
+
"export": true,
|
|
256
|
+
"exportResolution": "1080p",
|
|
257
|
+
"exportFps": 60,
|
|
258
|
+
"openExport": true
|
|
240
259
|
}
|
|
241
260
|
```
|
|
242
261
|
|
package/package.json
CHANGED
package/src/protocol.mjs
CHANGED
|
@@ -6,7 +6,7 @@ export const ENDPOINT_FILENAME = "agent-bridge.json";
|
|
|
6
6
|
|
|
7
7
|
export const MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
8
8
|
export const SERVER_NAME = "creavit-studio";
|
|
9
|
-
export const SERVER_VERSION = "1.2
|
|
9
|
+
export const SERVER_VERSION = "1.3.2";
|
|
10
10
|
|
|
11
11
|
export const JSONRPC_ERRORS = {
|
|
12
12
|
PARSE_ERROR: -32700,
|
package/src/rpcServer.mjs
CHANGED
|
@@ -40,6 +40,8 @@ export function startRpcServer({ listTools, callTool }) {
|
|
|
40
40
|
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
41
41
|
capabilities: { tools: { listChanged: false } },
|
|
42
42
|
serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
|
|
43
|
+
instructions:
|
|
44
|
+
"Plan the complete Creavit tool sequence before the first call, then execute it without unnecessary pauses. For any website workflow that includes open + record + multiple interactions + stop, use creavit_record_url_walkthrough once instead of separate browser/recording calls; it can also start export in the background and open the result when ready. Mutating recording/export calls are idempotent, so do not stop/restart merely because a client-side timeout made the result uncertain—check creavit_recording_status or creavit_events.",
|
|
43
45
|
};
|
|
44
46
|
},
|
|
45
47
|
|
|
@@ -135,6 +135,9 @@ function trimSegmentsToDuration(segments, targetDuration) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
export function browserTools() {
|
|
138
|
+
let activeUrlWalkthroughPromise = null;
|
|
139
|
+
let recentUrlWalkthrough = null;
|
|
140
|
+
|
|
138
141
|
return [
|
|
139
142
|
bridgeTool({
|
|
140
143
|
name: "creavit_browser_open",
|
|
@@ -165,6 +168,17 @@ export function browserTools() {
|
|
|
165
168
|
),
|
|
166
169
|
}),
|
|
167
170
|
|
|
171
|
+
bridgeTool({
|
|
172
|
+
name: "creavit_browser_activate",
|
|
173
|
+
command: "browser.activate",
|
|
174
|
+
description:
|
|
175
|
+
"Brings the capture window or external browser to the foreground without changing its size or entering fullscreen. Call immediately after recording starts if you are driving the recording manually.",
|
|
176
|
+
inputSchema: schema({
|
|
177
|
+
captureWindowId: S.number("Clean capture window ID"),
|
|
178
|
+
browser: S.string("External browser name when there is no captureWindowId"),
|
|
179
|
+
}),
|
|
180
|
+
}),
|
|
181
|
+
|
|
168
182
|
bridgeTool({
|
|
169
183
|
name: "creavit_browser_focus",
|
|
170
184
|
command: "browser.focusPoint",
|
|
@@ -220,7 +234,7 @@ export function browserTools() {
|
|
|
220
234
|
{
|
|
221
235
|
name: "creavit_record_url_walkthrough",
|
|
222
236
|
description:
|
|
223
|
-
"
|
|
237
|
+
"USE THIS SINGLE ATOMIC TOOL for requests that open a website, record several clicks/types, stop, and optionally export/open the video. Do not split that workflow into manual browser + recording calls: this tool prevents duplicate recordings and agent round-trip gaps. It opens a non-fullscreen configurable-ratio window, waits for real page readiness, keeps camera off, defaults microphone/system audio off, executes ordered semantic steps, and can export/open the final video. Zooms are NOT added: Creavit Studio records the real clicks and generates its own auto-zoom segments in the editor. Only pass autoZoom=true when the user explicitly asks for extra scripted zooms.",
|
|
224
238
|
inputSchema: schema(
|
|
225
239
|
{
|
|
226
240
|
url: S.string("http(s) page to record"),
|
|
@@ -240,16 +254,33 @@ export function browserTools() {
|
|
|
240
254
|
tailMs: S.number("Still time after the last scroll (default 800)"),
|
|
241
255
|
controlSystemMouse: S.bool("Move/click the real macOS mouse so Creavit records native cursor data (default true)"),
|
|
242
256
|
mute: S.bool("Disable recording audio and mute export clips (default true)"),
|
|
243
|
-
autoZoom: S.bool("Add zooms around
|
|
244
|
-
replaceZooms: S.bool("
|
|
257
|
+
autoZoom: S.bool("Add scripted zooms around step destinations (default FALSE — the app already creates zooms from the real clicks; only enable when the user asks for it)"),
|
|
258
|
+
replaceZooms: S.bool("Delete the app's own click-based zooms before adding scripted ones (default false; only meaningful with autoZoom=true)"),
|
|
245
259
|
zoomScale: S.number("Automatic zoom scale (default 1.7)"),
|
|
246
260
|
perspective: S.bool("Apply perspective to the complete result"),
|
|
247
261
|
perspectiveTemplate: S.string("Perspective template id (default minimal-tilt)"),
|
|
248
262
|
save: S.bool("Save the generated project after editing (default true)"),
|
|
263
|
+
export: S.bool("Start export in the background after recording/editing (default false)"),
|
|
264
|
+
exportFilePath: S.string("Optional absolute target .mp4 path; defaults beside the .crvt project"),
|
|
265
|
+
exportResolution: S.string("Export resolution (default 1080p)"),
|
|
266
|
+
exportFps: S.number("Export frame rate (default 60)"),
|
|
267
|
+
exportQuality: S.string("Export quality (default high)", {
|
|
268
|
+
enum: ["compact", "high", "max"],
|
|
269
|
+
}),
|
|
270
|
+
openExport: S.bool("Open the exported video when finished (default true when export=true)"),
|
|
249
271
|
},
|
|
250
272
|
["url"],
|
|
251
273
|
),
|
|
252
|
-
run:
|
|
274
|
+
run: (args) => {
|
|
275
|
+
const requestKey = JSON.stringify(args || {});
|
|
276
|
+
if (
|
|
277
|
+
recentUrlWalkthrough?.key === requestKey &&
|
|
278
|
+
Date.now() < recentUrlWalkthrough.expiresAt
|
|
279
|
+
) {
|
|
280
|
+
return Promise.resolve(recentUrlWalkthrough.result);
|
|
281
|
+
}
|
|
282
|
+
if (activeUrlWalkthroughPromise) return activeUrlWalkthroughPromise;
|
|
283
|
+
const operation = (async () => {
|
|
253
284
|
const browser = canonicalBrowser(args.browser || "Zen Browser");
|
|
254
285
|
const cleanWindow = args.cleanWindow !== false;
|
|
255
286
|
const loadWaitMs = Math.max(0, Math.min(60_000, Number(args.loadWaitMs) || 1500));
|
|
@@ -259,8 +290,12 @@ export function browserTools() {
|
|
|
259
290
|
const scrollIntervalMs = Math.max(300, Math.min(15_000, Number(args.scrollIntervalMs) || 1400));
|
|
260
291
|
const tailMs = Math.max(200, Math.min(30_000, Number(args.tailMs) || 800));
|
|
261
292
|
const muted = args.mute !== false;
|
|
262
|
-
|
|
263
|
-
|
|
293
|
+
// Zoom'ları KENDİMİZ eklemiyoruz: Creavit Studio gerçek tıklamaları
|
|
294
|
+
// kaydedip editörde otomatik zoom segmentlerini kendi üretiyor. Bizim
|
|
295
|
+
// tahmini zamanlamayla eklediğimiz zoom'lar onların üstüne yanlış oturuyordu.
|
|
296
|
+
// Sadece kullanıcı açıkça isterse (autoZoom=true) devreye girer.
|
|
297
|
+
const autoZoom = args.autoZoom === true;
|
|
298
|
+
const replaceZooms = autoZoom && args.replaceZooms === true;
|
|
264
299
|
const controlSystemMouse = args.controlSystemMouse !== false;
|
|
265
300
|
const zoomScale = Math.max(1, Math.min(5, Number(args.zoomScale) || 1.7));
|
|
266
301
|
const requestedSteps = Array.isArray(args.steps) && args.steps.length ? args.steps : args.sections;
|
|
@@ -325,7 +360,7 @@ export function browserTools() {
|
|
|
325
360
|
}
|
|
326
361
|
const browserWindow = await waitForBrowserWindow(captureWindowId ? "Creavit Studio" : browser, titleHint, 20_000);
|
|
327
362
|
|
|
328
|
-
await callCommand("recording.start", {
|
|
363
|
+
const startResult = await callCommand("recording.start", {
|
|
329
364
|
options: {
|
|
330
365
|
startScreen: true,
|
|
331
366
|
cameraEnabled: false,
|
|
@@ -334,7 +369,19 @@ export function browserTools() {
|
|
|
334
369
|
recordingSource: { type: "window", windowId: browserWindow.id, windowInfo: browserWindow },
|
|
335
370
|
},
|
|
336
371
|
}, 180_000);
|
|
372
|
+
if (startResult?.started === false) {
|
|
373
|
+
throw new Error(
|
|
374
|
+
"A recording is already active. Stop it before starting a URL walkthrough.",
|
|
375
|
+
);
|
|
376
|
+
}
|
|
337
377
|
recordingStarted = true;
|
|
378
|
+
// recording.start briefly focuses the recorder controls. Restore the
|
|
379
|
+
// requested browser immediately so the actual walkthrough is visibly
|
|
380
|
+
// in front from the first recorded frame onward.
|
|
381
|
+
await callCommand("browser.activate", {
|
|
382
|
+
captureWindowId,
|
|
383
|
+
browser: captureWindowId ? undefined : browser,
|
|
384
|
+
});
|
|
338
385
|
const recordingStartedAt = Date.now();
|
|
339
386
|
const contentDeadline = durationMs ? recordingStartedAt + durationMs - tailMs : Number.POSITIVE_INFINITY;
|
|
340
387
|
await sleep(Math.min(leadInMs, Math.max(0, contentDeadline - Date.now())));
|
|
@@ -351,6 +398,7 @@ export function browserTools() {
|
|
|
351
398
|
selector: section.selector,
|
|
352
399
|
text: section.text,
|
|
353
400
|
value: section.value,
|
|
401
|
+
useSystemCursor: controlSystemMouse,
|
|
354
402
|
}, 30_000);
|
|
355
403
|
if (Number.isFinite(interaction?.x)) focus = { x: interaction.x, y: interaction.y };
|
|
356
404
|
} else {
|
|
@@ -383,9 +431,24 @@ export function browserTools() {
|
|
|
383
431
|
}
|
|
384
432
|
await callCommand("recording.stop", {}, 600_000);
|
|
385
433
|
recordingStarted = false;
|
|
434
|
+
// The source is finalized now. Closing it before editor processing/export
|
|
435
|
+
// avoids leaving a stale capture window over the foreground app.
|
|
436
|
+
if (captureWindowId) {
|
|
437
|
+
await callCommand("browser.close", { captureWindowId });
|
|
438
|
+
captureWindowId = null;
|
|
439
|
+
}
|
|
386
440
|
|
|
387
441
|
const editorState = await waitForEditor(previousEditor?.projectFilePath, 600_000);
|
|
388
|
-
const applied = {
|
|
442
|
+
const applied = {
|
|
443
|
+
muted: false,
|
|
444
|
+
zooms: [],
|
|
445
|
+
zoomSource: autoZoom ? "scripted (autoZoom=true)" : "editor auto-zoom from the recorded clicks",
|
|
446
|
+
perspective: null,
|
|
447
|
+
saved: false,
|
|
448
|
+
trimmedTo: null,
|
|
449
|
+
export: null,
|
|
450
|
+
openedExport: null,
|
|
451
|
+
};
|
|
389
452
|
let finalDuration = Number(editorState.duration);
|
|
390
453
|
if (durationMs) {
|
|
391
454
|
const targetDuration = durationMs / 1000;
|
|
@@ -421,7 +484,24 @@ export function browserTools() {
|
|
|
421
484
|
await callCommand("editor.saveProject", {}, 180_000);
|
|
422
485
|
applied.saved = true;
|
|
423
486
|
}
|
|
424
|
-
|
|
487
|
+
if (args.export === true) {
|
|
488
|
+
const exportResult = await callCommand(
|
|
489
|
+
"editor.export.start",
|
|
490
|
+
{
|
|
491
|
+
...(args.exportFilePath ? { filePath: args.exportFilePath } : {}),
|
|
492
|
+
format: "mp4",
|
|
493
|
+
resolution: args.exportResolution || "1080p",
|
|
494
|
+
fps: Math.max(1, Math.min(120, Math.round(Number(args.exportFps) || 60))),
|
|
495
|
+
quality: args.exportQuality || "high",
|
|
496
|
+
openWhenFinished: args.openExport !== false,
|
|
497
|
+
},
|
|
498
|
+
30_000,
|
|
499
|
+
);
|
|
500
|
+
applied.export = exportResult;
|
|
501
|
+
applied.openedExport =
|
|
502
|
+
args.openExport !== false ? "scheduled when export finishes" : null;
|
|
503
|
+
}
|
|
504
|
+
return textResult({ ok: true, url: args.url, browser: cleanWindow ? "Creavit Capture" : browser, cleanWindow, page: openResult, window: browserWindow, duration: finalDuration, rawDuration: editorState.duration, projectFilePath: editorState.projectFilePath, exportStartedInBackground: applied.export?.started === true, exportJob: applied.export?.job || null, applied });
|
|
425
505
|
} finally {
|
|
426
506
|
if (recordingStarted) {
|
|
427
507
|
try { await callCommand("recording.stop", {}, 600_000); } catch (_) {}
|
|
@@ -430,6 +510,20 @@ export function browserTools() {
|
|
|
430
510
|
try { await callCommand("browser.close", { captureWindowId }); } catch (_) {}
|
|
431
511
|
}
|
|
432
512
|
}
|
|
513
|
+
})();
|
|
514
|
+
activeUrlWalkthroughPromise = operation;
|
|
515
|
+
return operation.then((result) => {
|
|
516
|
+
recentUrlWalkthrough = {
|
|
517
|
+
key: requestKey,
|
|
518
|
+
result,
|
|
519
|
+
expiresAt: Date.now() + 60_000,
|
|
520
|
+
};
|
|
521
|
+
return result;
|
|
522
|
+
}).finally(() => {
|
|
523
|
+
if (activeUrlWalkthroughPromise === operation) {
|
|
524
|
+
activeUrlWalkthroughPromise = null;
|
|
525
|
+
}
|
|
526
|
+
});
|
|
433
527
|
},
|
|
434
528
|
},
|
|
435
529
|
];
|
|
@@ -61,14 +61,15 @@ export function editorTools() {
|
|
|
61
61
|
name: "creavit_editor_background_set",
|
|
62
62
|
command: "editor.setBackground",
|
|
63
63
|
description:
|
|
64
|
-
"Sets the canvas background. For solid use type='solid' and color. For gradient pass at least two stops as {type:'linear'|'radial', direction:'to-right', colors:[{color:'#...',position:0},...]}. Call creavit_project_save afterwards.",
|
|
64
|
+
"Sets the canvas background. For solid use type='solid' and color. For gradient pass at least two stops as {type:'linear'|'radial', direction:'to-right', colors:[{color:'#...',position:0},...]}. For a ready-made wallpaper use type='image' with `wallpaper` (name from creavit_editor_wallpapers) — or use creavit_editor_wallpaper_set directly. Call creavit_project_save afterwards.",
|
|
65
65
|
inputSchema: schema(
|
|
66
66
|
{
|
|
67
67
|
type: S.string("Background type", {
|
|
68
68
|
enum: ["solid", "color", "gradient", "image", "dynamic"],
|
|
69
69
|
}),
|
|
70
70
|
color: S.string("CSS color for a solid background"),
|
|
71
|
-
image: S.string("Image URL or
|
|
71
|
+
image: S.string("Image URL, local path, or a CMS wallpaper name"),
|
|
72
|
+
wallpaper: S.string("CMS wallpaper name (see creavit_editor_wallpapers)"),
|
|
72
73
|
blur: S.number("Image blur amount"),
|
|
73
74
|
gradient: S.object(
|
|
74
75
|
"Gradient configuration: {type, direction, colors:[{color,position}]}.",
|
|
@@ -81,6 +82,35 @@ export function editorTools() {
|
|
|
81
82
|
textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
|
|
82
83
|
}),
|
|
83
84
|
|
|
85
|
+
bridgeTool({
|
|
86
|
+
name: "creavit_editor_wallpapers",
|
|
87
|
+
command: "editor.listWallpapers",
|
|
88
|
+
description:
|
|
89
|
+
"Lists the ready-made wallpapers (background images from the Creavit CMS) grouped by category. Without arguments it returns the categories with a small sample of names — pass `category` for that category's complete list, or `search` to look a name up. Feed the name to creavit_editor_wallpaper_set.",
|
|
90
|
+
inputSchema: schema({
|
|
91
|
+
category: S.string("Only this category, e.g. 'macos'"),
|
|
92
|
+
search: S.string("Find wallpapers whose name contains this text"),
|
|
93
|
+
limit: S.number("Maximum number of names to return"),
|
|
94
|
+
}),
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
bridgeTool({
|
|
98
|
+
name: "creavit_editor_wallpaper_set",
|
|
99
|
+
command: "editor.setWallpaper",
|
|
100
|
+
description:
|
|
101
|
+
"Sets the canvas background to a CMS wallpaper — exactly what picking one in the UI does. Select it by `name` (from creavit_editor_wallpapers), by `category` + `index`, or with random=true. Call creavit_project_save afterwards.",
|
|
102
|
+
inputSchema: schema({
|
|
103
|
+
name: S.string("Wallpaper name, e.g. 'sonoma-dark'"),
|
|
104
|
+
category: S.string("Category to pick from, e.g. 'macos'"),
|
|
105
|
+
index: S.number("Zero-based position inside the category"),
|
|
106
|
+
random: S.bool("Pick a random wallpaper"),
|
|
107
|
+
blur: S.number("Background blur amount (optional)"),
|
|
108
|
+
}),
|
|
109
|
+
timeoutMs: 60_000,
|
|
110
|
+
mapResult: (result) =>
|
|
111
|
+
textResult({ ...result, note: "Applied. Call creavit_project_save to persist." }),
|
|
112
|
+
}),
|
|
113
|
+
|
|
84
114
|
bridgeTool({
|
|
85
115
|
name: "creavit_editor_camera_get",
|
|
86
116
|
command: "editor.getCamera",
|
|
@@ -136,7 +166,7 @@ export function editorTools() {
|
|
|
136
166
|
name: "creavit_editor_add_zoom",
|
|
137
167
|
command: "editor.addZoom",
|
|
138
168
|
description:
|
|
139
|
-
"Adds a zoom range. start/end are in seconds and end must be greater than start. scale defaults to 2 (1 means no zoom), x/y default to 0.5 (center). Get the video duration from creavit_editor_state.",
|
|
169
|
+
"Adds a zoom range MANUALLY. Do NOT use this to 'zoom on the clicks' after a recording — Creavit Studio records the real mouse clicks and builds its own auto-zoom segments in the editor, and hand-added ranges land on estimated times instead. Only call it when the user explicitly asks for a zoom at a specific moment. start/end are in seconds and end must be greater than start. scale defaults to 2 (1 means no zoom), x/y default to 0.5 (center). Get the video duration from creavit_editor_state.",
|
|
140
170
|
inputSchema: schema(
|
|
141
171
|
{
|
|
142
172
|
start: S.number("Start time in seconds"),
|
|
@@ -284,7 +314,7 @@ export function editorTools() {
|
|
|
284
314
|
name: "creavit_editor_export",
|
|
285
315
|
command: "editor.export",
|
|
286
316
|
description:
|
|
287
|
-
"Exports the video. This takes a LONG time (minutes). Follow progress with creavit_events (export.started / export.finished / export.failed)
|
|
317
|
+
"Exports the video idempotently; concurrent retries share one render. This takes a LONG time (minutes). Follow progress with creavit_events (export.started / export.finished / export.failed), then use creavit_file_open when the user asks to open/play it. If filePath is omitted, the export is written beside the open .crvt project.",
|
|
288
318
|
inputSchema: schema({
|
|
289
319
|
filePath: S.string("Target file path (.mp4)"),
|
|
290
320
|
format: S.string("mp4 or gif", { enum: ["mp4", "gif"] }),
|
|
@@ -295,6 +325,22 @@ export function editorTools() {
|
|
|
295
325
|
timeoutMs: 3_600_000,
|
|
296
326
|
}),
|
|
297
327
|
|
|
328
|
+
bridgeTool({
|
|
329
|
+
name: "creavit_editor_export_start",
|
|
330
|
+
command: "editor.export.start",
|
|
331
|
+
description:
|
|
332
|
+
"Starts one export in the background and returns immediately. Use this when tool latency matters. Progress/completion is reported by creavit_events; set openWhenFinished=true to open/play the result automatically without showing export UI.",
|
|
333
|
+
inputSchema: schema({
|
|
334
|
+
filePath: S.string("Target file path (.mp4); omit to export beside the project"),
|
|
335
|
+
format: S.string("mp4 or gif", { enum: ["mp4", "gif"] }),
|
|
336
|
+
resolution: S.string("e.g. 720p, 1080p, 4k"),
|
|
337
|
+
fps: S.number("Frame rate, e.g. 30 or 60"),
|
|
338
|
+
quality: S.string("compact | high | max"),
|
|
339
|
+
openWhenFinished: S.bool("Open the exported file automatically when rendering completes"),
|
|
340
|
+
}),
|
|
341
|
+
timeoutMs: 30_000,
|
|
342
|
+
}),
|
|
343
|
+
|
|
298
344
|
{
|
|
299
345
|
name: "creavit_editor_history",
|
|
300
346
|
description: "Undoes the last editor change, or redoes it.",
|
|
@@ -71,6 +71,14 @@ export function projectTools() {
|
|
|
71
71
|
inputSchema: schema({ filePath: S.string("Absolute path to the file") }, ["filePath"]),
|
|
72
72
|
}),
|
|
73
73
|
|
|
74
|
+
bridgeTool({
|
|
75
|
+
name: "creavit_file_open",
|
|
76
|
+
command: "project.openFile",
|
|
77
|
+
description:
|
|
78
|
+
"Opens an existing exported video or other file with its default macOS application. Use this after creavit_editor_export when the user asks to open/play the result.",
|
|
79
|
+
inputSchema: schema({ filePath: S.string("Absolute path to the file") }, ["filePath"]),
|
|
80
|
+
}),
|
|
81
|
+
|
|
74
82
|
bridgeTool({
|
|
75
83
|
name: "creavit_project_save",
|
|
76
84
|
command: "editor.saveProject",
|
|
@@ -74,7 +74,7 @@ export function systemTools() {
|
|
|
74
74
|
name: "creavit_recording_start",
|
|
75
75
|
command: "recording.start",
|
|
76
76
|
description:
|
|
77
|
-
"Starts a screen recording. Get source IDs from creavit_devices_list first.
|
|
77
|
+
"Starts a screen recording idempotently: retries while starting share the same native operation, and calling it while active does not restart. Get source IDs from creavit_devices_list first. For a multi-step website recording, use ONE creavit_record_url_walkthrough call instead of this manual tool.",
|
|
78
78
|
inputSchema: schema({
|
|
79
79
|
options: S.object(
|
|
80
80
|
"Recording options: {sourceType:'display'|'window'|'area', sourceId, cameraEnabled, micEnabled, systemAudioEnabled, delayMs, area:{x,y,width,height}}. cameraEnabled:false also turns the camera off and hides its window, so it does not appear in a screen recording; cameraEnabled:true opens and starts it.",
|
|
@@ -88,7 +88,7 @@ export function systemTools() {
|
|
|
88
88
|
name: "creavit_recording_stop",
|
|
89
89
|
command: "recording.stop",
|
|
90
90
|
description:
|
|
91
|
-
"Stops the recording. Processing can take a few minutes; the editor opens automatically when it finishes. Track progress with creavit_events (watch for recording.stopped and project.loaded).",
|
|
91
|
+
"Stops the recording idempotently. Processing can take a few minutes; concurrent retries share the same operation and the editor opens automatically when it finishes. Track progress with creavit_events (watch for recording.stopped and project.loaded).",
|
|
92
92
|
inputSchema: schema(),
|
|
93
93
|
timeoutMs: 600_000,
|
|
94
94
|
}),
|