@synthetic-ai/premiere-mcp 2.2.0 → 2.3.0-dev.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +135 -135
  2. package/LICENSE +21 -21
  3. package/README.md +242 -242
  4. package/cep-plugin/.debug +8 -8
  5. package/cep-plugin/CSInterface.js +92 -92
  6. package/cep-plugin/host.jsx +7 -7
  7. package/cep-plugin/index.html +472 -472
  8. package/cep-plugin/main.js +6 -0
  9. package/cep-plugin/premiere.jsx +24947 -24947
  10. package/dist/bridge/script-builder.js +378 -378
  11. package/dist/license.js +38 -0
  12. package/dist/server.js +60 -60
  13. package/dist/tools/advanced.js +357 -357
  14. package/dist/tools/audio-advanced.js +1049 -1049
  15. package/dist/tools/audio.js +42 -42
  16. package/dist/tools/captions.js +27 -27
  17. package/dist/tools/clipboard.js +214 -214
  18. package/dist/tools/color-advanced.js +253 -253
  19. package/dist/tools/discovery.js +291 -291
  20. package/dist/tools/effects.js +285 -285
  21. package/dist/tools/export-presets.js +206 -206
  22. package/dist/tools/export.js +255 -255
  23. package/dist/tools/health.js +10 -10
  24. package/dist/tools/inspection.js +885 -885
  25. package/dist/tools/keyframes.js +369 -369
  26. package/dist/tools/markers.js +89 -89
  27. package/dist/tools/media.js +178 -178
  28. package/dist/tools/metadata.js +94 -94
  29. package/dist/tools/multicam.js +50 -50
  30. package/dist/tools/playback.js +15 -15
  31. package/dist/tools/playhead.js +95 -95
  32. package/dist/tools/project-manager.js +21 -21
  33. package/dist/tools/project.js +149 -149
  34. package/dist/tools/scripting.js +319 -319
  35. package/dist/tools/selection.js +202 -202
  36. package/dist/tools/sequence-advanced.js +379 -379
  37. package/dist/tools/sequence-settings.js +564 -564
  38. package/dist/tools/sequence.js +167 -167
  39. package/dist/tools/source-monitor.js +68 -68
  40. package/dist/tools/text.js +58 -58
  41. package/dist/tools/timeline.js +312 -312
  42. package/dist/tools/track-management.js +446 -446
  43. package/dist/tools/track-targeting.js +635 -635
  44. package/dist/tools/tracks.js +87 -87
  45. package/dist/tools/transitions-motion.js +174 -174
  46. package/dist/tools/transitions.js +111 -111
  47. package/dist/tools/utility.js +606 -606
  48. package/dist/tools/workspace.js +29 -29
  49. package/package.json +66 -66
  50. package/scripts/build-chat-dmg.sh +210 -210
  51. package/scripts/build-chat-zip.sh +291 -291
  52. package/scripts/install-cep-windows.ps1 +99 -99
  53. package/scripts/install-cep.sh +66 -66
  54. package/scripts/install-chat-plugin.bat +67 -67
  55. package/scripts/install-chat-plugin.sh +85 -85
  56. package/scripts/install-windows.bat +95 -95
  57. package/scripts/package.mjs +254 -254
@@ -15,24 +15,24 @@ export function getAdvancedTools(bridgeOptions) {
15
15
  required: ["node_id"],
16
16
  },
17
17
  handler: async (args) => {
18
- const script = buildToolScript(`
19
- app.enableQE();
20
- var qeSeq = qe.project.getActiveSequence();
21
- if (!qeSeq) return __error("No active sequence (QE)");
22
-
23
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
24
- if (!result) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
25
-
26
- var qeTrack = result.trackType === "video"
27
- ? qeSeq.getVideoTrackAt(result.trackIndex)
28
- : qeSeq.getAudioTrackAt(result.trackIndex);
29
- if (!qeTrack) return __error("QE track not found");
30
-
31
- var qeClip = qeTrack.getItemAt(result.clipIndex);
32
- if (!qeClip) return __error("QE clip not found");
33
-
34
- qeClip.rippleDelete();
35
- return __result({ rippleDeleted: true, clipName: result.clip.name });
18
+ const script = buildToolScript(`
19
+ app.enableQE();
20
+ var qeSeq = qe.project.getActiveSequence();
21
+ if (!qeSeq) return __error("No active sequence (QE)");
22
+
23
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
24
+ if (!result) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
25
+
26
+ var qeTrack = result.trackType === "video"
27
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
28
+ : qeSeq.getAudioTrackAt(result.trackIndex);
29
+ if (!qeTrack) return __error("QE track not found");
30
+
31
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
32
+ if (!qeClip) return __error("QE clip not found");
33
+
34
+ qeClip.rippleDelete();
35
+ return __result({ rippleDeleted: true, clipName: result.clip.name });
36
36
  `);
37
37
  return sendCommand(script, bridgeOptions);
38
38
  },
@@ -54,23 +54,23 @@ export function getAdvancedTools(bridgeOptions) {
54
54
  required: ["node_id", "offset_seconds"],
55
55
  },
56
56
  handler: async (args) => {
57
- const script = buildToolScript(`
58
- app.enableQE();
59
- var qeSeq = qe.project.getActiveSequence();
60
- if (!qeSeq) return __error("No active sequence (QE)");
61
-
62
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
63
- if (!result) return __error("Clip not found");
64
-
65
- var qeTrack = result.trackType === "video"
66
- ? qeSeq.getVideoTrackAt(result.trackIndex)
67
- : qeSeq.getAudioTrackAt(result.trackIndex);
68
- var qeClip = qeTrack.getItemAt(result.clipIndex);
69
- if (!qeClip) return __error("QE clip not found");
70
-
71
- var offsetTicks = __secondsToTicks(${args.offset_seconds}).toString();
72
- qeClip.roll(offsetTicks);
73
- return __result({ rolled: true, clipName: result.clip.name, offsetSeconds: ${args.offset_seconds} });
57
+ const script = buildToolScript(`
58
+ app.enableQE();
59
+ var qeSeq = qe.project.getActiveSequence();
60
+ if (!qeSeq) return __error("No active sequence (QE)");
61
+
62
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
63
+ if (!result) return __error("Clip not found");
64
+
65
+ var qeTrack = result.trackType === "video"
66
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
67
+ : qeSeq.getAudioTrackAt(result.trackIndex);
68
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
69
+ if (!qeClip) return __error("QE clip not found");
70
+
71
+ var offsetTicks = __secondsToTicks(${args.offset_seconds}).toString();
72
+ qeClip.roll(offsetTicks);
73
+ return __result({ rolled: true, clipName: result.clip.name, offsetSeconds: ${args.offset_seconds} });
74
74
  `);
75
75
  return sendCommand(script, bridgeOptions);
76
76
  },
@@ -92,23 +92,23 @@ export function getAdvancedTools(bridgeOptions) {
92
92
  required: ["node_id", "offset_seconds"],
93
93
  },
94
94
  handler: async (args) => {
95
- const script = buildToolScript(`
96
- app.enableQE();
97
- var qeSeq = qe.project.getActiveSequence();
98
- if (!qeSeq) return __error("No active sequence (QE)");
99
-
100
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
101
- if (!result) return __error("Clip not found");
102
-
103
- var qeTrack = result.trackType === "video"
104
- ? qeSeq.getVideoTrackAt(result.trackIndex)
105
- : qeSeq.getAudioTrackAt(result.trackIndex);
106
- var qeClip = qeTrack.getItemAt(result.clipIndex);
107
- if (!qeClip) return __error("QE clip not found");
108
-
109
- var offsetTicks = __secondsToTicks(${args.offset_seconds}).toString();
110
- qeClip.slide(offsetTicks);
111
- return __result({ slid: true, clipName: result.clip.name, offsetSeconds: ${args.offset_seconds} });
95
+ const script = buildToolScript(`
96
+ app.enableQE();
97
+ var qeSeq = qe.project.getActiveSequence();
98
+ if (!qeSeq) return __error("No active sequence (QE)");
99
+
100
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
101
+ if (!result) return __error("Clip not found");
102
+
103
+ var qeTrack = result.trackType === "video"
104
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
105
+ : qeSeq.getAudioTrackAt(result.trackIndex);
106
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
107
+ if (!qeClip) return __error("QE clip not found");
108
+
109
+ var offsetTicks = __secondsToTicks(${args.offset_seconds}).toString();
110
+ qeClip.slide(offsetTicks);
111
+ return __result({ slid: true, clipName: result.clip.name, offsetSeconds: ${args.offset_seconds} });
112
112
  `);
113
113
  return sendCommand(script, bridgeOptions);
114
114
  },
@@ -130,23 +130,23 @@ export function getAdvancedTools(bridgeOptions) {
130
130
  required: ["node_id", "offset_seconds"],
131
131
  },
132
132
  handler: async (args) => {
133
- const script = buildToolScript(`
134
- app.enableQE();
135
- var qeSeq = qe.project.getActiveSequence();
136
- if (!qeSeq) return __error("No active sequence (QE)");
137
-
138
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
139
- if (!result) return __error("Clip not found");
140
-
141
- var qeTrack = result.trackType === "video"
142
- ? qeSeq.getVideoTrackAt(result.trackIndex)
143
- : qeSeq.getAudioTrackAt(result.trackIndex);
144
- var qeClip = qeTrack.getItemAt(result.clipIndex);
145
- if (!qeClip) return __error("QE clip not found");
146
-
147
- var offsetTicks = __secondsToTicks(${args.offset_seconds}).toString();
148
- qeClip.slip(offsetTicks);
149
- return __result({ slipped: true, clipName: result.clip.name, offsetSeconds: ${args.offset_seconds} });
133
+ const script = buildToolScript(`
134
+ app.enableQE();
135
+ var qeSeq = qe.project.getActiveSequence();
136
+ if (!qeSeq) return __error("No active sequence (QE)");
137
+
138
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
139
+ if (!result) return __error("Clip not found");
140
+
141
+ var qeTrack = result.trackType === "video"
142
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
143
+ : qeSeq.getAudioTrackAt(result.trackIndex);
144
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
145
+ if (!qeClip) return __error("QE clip not found");
146
+
147
+ var offsetTicks = __secondsToTicks(${args.offset_seconds}).toString();
148
+ qeClip.slip(offsetTicks);
149
+ return __result({ slipped: true, clipName: result.clip.name, offsetSeconds: ${args.offset_seconds} });
150
150
  `);
151
151
  return sendCommand(script, bridgeOptions);
152
152
  },
@@ -168,22 +168,22 @@ export function getAdvancedTools(bridgeOptions) {
168
168
  required: ["node_id", "target_track_index"],
169
169
  },
170
170
  handler: async (args) => {
171
- const script = buildToolScript(`
172
- app.enableQE();
173
- var qeSeq = qe.project.getActiveSequence();
174
- if (!qeSeq) return __error("No active sequence (QE)");
175
-
176
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
177
- if (!result) return __error("Clip not found");
178
-
179
- var qeTrack = result.trackType === "video"
180
- ? qeSeq.getVideoTrackAt(result.trackIndex)
181
- : qeSeq.getAudioTrackAt(result.trackIndex);
182
- var qeClip = qeTrack.getItemAt(result.clipIndex);
183
- if (!qeClip) return __error("QE clip not found");
184
-
185
- qeClip.moveToTrack(${args.target_track_index});
186
- return __result({ moved: true, clipName: result.clip.name, newTrackIndex: ${args.target_track_index} });
171
+ const script = buildToolScript(`
172
+ app.enableQE();
173
+ var qeSeq = qe.project.getActiveSequence();
174
+ if (!qeSeq) return __error("No active sequence (QE)");
175
+
176
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
177
+ if (!result) return __error("Clip not found");
178
+
179
+ var qeTrack = result.trackType === "video"
180
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
181
+ : qeSeq.getAudioTrackAt(result.trackIndex);
182
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
183
+ if (!qeClip) return __error("QE clip not found");
184
+
185
+ qeClip.moveToTrack(${args.target_track_index});
186
+ return __result({ moved: true, clipName: result.clip.name, newTrackIndex: ${args.target_track_index} });
187
187
  `);
188
188
  return sendCommand(script, bridgeOptions);
189
189
  },
@@ -201,22 +201,22 @@ export function getAdvancedTools(bridgeOptions) {
201
201
  required: ["node_id"],
202
202
  },
203
203
  handler: async (args) => {
204
- const script = buildToolScript(`
205
- app.enableQE();
206
- var qeSeq = qe.project.getActiveSequence();
207
- if (!qeSeq) return __error("No active sequence (QE)");
208
-
209
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
210
- if (!result) return __error("Clip not found");
211
-
212
- var qeTrack = result.trackType === "video"
213
- ? qeSeq.getVideoTrackAt(result.trackIndex)
214
- : qeSeq.getAudioTrackAt(result.trackIndex);
215
- var qeClip = qeTrack.getItemAt(result.clipIndex);
216
- if (!qeClip) return __error("QE clip not found");
217
-
218
- qeClip.removeEffects();
219
- return __result({ removed: true, clipName: result.clip.name });
204
+ const script = buildToolScript(`
205
+ app.enableQE();
206
+ var qeSeq = qe.project.getActiveSequence();
207
+ if (!qeSeq) return __error("No active sequence (QE)");
208
+
209
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
210
+ if (!result) return __error("Clip not found");
211
+
212
+ var qeTrack = result.trackType === "video"
213
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
214
+ : qeSeq.getAudioTrackAt(result.trackIndex);
215
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
216
+ if (!qeClip) return __error("QE clip not found");
217
+
218
+ qeClip.removeEffects();
219
+ return __result({ removed: true, clipName: result.clip.name });
220
220
  `);
221
221
  return sendCommand(script, bridgeOptions);
222
222
  },
@@ -242,29 +242,29 @@ export function getAdvancedTools(bridgeOptions) {
242
242
  required: ["node_id", "speed_percent"],
243
243
  },
244
244
  handler: async (args) => {
245
- const script = buildToolScript(`
246
- app.enableQE();
247
- var qeSeq = qe.project.getActiveSequence();
248
- if (!qeSeq) return __error("No active sequence (QE)");
249
-
250
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
251
- if (!result) return __error("Clip not found");
252
-
253
- var qeTrack = result.trackType === "video"
254
- ? qeSeq.getVideoTrackAt(result.trackIndex)
255
- : qeSeq.getAudioTrackAt(result.trackIndex);
256
- var qeClip = qeTrack.getItemAt(result.clipIndex);
257
- if (!qeClip) return __error("QE clip not found");
258
-
259
- qeClip.setSpeed(${args.speed_percent});
260
- ${args.reverse ? `qeClip.setReverse(true);` : ""}
261
-
262
- return __result({
263
- speedSet: true,
264
- clipName: result.clip.name,
265
- speed: ${args.speed_percent},
266
- reverse: ${!!args.reverse}
267
- });
245
+ const script = buildToolScript(`
246
+ app.enableQE();
247
+ var qeSeq = qe.project.getActiveSequence();
248
+ if (!qeSeq) return __error("No active sequence (QE)");
249
+
250
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
251
+ if (!result) return __error("Clip not found");
252
+
253
+ var qeTrack = result.trackType === "video"
254
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
255
+ : qeSeq.getAudioTrackAt(result.trackIndex);
256
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
257
+ if (!qeClip) return __error("QE clip not found");
258
+
259
+ qeClip.setSpeed(${args.speed_percent});
260
+ ${args.reverse ? `qeClip.setReverse(true);` : ""}
261
+
262
+ return __result({
263
+ speedSet: true,
264
+ clipName: result.clip.name,
265
+ speed: ${args.speed_percent},
266
+ reverse: ${!!args.reverse}
267
+ });
268
268
  `);
269
269
  return sendCommand(script, bridgeOptions);
270
270
  },
@@ -287,22 +287,22 @@ export function getAdvancedTools(bridgeOptions) {
287
287
  },
288
288
  handler: async (args) => {
289
289
  const rev = args.reverse !== false;
290
- const script = buildToolScript(`
291
- app.enableQE();
292
- var qeSeq = qe.project.getActiveSequence();
293
- if (!qeSeq) return __error("No active sequence (QE)");
294
-
295
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
296
- if (!result) return __error("Clip not found");
297
-
298
- var qeTrack = result.trackType === "video"
299
- ? qeSeq.getVideoTrackAt(result.trackIndex)
300
- : qeSeq.getAudioTrackAt(result.trackIndex);
301
- var qeClip = qeTrack.getItemAt(result.clipIndex);
302
- if (!qeClip) return __error("QE clip not found");
303
-
304
- qeClip.setReverse(${rev});
305
- return __result({ reversed: ${rev}, clipName: result.clip.name });
290
+ const script = buildToolScript(`
291
+ app.enableQE();
292
+ var qeSeq = qe.project.getActiveSequence();
293
+ if (!qeSeq) return __error("No active sequence (QE)");
294
+
295
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
296
+ if (!result) return __error("Clip not found");
297
+
298
+ var qeTrack = result.trackType === "video"
299
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
300
+ : qeSeq.getAudioTrackAt(result.trackIndex);
301
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
302
+ if (!qeClip) return __error("QE clip not found");
303
+
304
+ qeClip.setReverse(${rev});
305
+ return __result({ reversed: ${rev}, clipName: result.clip.name });
306
306
  `);
307
307
  return sendCommand(script, bridgeOptions);
308
308
  },
@@ -324,22 +324,22 @@ export function getAdvancedTools(bridgeOptions) {
324
324
  required: ["node_id", "enabled"],
325
325
  },
326
326
  handler: async (args) => {
327
- const script = buildToolScript(`
328
- app.enableQE();
329
- var qeSeq = qe.project.getActiveSequence();
330
- if (!qeSeq) return __error("No active sequence (QE)");
331
-
332
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
333
- if (!result) return __error("Clip not found");
334
-
335
- var qeTrack = result.trackType === "video"
336
- ? qeSeq.getVideoTrackAt(result.trackIndex)
337
- : qeSeq.getAudioTrackAt(result.trackIndex);
338
- var qeClip = qeTrack.getItemAt(result.clipIndex);
339
- if (!qeClip) return __error("QE clip not found");
340
-
341
- qeClip.setFrameBlend(${args.enabled});
342
- return __result({ frameBlend: ${args.enabled}, clipName: result.clip.name });
327
+ const script = buildToolScript(`
328
+ app.enableQE();
329
+ var qeSeq = qe.project.getActiveSequence();
330
+ if (!qeSeq) return __error("No active sequence (QE)");
331
+
332
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
333
+ if (!result) return __error("Clip not found");
334
+
335
+ var qeTrack = result.trackType === "video"
336
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
337
+ : qeSeq.getAudioTrackAt(result.trackIndex);
338
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
339
+ if (!qeClip) return __error("QE clip not found");
340
+
341
+ qeClip.setFrameBlend(${args.enabled});
342
+ return __result({ frameBlend: ${args.enabled}, clipName: result.clip.name });
343
343
  `);
344
344
  return sendCommand(script, bridgeOptions);
345
345
  },
@@ -361,27 +361,27 @@ export function getAdvancedTools(bridgeOptions) {
361
361
  required: ["node_id", "interpolation_type"],
362
362
  },
363
363
  handler: async (args) => {
364
- const script = buildToolScript(`
365
- app.enableQE();
366
- var qeSeq = qe.project.getActiveSequence();
367
- if (!qeSeq) return __error("No active sequence (QE)");
368
-
369
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
370
- if (!result) return __error("Clip not found");
371
-
372
- var qeTrack = result.trackType === "video"
373
- ? qeSeq.getVideoTrackAt(result.trackIndex)
374
- : qeSeq.getAudioTrackAt(result.trackIndex);
375
- var qeClip = qeTrack.getItemAt(result.clipIndex);
376
- if (!qeClip) return __error("QE clip not found");
377
-
378
- qeClip.setTimeInterpolationType(${args.interpolation_type});
379
- var typeNames = ["Frame Sampling", "Frame Blending", "Optical Flow"];
380
- return __result({
381
- set: true,
382
- clipName: result.clip.name,
383
- interpolationType: typeNames[${args.interpolation_type}] || "Unknown"
384
- });
364
+ const script = buildToolScript(`
365
+ app.enableQE();
366
+ var qeSeq = qe.project.getActiveSequence();
367
+ if (!qeSeq) return __error("No active sequence (QE)");
368
+
369
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
370
+ if (!result) return __error("Clip not found");
371
+
372
+ var qeTrack = result.trackType === "video"
373
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
374
+ : qeSeq.getAudioTrackAt(result.trackIndex);
375
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
376
+ if (!qeClip) return __error("QE clip not found");
377
+
378
+ qeClip.setTimeInterpolationType(${args.interpolation_type});
379
+ var typeNames = ["Frame Sampling", "Frame Blending", "Optical Flow"];
380
+ return __result({
381
+ set: true,
382
+ clipName: result.clip.name,
383
+ interpolationType: typeNames[${args.interpolation_type}] || "Unknown"
384
+ });
385
385
  `);
386
386
  return sendCommand(script, bridgeOptions);
387
387
  },
@@ -403,23 +403,23 @@ export function getAdvancedTools(bridgeOptions) {
403
403
  required: ["node_id", "new_name"],
404
404
  },
405
405
  handler: async (args) => {
406
- const script = buildToolScript(`
407
- app.enableQE();
408
- var qeSeq = qe.project.getActiveSequence();
409
- if (!qeSeq) return __error("No active sequence (QE)");
410
-
411
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
412
- if (!result) return __error("Clip not found");
413
-
414
- var qeTrack = result.trackType === "video"
415
- ? qeSeq.getVideoTrackAt(result.trackIndex)
416
- : qeSeq.getAudioTrackAt(result.trackIndex);
417
- var qeClip = qeTrack.getItemAt(result.clipIndex);
418
- if (!qeClip) return __error("QE clip not found");
419
-
420
- var oldName = result.clip.name;
421
- qeClip.setName("${escapeForExtendScript(args.new_name)}");
422
- return __result({ renamed: true, oldName: oldName, newName: "${escapeForExtendScript(args.new_name)}" });
406
+ const script = buildToolScript(`
407
+ app.enableQE();
408
+ var qeSeq = qe.project.getActiveSequence();
409
+ if (!qeSeq) return __error("No active sequence (QE)");
410
+
411
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
412
+ if (!result) return __error("Clip not found");
413
+
414
+ var qeTrack = result.trackType === "video"
415
+ ? qeSeq.getVideoTrackAt(result.trackIndex)
416
+ : qeSeq.getAudioTrackAt(result.trackIndex);
417
+ var qeClip = qeTrack.getItemAt(result.clipIndex);
418
+ if (!qeClip) return __error("QE clip not found");
419
+
420
+ var oldName = result.clip.name;
421
+ qeClip.setName("${escapeForExtendScript(args.new_name)}");
422
+ return __result({ renamed: true, oldName: oldName, newName: "${escapeForExtendScript(args.new_name)}" });
423
423
  `);
424
424
  return sendCommand(script, bridgeOptions);
425
425
  },
@@ -437,21 +437,21 @@ export function getAdvancedTools(bridgeOptions) {
437
437
  required: ["node_id"],
438
438
  },
439
439
  handler: async (args) => {
440
- const script = buildToolScript(`
441
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
442
- if (!result) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
443
-
444
- var clip = result.clip;
445
- var speed = 1;
446
- var reversed = false;
447
- try { speed = clip.getSpeed(); } catch(e) {}
448
- try { reversed = clip.isSpeedReversed() == 1; } catch(e) {}
449
-
450
- return __result({
451
- clipName: clip.name,
452
- speed: speed,
453
- reversed: reversed
454
- });
440
+ const script = buildToolScript(`
441
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
442
+ if (!result) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
443
+
444
+ var clip = result.clip;
445
+ var speed = 1;
446
+ var reversed = false;
447
+ try { speed = clip.getSpeed(); } catch(e) {}
448
+ try { reversed = clip.isSpeedReversed() == 1; } catch(e) {}
449
+
450
+ return __result({
451
+ clipName: clip.name,
452
+ speed: speed,
453
+ reversed: reversed
454
+ });
455
455
  `);
456
456
  return sendCommand(script, bridgeOptions);
457
457
  },
@@ -473,12 +473,12 @@ export function getAdvancedTools(bridgeOptions) {
473
473
  required: ["node_id", "selected"],
474
474
  },
475
475
  handler: async (args) => {
476
- const script = buildToolScript(`
477
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
478
- if (!result) return __error("Clip not found");
479
-
480
- result.clip.setSelected(${args.selected ? 1 : 0}, true);
481
- return __result({ selected: ${args.selected}, clipName: result.clip.name });
476
+ const script = buildToolScript(`
477
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
478
+ if (!result) return __error("Clip not found");
479
+
480
+ result.clip.setSelected(${args.selected ? 1 : 0}, true);
481
+ return __result({ selected: ${args.selected}, clipName: result.clip.name });
482
482
  `);
483
483
  return sendCommand(script, bridgeOptions);
484
484
  },
@@ -487,11 +487,11 @@ export function getAdvancedTools(bridgeOptions) {
487
487
  description: "Link the currently selected video and audio clips in the active sequence",
488
488
  parameters: {},
489
489
  handler: async () => {
490
- const script = buildToolScript(`
491
- var seq = app.project.activeSequence;
492
- if (!seq) return __error("No active sequence");
493
- seq.linkSelection();
494
- return __result({ linked: true });
490
+ const script = buildToolScript(`
491
+ var seq = app.project.activeSequence;
492
+ if (!seq) return __error("No active sequence");
493
+ seq.linkSelection();
494
+ return __result({ linked: true });
495
495
  `);
496
496
  return sendCommand(script, bridgeOptions);
497
497
  },
@@ -500,11 +500,11 @@ export function getAdvancedTools(bridgeOptions) {
500
500
  description: "Unlink the currently selected video and audio clips in the active sequence",
501
501
  parameters: {},
502
502
  handler: async () => {
503
- const script = buildToolScript(`
504
- var seq = app.project.activeSequence;
505
- if (!seq) return __error("No active sequence");
506
- seq.unlinkSelection();
507
- return __result({ unlinked: true });
503
+ const script = buildToolScript(`
504
+ var seq = app.project.activeSequence;
505
+ if (!seq) return __error("No active sequence");
506
+ seq.unlinkSelection();
507
+ return __result({ unlinked: true });
508
508
  `);
509
509
  return sendCommand(script, bridgeOptions);
510
510
  },
@@ -537,22 +537,22 @@ export function getAdvancedTools(bridgeOptions) {
537
537
  const startSeconds = args.start_seconds ?? 0;
538
538
  const trackIndex = args.track_index ?? 0;
539
539
  const audioTrackIndex = args.audio_track_index ?? 0;
540
- const script = buildToolScript(`
541
- var seq = app.project.activeSequence;
542
- if (!seq) return __error("No active sequence");
543
-
544
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
545
- if (!item) return __error("Project item not found: ${escapeForExtendScript(args.item_id)}");
546
-
547
- var startTicks = __secondsToTicks(${startSeconds}).toString();
548
- seq.overwriteClip(item, startTicks, ${trackIndex}, ${audioTrackIndex});
549
-
550
- return __result({
551
- overwritten: true,
552
- item: item.name,
553
- trackIndex: ${trackIndex},
554
- startSeconds: ${startSeconds}
555
- });
540
+ const script = buildToolScript(`
541
+ var seq = app.project.activeSequence;
542
+ if (!seq) return __error("No active sequence");
543
+
544
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
545
+ if (!item) return __error("Project item not found: ${escapeForExtendScript(args.item_id)}");
546
+
547
+ var startTicks = __secondsToTicks(${startSeconds}).toString();
548
+ seq.overwriteClip(item, startTicks, ${trackIndex}, ${audioTrackIndex});
549
+
550
+ return __result({
551
+ overwritten: true,
552
+ item: item.name,
553
+ trackIndex: ${trackIndex},
554
+ startSeconds: ${startSeconds}
555
+ });
556
556
  `);
557
557
  return sendCommand(script, bridgeOptions);
558
558
  },
@@ -577,14 +577,14 @@ export function getAdvancedTools(bridgeOptions) {
577
577
  const itemLookups = args.item_ids
578
578
  .map((id, i) => `var item${i} = __findProjectItem("${escapeForExtendScript(id)}"); if (!item${i}) return __error("Item not found: ${escapeForExtendScript(id)}"); items.push(item${i});`)
579
579
  .join("\n ");
580
- const script = buildToolScript(`
581
- var items = [];
582
- ${itemLookups}
583
-
584
- // PP 2026: pass rootItem as third argument (required for correct bin placement)
585
- var seq = app.project.createNewSequenceFromClips("${escapeForExtendScript(args.name)}", items, app.project.rootItem);
586
- if (!seq) return __error("Failed to create sequence from clips");
587
- return __result({ created: true, name: seq.name, id: seq.sequenceID, clipCount: items.length });
580
+ const script = buildToolScript(`
581
+ var items = [];
582
+ ${itemLookups}
583
+
584
+ // PP 2026: pass rootItem as third argument (required for correct bin placement)
585
+ var seq = app.project.createNewSequenceFromClips("${escapeForExtendScript(args.name)}", items, app.project.rootItem);
586
+ if (!seq) return __error("Failed to create sequence from clips");
587
+ return __result({ created: true, name: seq.name, id: seq.sequenceID, clipCount: items.length });
588
588
  `);
589
589
  return sendCommand(script, bridgeOptions);
590
590
  },
@@ -604,11 +604,11 @@ export function getAdvancedTools(bridgeOptions) {
604
604
  const seqLookup = args.sequence_id
605
605
  ? `var seq = __findSequence("${escapeForExtendScript(args.sequence_id)}"); if (!seq) return __error("Sequence not found");`
606
606
  : `var seq = app.project.activeSequence; if (!seq) return __error("No active sequence");`;
607
- const script = buildToolScript(`
608
- ${seqLookup}
609
- var name = seq.name;
610
- seq.close();
611
- return __result({ closed: true, name: name });
607
+ const script = buildToolScript(`
608
+ ${seqLookup}
609
+ var name = seq.name;
610
+ seq.close();
611
+ return __result({ closed: true, name: name });
612
612
  `);
613
613
  return sendCommand(script, bridgeOptions);
614
614
  },
@@ -633,10 +633,10 @@ export function getAdvancedTools(bridgeOptions) {
633
633
  const seqLookup = args.sequence_id
634
634
  ? `var seq = __findSequence("${escapeForExtendScript(args.sequence_id)}"); if (!seq) return __error("Sequence not found");`
635
635
  : `var seq = app.project.activeSequence; if (!seq) return __error("No active sequence");`;
636
- const script = buildToolScript(`
637
- ${seqLookup}
638
- seq.exportAsProject("${escapeForExtendScript(args.output_path)}");
639
- return __result({ exported: true, path: "${escapeForExtendScript(args.output_path)}" });
636
+ const script = buildToolScript(`
637
+ ${seqLookup}
638
+ seq.exportAsProject("${escapeForExtendScript(args.output_path)}");
639
+ return __result({ exported: true, path: "${escapeForExtendScript(args.output_path)}" });
640
640
  `);
641
641
  return sendCommand(script, bridgeOptions);
642
642
  },
@@ -661,11 +661,11 @@ export function getAdvancedTools(bridgeOptions) {
661
661
  const seqLookup = args.sequence_id
662
662
  ? `var seq = __findSequence("${escapeForExtendScript(args.sequence_id)}"); if (!seq) return __error("Sequence not found");`
663
663
  : `var seq = app.project.activeSequence; if (!seq) return __error("No active sequence");`;
664
- const script = buildToolScript(`
665
- ${seqLookup}
666
- var ticks = __secondsToTicks(${args.start_seconds}).toString();
667
- seq.setZeroPoint(ticks);
668
- return __result({ set: true, startSeconds: ${args.start_seconds} });
664
+ const script = buildToolScript(`
665
+ ${seqLookup}
666
+ var ticks = __secondsToTicks(${args.start_seconds}).toString();
667
+ seq.setZeroPoint(ticks);
668
+ return __result({ set: true, startSeconds: ${args.start_seconds} });
669
669
  `);
670
670
  return sendCommand(script, bridgeOptions);
671
671
  },
@@ -674,11 +674,11 @@ export function getAdvancedTools(bridgeOptions) {
674
674
  description: "Perform scene edit detection on the selected clips in the active sequence",
675
675
  parameters: {},
676
676
  handler: async () => {
677
- const script = buildToolScript(`
678
- var seq = app.project.activeSequence;
679
- if (!seq) return __error("No active sequence");
680
- seq.performSceneEditDetectionOnSelection();
681
- return __result({ sceneDetection: true });
677
+ const script = buildToolScript(`
678
+ var seq = app.project.activeSequence;
679
+ if (!seq) return __error("No active sequence");
680
+ seq.performSceneEditDetectionOnSelection();
681
+ return __result({ sceneDetection: true });
682
682
  `);
683
683
  return sendCommand(script, bridgeOptions);
684
684
  },
@@ -701,10 +701,10 @@ export function getAdvancedTools(bridgeOptions) {
701
701
  all: '"FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"',
702
702
  };
703
703
  const mediaType = typeMap[args.media_type || "all"] || typeMap.all;
704
- const script = buildToolScript(`
705
- app.enableQE();
706
- qe.project.deletePreviewFiles(${mediaType});
707
- return __result({ deleted: true, mediaType: "${args.media_type || "all"}" });
704
+ const script = buildToolScript(`
705
+ app.enableQE();
706
+ qe.project.deletePreviewFiles(${mediaType});
707
+ return __result({ deleted: true, mediaType: "${args.media_type || "all"}" });
708
708
  `);
709
709
  return sendCommand(script, bridgeOptions);
710
710
  },
@@ -737,19 +737,19 @@ export function getAdvancedTools(bridgeOptions) {
737
737
  const a = args.audio_tracks ?? 0;
738
738
  const aMono = args.audio_mono_tracks ?? 0;
739
739
  const a51 = args.audio_51_tracks ?? 0;
740
- const script = buildToolScript(`
741
- app.enableQE();
742
- var qeSeq = qe.project.getActiveSequence();
743
- if (!qeSeq) return __error("No active sequence (QE)");
744
-
745
- qeSeq.addTracks(${v}, ${a}, ${aMono}, ${a51});
746
- return __result({
747
- added: true,
748
- videoTracks: ${v},
749
- audioTracks: ${a},
750
- audioMonoTracks: ${aMono},
751
- audio51Tracks: ${a51}
752
- });
740
+ const script = buildToolScript(`
741
+ app.enableQE();
742
+ var qeSeq = qe.project.getActiveSequence();
743
+ if (!qeSeq) return __error("No active sequence (QE)");
744
+
745
+ qeSeq.addTracks(${v}, ${a}, ${aMono}, ${a51});
746
+ return __result({
747
+ added: true,
748
+ videoTracks: ${v},
749
+ audioTracks: ${a},
750
+ audioMonoTracks: ${aMono},
751
+ audio51Tracks: ${a51}
752
+ });
753
753
  `);
754
754
  return sendCommand(script, bridgeOptions);
755
755
  },
@@ -791,35 +791,35 @@ export function getAdvancedTools(bridgeOptions) {
791
791
  required: ["node_id", "component_name", "property_name", "alpha", "red", "green", "blue"],
792
792
  },
793
793
  handler: async (args) => {
794
- const script = buildToolScript(`
795
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
796
- if (!result) return __error("Clip not found");
797
-
798
- var clip = result.clip;
799
- var components = clip.components;
800
- var targetComp = null;
801
- for (var i = 0; i < components.numItems; i++) {
802
- if (components[i].displayName === "${escapeForExtendScript(args.component_name)}") {
803
- targetComp = components[i];
804
- break;
805
- }
806
- }
807
- if (!targetComp) return __error("Component not found");
808
-
809
- var targetProp = null;
810
- for (var j = 0; j < targetComp.properties.numItems; j++) {
811
- if (targetComp.properties[j].displayName === "${escapeForExtendScript(args.property_name)}") {
812
- targetProp = targetComp.properties[j];
813
- break;
814
- }
815
- }
816
- if (!targetProp) return __error("Property not found");
817
-
818
- targetProp.setColorValue(${args.alpha}, ${args.red}, ${args.green}, ${args.blue}, true);
819
- return __result({
820
- set: true,
821
- color: { alpha: ${args.alpha}, red: ${args.red}, green: ${args.green}, blue: ${args.blue} }
822
- });
794
+ const script = buildToolScript(`
795
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
796
+ if (!result) return __error("Clip not found");
797
+
798
+ var clip = result.clip;
799
+ var components = clip.components;
800
+ var targetComp = null;
801
+ for (var i = 0; i < components.numItems; i++) {
802
+ if (components[i].displayName === "${escapeForExtendScript(args.component_name)}") {
803
+ targetComp = components[i];
804
+ break;
805
+ }
806
+ }
807
+ if (!targetComp) return __error("Component not found");
808
+
809
+ var targetProp = null;
810
+ for (var j = 0; j < targetComp.properties.numItems; j++) {
811
+ if (targetComp.properties[j].displayName === "${escapeForExtendScript(args.property_name)}") {
812
+ targetProp = targetComp.properties[j];
813
+ break;
814
+ }
815
+ }
816
+ if (!targetProp) return __error("Property not found");
817
+
818
+ targetProp.setColorValue(${args.alpha}, ${args.red}, ${args.green}, ${args.blue}, true);
819
+ return __result({
820
+ set: true,
821
+ color: { alpha: ${args.alpha}, red: ${args.red}, green: ${args.green}, blue: ${args.blue} }
822
+ });
823
823
  `);
824
824
  return sendCommand(script, bridgeOptions);
825
825
  },
@@ -837,15 +837,15 @@ export function getAdvancedTools(bridgeOptions) {
837
837
  required: ["node_id"],
838
838
  },
839
839
  handler: async (args) => {
840
- const script = buildToolScript(`
841
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
842
- if (!result) return __error("Clip not found");
843
-
844
- var clip = result.clip;
845
- var isAdj = false;
846
- try { isAdj = clip.isAdjustmentLayer(); } catch(e) {}
847
-
848
- return __result({ clipName: clip.name, isAdjustmentLayer: isAdj });
840
+ const script = buildToolScript(`
841
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
842
+ if (!result) return __error("Clip not found");
843
+
844
+ var clip = result.clip;
845
+ var isAdj = false;
846
+ try { isAdj = clip.isAdjustmentLayer(); } catch(e) {}
847
+
848
+ return __result({ clipName: clip.name, isAdjustmentLayer: isAdj });
849
849
  `);
850
850
  return sendCommand(script, bridgeOptions);
851
851
  },
@@ -863,23 +863,23 @@ export function getAdvancedTools(bridgeOptions) {
863
863
  required: ["node_id"],
864
864
  },
865
865
  handler: async (args) => {
866
- const script = buildToolScript(`
867
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
868
- if (!result) return __error("Clip not found");
869
-
870
- var linked = result.clip.getLinkedItems();
871
- var items = [];
872
- if (linked) {
873
- for (var i = 0; i < linked.numItems; i++) {
874
- items.push({
875
- name: linked[i].name,
876
- nodeId: linked[i].nodeId,
877
- startSeconds: __ticksToSeconds(linked[i].start.ticks)
878
- });
879
- }
880
- }
881
-
882
- return __result({ clipName: result.clip.name, linkedItems: items, count: items.length });
866
+ const script = buildToolScript(`
867
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
868
+ if (!result) return __error("Clip not found");
869
+
870
+ var linked = result.clip.getLinkedItems();
871
+ var items = [];
872
+ if (linked) {
873
+ for (var i = 0; i < linked.numItems; i++) {
874
+ items.push({
875
+ name: linked[i].name,
876
+ nodeId: linked[i].nodeId,
877
+ startSeconds: __ticksToSeconds(linked[i].start.ticks)
878
+ });
879
+ }
880
+ }
881
+
882
+ return __result({ clipName: result.clip.name, linkedItems: items, count: items.length });
883
883
  `);
884
884
  return sendCommand(script, bridgeOptions);
885
885
  },
@@ -897,23 +897,23 @@ export function getAdvancedTools(bridgeOptions) {
897
897
  required: ["node_id"],
898
898
  },
899
899
  handler: async (args) => {
900
- const script = buildToolScript(`
901
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
902
- if (!result) return __error("Clip not found");
903
-
904
- var mgtComp = result.clip.getMGTComponent();
905
- if (!mgtComp) return __error("Not a MOGRT clip or no MGT component found");
906
-
907
- var params = [];
908
- for (var i = 0; i < mgtComp.properties.numItems; i++) {
909
- var p = mgtComp.properties[i];
910
- params.push({
911
- displayName: p.displayName,
912
- value: p.getValue()
913
- });
914
- }
915
-
916
- return __result({ clipName: result.clip.name, parameters: params });
900
+ const script = buildToolScript(`
901
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
902
+ if (!result) return __error("Clip not found");
903
+
904
+ var mgtComp = result.clip.getMGTComponent();
905
+ if (!mgtComp) return __error("Not a MOGRT clip or no MGT component found");
906
+
907
+ var params = [];
908
+ for (var i = 0; i < mgtComp.properties.numItems; i++) {
909
+ var p = mgtComp.properties[i];
910
+ params.push({
911
+ displayName: p.displayName,
912
+ value: p.getValue()
913
+ });
914
+ }
915
+
916
+ return __result({ clipName: result.clip.name, parameters: params });
917
917
  `);
918
918
  return sendCommand(script, bridgeOptions);
919
919
  },