@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
@@ -19,43 +19,43 @@ export function getKeyframeTools(bridgeOptions) {
19
19
  required: ["node_id", "effect_name"],
20
20
  },
21
21
  handler: async (args) => {
22
- const script = buildToolScript(`
23
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
24
- if (!result) return __error("Clip not found");
25
-
26
- var clip = result.clip;
27
- var effectName = "${escapeForExtendScript(args.effect_name)}";
28
- var comp = null;
29
-
30
- for (var i = 0; i < clip.components.numItems; i++) {
31
- if (clip.components[i].displayName === effectName || clip.components[i].matchName === effectName) {
32
- comp = clip.components[i];
33
- break;
34
- }
35
- }
36
-
37
- if (!comp) return __error("Effect not found: " + effectName);
38
-
39
- var props = [];
40
- for (var p = 0; p < comp.properties.numItems; p++) {
41
- var prop = comp.properties[p];
42
- var info = {
43
- index: p,
44
- displayName: prop.displayName,
45
- isTimeVarying: false,
46
- keyframesSupported: false
47
- };
48
- try { info.isTimeVarying = prop.isTimeVarying(); } catch(e) {}
49
- try { info.keyframesSupported = prop.areKeyframesSupported(); } catch(e) {}
50
- try { info.value = prop.getValue(0, 0); } catch(e) {}
51
- props.push(info);
52
- }
53
-
54
- return __result({
55
- effect: comp.displayName,
56
- matchName: comp.matchName,
57
- properties: props
58
- });
22
+ const script = buildToolScript(`
23
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
24
+ if (!result) return __error("Clip not found");
25
+
26
+ var clip = result.clip;
27
+ var effectName = "${escapeForExtendScript(args.effect_name)}";
28
+ var comp = null;
29
+
30
+ for (var i = 0; i < clip.components.numItems; i++) {
31
+ if (clip.components[i].displayName === effectName || clip.components[i].matchName === effectName) {
32
+ comp = clip.components[i];
33
+ break;
34
+ }
35
+ }
36
+
37
+ if (!comp) return __error("Effect not found: " + effectName);
38
+
39
+ var props = [];
40
+ for (var p = 0; p < comp.properties.numItems; p++) {
41
+ var prop = comp.properties[p];
42
+ var info = {
43
+ index: p,
44
+ displayName: prop.displayName,
45
+ isTimeVarying: false,
46
+ keyframesSupported: false
47
+ };
48
+ try { info.isTimeVarying = prop.isTimeVarying(); } catch(e) {}
49
+ try { info.keyframesSupported = prop.areKeyframesSupported(); } catch(e) {}
50
+ try { info.value = prop.getValue(0, 0); } catch(e) {}
51
+ props.push(info);
52
+ }
53
+
54
+ return __result({
55
+ effect: comp.displayName,
56
+ matchName: comp.matchName,
57
+ properties: props
58
+ });
59
59
  `);
60
60
  return sendCommand(script, bridgeOptions);
61
61
  },
@@ -85,36 +85,36 @@ export function getKeyframeTools(bridgeOptions) {
85
85
  required: ["node_id", "effect_name", "property_name", "value"],
86
86
  },
87
87
  handler: async (args) => {
88
- const script = buildToolScript(`
89
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
90
- if (!result) return __error("Clip not found");
91
-
92
- var clip = result.clip;
93
- var comp = null;
94
- for (var i = 0; i < clip.components.numItems; i++) {
95
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
96
- comp = clip.components[i];
97
- break;
98
- }
99
- }
100
- if (!comp) return __error("Effect not found: ${escapeForExtendScript(args.effect_name)}");
101
-
102
- var prop = null;
103
- for (var p = 0; p < comp.properties.numItems; p++) {
104
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
105
- prop = comp.properties[p];
106
- break;
107
- }
108
- }
109
- if (!prop) return __error("Property not found: ${escapeForExtendScript(args.property_name)}");
110
-
111
- prop.setValue(${args.value}, true);
112
- return __result({
113
- set: true,
114
- effect: "${escapeForExtendScript(args.effect_name)}",
115
- property: "${escapeForExtendScript(args.property_name)}",
116
- value: ${args.value}
117
- });
88
+ const script = buildToolScript(`
89
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
90
+ if (!result) return __error("Clip not found");
91
+
92
+ var clip = result.clip;
93
+ var comp = null;
94
+ for (var i = 0; i < clip.components.numItems; i++) {
95
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
96
+ comp = clip.components[i];
97
+ break;
98
+ }
99
+ }
100
+ if (!comp) return __error("Effect not found: ${escapeForExtendScript(args.effect_name)}");
101
+
102
+ var prop = null;
103
+ for (var p = 0; p < comp.properties.numItems; p++) {
104
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
105
+ prop = comp.properties[p];
106
+ break;
107
+ }
108
+ }
109
+ if (!prop) return __error("Property not found: ${escapeForExtendScript(args.property_name)}");
110
+
111
+ prop.setValue(${args.value}, true);
112
+ return __result({
113
+ set: true,
114
+ effect: "${escapeForExtendScript(args.effect_name)}",
115
+ property: "${escapeForExtendScript(args.property_name)}",
116
+ value: ${args.value}
117
+ });
118
118
  `);
119
119
  return sendCommand(script, bridgeOptions);
120
120
  },
@@ -140,56 +140,56 @@ export function getKeyframeTools(bridgeOptions) {
140
140
  required: ["node_id", "effect_name", "property_name"],
141
141
  },
142
142
  handler: async (args) => {
143
- const script = buildToolScript(`
144
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
145
- if (!result) return __error("Clip not found");
146
-
147
- var clip = result.clip;
148
- var comp = null;
149
- for (var i = 0; i < clip.components.numItems; i++) {
150
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
151
- comp = clip.components[i];
152
- break;
153
- }
154
- }
155
- if (!comp) return __error("Effect not found");
156
-
157
- var prop = null;
158
- for (var p = 0; p < comp.properties.numItems; p++) {
159
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
160
- prop = comp.properties[p];
161
- break;
162
- }
163
- }
164
- if (!prop) return __error("Property not found");
165
-
166
- var isTimeVarying = false;
167
- try { isTimeVarying = prop.isTimeVarying(); } catch(e) {}
168
-
169
- if (!isTimeVarying) {
170
- return __result({ keyframes: [], isTimeVarying: false, message: "Property has no keyframes" });
171
- }
172
-
173
- var keys = prop.getKeys();
174
- var keyframes = [];
175
- if (keys) {
176
- for (var k = 0; k < keys.length; k++) {
177
- var time = keys[k];
178
- var val = null;
179
- try { val = prop.getValueAtKey(time); } catch(e) {}
180
- keyframes.push({
181
- time: __ticksToSeconds(time.ticks),
182
- value: val
183
- });
184
- }
185
- }
186
-
187
- return __result({
188
- effect: "${escapeForExtendScript(args.effect_name)}",
189
- property: "${escapeForExtendScript(args.property_name)}",
190
- isTimeVarying: true,
191
- keyframes: keyframes
192
- });
143
+ const script = buildToolScript(`
144
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
145
+ if (!result) return __error("Clip not found");
146
+
147
+ var clip = result.clip;
148
+ var comp = null;
149
+ for (var i = 0; i < clip.components.numItems; i++) {
150
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
151
+ comp = clip.components[i];
152
+ break;
153
+ }
154
+ }
155
+ if (!comp) return __error("Effect not found");
156
+
157
+ var prop = null;
158
+ for (var p = 0; p < comp.properties.numItems; p++) {
159
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
160
+ prop = comp.properties[p];
161
+ break;
162
+ }
163
+ }
164
+ if (!prop) return __error("Property not found");
165
+
166
+ var isTimeVarying = false;
167
+ try { isTimeVarying = prop.isTimeVarying(); } catch(e) {}
168
+
169
+ if (!isTimeVarying) {
170
+ return __result({ keyframes: [], isTimeVarying: false, message: "Property has no keyframes" });
171
+ }
172
+
173
+ var keys = prop.getKeys();
174
+ var keyframes = [];
175
+ if (keys) {
176
+ for (var k = 0; k < keys.length; k++) {
177
+ var time = keys[k];
178
+ var val = null;
179
+ try { val = prop.getValueAtKey(time); } catch(e) {}
180
+ keyframes.push({
181
+ time: __ticksToSeconds(time.ticks),
182
+ value: val
183
+ });
184
+ }
185
+ }
186
+
187
+ return __result({
188
+ effect: "${escapeForExtendScript(args.effect_name)}",
189
+ property: "${escapeForExtendScript(args.property_name)}",
190
+ isTimeVarying: true,
191
+ keyframes: keyframes
192
+ });
193
193
  `);
194
194
  return sendCommand(script, bridgeOptions);
195
195
  },
@@ -223,48 +223,48 @@ export function getKeyframeTools(bridgeOptions) {
223
223
  required: ["node_id", "effect_name", "property_name", "time_seconds", "value"],
224
224
  },
225
225
  handler: async (args) => {
226
- const script = buildToolScript(`
227
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
228
- if (!result) return __error("Clip not found");
229
-
230
- var clip = result.clip;
231
- var comp = null;
232
- for (var i = 0; i < clip.components.numItems; i++) {
233
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
234
- comp = clip.components[i];
235
- break;
236
- }
237
- }
238
- if (!comp) return __error("Effect not found");
239
-
240
- var prop = null;
241
- for (var p = 0; p < comp.properties.numItems; p++) {
242
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
243
- prop = comp.properties[p];
244
- break;
245
- }
246
- }
247
- if (!prop) return __error("Property not found");
248
-
249
- // Enable keyframes if not already
250
- try {
251
- if (!prop.isTimeVarying()) {
252
- prop.setTimeVarying(true);
253
- }
254
- } catch(e) {}
255
-
256
- var time = new Time();
257
- time.ticks = __secondsToTicks(${args.time_seconds}).toString();
258
- prop.addKey(time);
259
- prop.setValueAtKey(time, ${args.value}, true);
260
-
261
- return __result({
262
- added: true,
263
- effect: "${escapeForExtendScript(args.effect_name)}",
264
- property: "${escapeForExtendScript(args.property_name)}",
265
- time: ${args.time_seconds},
266
- value: ${args.value}
267
- });
226
+ const script = buildToolScript(`
227
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
228
+ if (!result) return __error("Clip not found");
229
+
230
+ var clip = result.clip;
231
+ var comp = null;
232
+ for (var i = 0; i < clip.components.numItems; i++) {
233
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
234
+ comp = clip.components[i];
235
+ break;
236
+ }
237
+ }
238
+ if (!comp) return __error("Effect not found");
239
+
240
+ var prop = null;
241
+ for (var p = 0; p < comp.properties.numItems; p++) {
242
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
243
+ prop = comp.properties[p];
244
+ break;
245
+ }
246
+ }
247
+ if (!prop) return __error("Property not found");
248
+
249
+ // Enable keyframes if not already
250
+ try {
251
+ if (!prop.isTimeVarying()) {
252
+ prop.setTimeVarying(true);
253
+ }
254
+ } catch(e) {}
255
+
256
+ var time = new Time();
257
+ time.ticks = __secondsToTicks(${args.time_seconds}).toString();
258
+ prop.addKey(time);
259
+ prop.setValueAtKey(time, ${args.value}, true);
260
+
261
+ return __result({
262
+ added: true,
263
+ effect: "${escapeForExtendScript(args.effect_name)}",
264
+ property: "${escapeForExtendScript(args.property_name)}",
265
+ time: ${args.time_seconds},
266
+ value: ${args.value}
267
+ });
268
268
  `);
269
269
  return sendCommand(script, bridgeOptions);
270
270
  },
@@ -294,39 +294,39 @@ export function getKeyframeTools(bridgeOptions) {
294
294
  required: ["node_id", "effect_name", "property_name", "time_seconds"],
295
295
  },
296
296
  handler: async (args) => {
297
- const script = buildToolScript(`
298
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
299
- if (!result) return __error("Clip not found");
300
-
301
- var clip = result.clip;
302
- var comp = null;
303
- for (var i = 0; i < clip.components.numItems; i++) {
304
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
305
- comp = clip.components[i];
306
- break;
307
- }
308
- }
309
- if (!comp) return __error("Effect not found");
310
-
311
- var prop = null;
312
- for (var p = 0; p < comp.properties.numItems; p++) {
313
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
314
- prop = comp.properties[p];
315
- break;
316
- }
317
- }
318
- if (!prop) return __error("Property not found");
319
-
320
- var time = new Time();
321
- time.ticks = __secondsToTicks(${args.time_seconds}).toString();
322
- prop.removeKey(time);
323
-
324
- return __result({
325
- removed: true,
326
- effect: "${escapeForExtendScript(args.effect_name)}",
327
- property: "${escapeForExtendScript(args.property_name)}",
328
- time: ${args.time_seconds}
329
- });
297
+ const script = buildToolScript(`
298
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
299
+ if (!result) return __error("Clip not found");
300
+
301
+ var clip = result.clip;
302
+ var comp = null;
303
+ for (var i = 0; i < clip.components.numItems; i++) {
304
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
305
+ comp = clip.components[i];
306
+ break;
307
+ }
308
+ }
309
+ if (!comp) return __error("Effect not found");
310
+
311
+ var prop = null;
312
+ for (var p = 0; p < comp.properties.numItems; p++) {
313
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
314
+ prop = comp.properties[p];
315
+ break;
316
+ }
317
+ }
318
+ if (!prop) return __error("Property not found");
319
+
320
+ var time = new Time();
321
+ time.ticks = __secondsToTicks(${args.time_seconds}).toString();
322
+ prop.removeKey(time);
323
+
324
+ return __result({
325
+ removed: true,
326
+ effect: "${escapeForExtendScript(args.effect_name)}",
327
+ property: "${escapeForExtendScript(args.property_name)}",
328
+ time: ${args.time_seconds}
329
+ });
330
330
  `);
331
331
  return sendCommand(script, bridgeOptions);
332
332
  },
@@ -360,49 +360,49 @@ export function getKeyframeTools(bridgeOptions) {
360
360
  required: ["node_id", "effect_name", "property_name", "start_seconds", "end_seconds"],
361
361
  },
362
362
  handler: async (args) => {
363
- const script = buildToolScript(`
364
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
365
- if (!result) return __error("Clip not found");
366
-
367
- var clip = result.clip;
368
- var comp = null;
369
- for (var i = 0; i < clip.components.numItems; i++) {
370
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
371
- comp = clip.components[i];
372
- break;
373
- }
374
- }
375
- if (!comp) return __error("Effect not found");
376
-
377
- var prop = null;
378
- for (var p = 0; p < comp.properties.numItems; p++) {
379
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
380
- prop = comp.properties[p];
381
- break;
382
- }
383
- }
384
- if (!prop) return __error("Property not found");
385
-
386
- var keys = prop.getKeys();
387
- var startTicks = parseFloat(__secondsToTicks(${args.start_seconds}));
388
- var endTicks = parseFloat(__secondsToTicks(${args.end_seconds}));
389
- var removed = 0;
390
- if (keys) {
391
- for (var k = keys.length - 1; k >= 0; k--) {
392
- var kt = parseFloat(keys[k].ticks);
393
- if (kt >= startTicks && kt <= endTicks) {
394
- prop.removeKey(keys[k]);
395
- removed++;
396
- }
397
- }
398
- }
399
-
400
- return __result({
401
- removed: removed,
402
- effect: "${escapeForExtendScript(args.effect_name)}",
403
- property: "${escapeForExtendScript(args.property_name)}",
404
- range: { start: ${args.start_seconds}, end: ${args.end_seconds} }
405
- });
363
+ const script = buildToolScript(`
364
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
365
+ if (!result) return __error("Clip not found");
366
+
367
+ var clip = result.clip;
368
+ var comp = null;
369
+ for (var i = 0; i < clip.components.numItems; i++) {
370
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
371
+ comp = clip.components[i];
372
+ break;
373
+ }
374
+ }
375
+ if (!comp) return __error("Effect not found");
376
+
377
+ var prop = null;
378
+ for (var p = 0; p < comp.properties.numItems; p++) {
379
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
380
+ prop = comp.properties[p];
381
+ break;
382
+ }
383
+ }
384
+ if (!prop) return __error("Property not found");
385
+
386
+ var keys = prop.getKeys();
387
+ var startTicks = parseFloat(__secondsToTicks(${args.start_seconds}));
388
+ var endTicks = parseFloat(__secondsToTicks(${args.end_seconds}));
389
+ var removed = 0;
390
+ if (keys) {
391
+ for (var k = keys.length - 1; k >= 0; k--) {
392
+ var kt = parseFloat(keys[k].ticks);
393
+ if (kt >= startTicks && kt <= endTicks) {
394
+ prop.removeKey(keys[k]);
395
+ removed++;
396
+ }
397
+ }
398
+ }
399
+
400
+ return __result({
401
+ removed: removed,
402
+ effect: "${escapeForExtendScript(args.effect_name)}",
403
+ property: "${escapeForExtendScript(args.property_name)}",
404
+ range: { start: ${args.start_seconds}, end: ${args.end_seconds} }
405
+ });
406
406
  `);
407
407
  return sendCommand(script, bridgeOptions);
408
408
  },
@@ -439,38 +439,38 @@ export function getKeyframeTools(bridgeOptions) {
439
439
  handler: async (args) => {
440
440
  const interpMap = { linear: 0, hold: 4, bezier: 5 };
441
441
  const interpType = interpMap[args.interpolation] ?? 0;
442
- const script = buildToolScript(`
443
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
444
- if (!result) return __error("Clip not found");
445
-
446
- var clip = result.clip;
447
- var comp = null;
448
- for (var i = 0; i < clip.components.numItems; i++) {
449
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
450
- comp = clip.components[i];
451
- break;
452
- }
453
- }
454
- if (!comp) return __error("Effect not found");
455
-
456
- var prop = null;
457
- for (var p = 0; p < comp.properties.numItems; p++) {
458
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
459
- prop = comp.properties[p];
460
- break;
461
- }
462
- }
463
- if (!prop) return __error("Property not found");
464
-
465
- var time = new Time();
466
- time.ticks = __secondsToTicks(${args.time_seconds}).toString();
467
- prop.setInterpolationTypeAtKey(time, ${interpType}, true);
468
-
469
- return __result({
470
- set: true,
471
- interpolation: "${args.interpolation}",
472
- time: ${args.time_seconds}
473
- });
442
+ const script = buildToolScript(`
443
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
444
+ if (!result) return __error("Clip not found");
445
+
446
+ var clip = result.clip;
447
+ var comp = null;
448
+ for (var i = 0; i < clip.components.numItems; i++) {
449
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
450
+ comp = clip.components[i];
451
+ break;
452
+ }
453
+ }
454
+ if (!comp) return __error("Effect not found");
455
+
456
+ var prop = null;
457
+ for (var p = 0; p < comp.properties.numItems; p++) {
458
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
459
+ prop = comp.properties[p];
460
+ break;
461
+ }
462
+ }
463
+ if (!prop) return __error("Property not found");
464
+
465
+ var time = new Time();
466
+ time.ticks = __secondsToTicks(${args.time_seconds}).toString();
467
+ prop.setInterpolationTypeAtKey(time, ${interpType}, true);
468
+
469
+ return __result({
470
+ set: true,
471
+ interpolation: "${args.interpolation}",
472
+ time: ${args.time_seconds}
473
+ });
474
474
  `);
475
475
  return sendCommand(script, bridgeOptions);
476
476
  },
@@ -500,108 +500,108 @@ export function getKeyframeTools(bridgeOptions) {
500
500
  required: ["node_id", "effect_name", "property_name", "time_seconds"],
501
501
  },
502
502
  handler: async (args) => {
503
- const script = buildToolScript(`
504
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
505
- if (!result) return __error("Clip not found");
506
-
507
- var clip = result.clip;
508
- var comp = null;
509
- for (var i = 0; i < clip.components.numItems; i++) {
510
- if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
511
- comp = clip.components[i];
512
- break;
513
- }
514
- }
515
- if (!comp) return __error("Effect not found");
516
-
517
- var prop = null;
518
- for (var p = 0; p < comp.properties.numItems; p++) {
519
- if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
520
- prop = comp.properties[p];
521
- break;
522
- }
523
- }
524
- if (!prop) return __error("Property not found");
525
-
526
- var targetTicks = parseFloat(__secondsToTicks(${args.time_seconds}).toString());
527
- var value = null;
528
- var source = "static";
529
-
530
- var isTimeVarying = false;
531
- try { isTimeVarying = prop.isTimeVarying(); } catch(e) { isTimeVarying = false; }
532
-
533
- if (isTimeVarying) {
534
- var keys = prop.getKeys();
535
- if (keys && keys.length > 0) {
536
- // Look for an exact key match by tick value.
537
- var exactKey = null;
538
- for (var k = 0; k < keys.length; k++) {
539
- if (parseFloat(keys[k].ticks) === targetTicks) {
540
- exactKey = keys[k];
541
- break;
542
- }
543
- }
544
- if (exactKey !== null) {
545
- value = prop.getValueAtKey(exactKey);
546
- source = "exact-key";
547
- } else {
548
- // Find the bracketing keys (lower = last key before target, upper = first key after target).
549
- var lowerKey = null;
550
- var upperKey = null;
551
- var lowerTicks = 0;
552
- var upperTicks = 0;
553
- for (var k2 = 0; k2 < keys.length; k2++) {
554
- var kt = parseFloat(keys[k2].ticks);
555
- if (kt <= targetTicks && (lowerKey === null || kt > lowerTicks)) {
556
- lowerKey = keys[k2];
557
- lowerTicks = kt;
558
- }
559
- if (kt >= targetTicks && (upperKey === null || kt < upperTicks)) {
560
- upperKey = keys[k2];
561
- upperTicks = kt;
562
- }
563
- }
564
- if (lowerKey !== null && upperKey !== null) {
565
- var lowerVal = prop.getValueAtKey(lowerKey);
566
- var upperVal = prop.getValueAtKey(upperKey);
567
- var span = upperTicks - lowerTicks;
568
- var ratio = (span === 0) ? 0 : (targetTicks - lowerTicks) / span;
569
- if (typeof lowerVal === "number" && typeof upperVal === "number") {
570
- value = lowerVal + (upperVal - lowerVal) * ratio;
571
- } else if (lowerVal && upperVal && typeof lowerVal.length === "number" && typeof upperVal.length === "number") {
572
- var arr = [];
573
- for (var d = 0; d < lowerVal.length; d++) {
574
- arr.push(lowerVal[d] + (upperVal[d] - lowerVal[d]) * ratio);
575
- }
576
- value = arr;
577
- } else {
578
- value = lowerVal;
579
- }
580
- source = "interpolated";
581
- } else if (lowerKey !== null) {
582
- value = prop.getValueAtKey(lowerKey);
583
- source = "exact-key";
584
- } else if (upperKey !== null) {
585
- value = prop.getValueAtKey(upperKey);
586
- source = "exact-key";
587
- }
588
- }
589
- } else {
590
- try { value = prop.getValue(); } catch(e) { value = null; }
591
- source = "static";
592
- }
593
- } else {
594
- try { value = prop.getValue(); } catch(e) { value = null; }
595
- source = "static";
596
- }
597
-
598
- return __result({
599
- effect: "${escapeForExtendScript(args.effect_name)}",
600
- property: "${escapeForExtendScript(args.property_name)}",
601
- time: ${args.time_seconds},
602
- value: value,
603
- source: source
604
- });
503
+ const script = buildToolScript(`
504
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
505
+ if (!result) return __error("Clip not found");
506
+
507
+ var clip = result.clip;
508
+ var comp = null;
509
+ for (var i = 0; i < clip.components.numItems; i++) {
510
+ if (clip.components[i].displayName === "${escapeForExtendScript(args.effect_name)}" || clip.components[i].matchName === "${escapeForExtendScript(args.effect_name)}") {
511
+ comp = clip.components[i];
512
+ break;
513
+ }
514
+ }
515
+ if (!comp) return __error("Effect not found");
516
+
517
+ var prop = null;
518
+ for (var p = 0; p < comp.properties.numItems; p++) {
519
+ if (comp.properties[p].displayName === "${escapeForExtendScript(args.property_name)}") {
520
+ prop = comp.properties[p];
521
+ break;
522
+ }
523
+ }
524
+ if (!prop) return __error("Property not found");
525
+
526
+ var targetTicks = parseFloat(__secondsToTicks(${args.time_seconds}).toString());
527
+ var value = null;
528
+ var source = "static";
529
+
530
+ var isTimeVarying = false;
531
+ try { isTimeVarying = prop.isTimeVarying(); } catch(e) { isTimeVarying = false; }
532
+
533
+ if (isTimeVarying) {
534
+ var keys = prop.getKeys();
535
+ if (keys && keys.length > 0) {
536
+ // Look for an exact key match by tick value.
537
+ var exactKey = null;
538
+ for (var k = 0; k < keys.length; k++) {
539
+ if (parseFloat(keys[k].ticks) === targetTicks) {
540
+ exactKey = keys[k];
541
+ break;
542
+ }
543
+ }
544
+ if (exactKey !== null) {
545
+ value = prop.getValueAtKey(exactKey);
546
+ source = "exact-key";
547
+ } else {
548
+ // Find the bracketing keys (lower = last key before target, upper = first key after target).
549
+ var lowerKey = null;
550
+ var upperKey = null;
551
+ var lowerTicks = 0;
552
+ var upperTicks = 0;
553
+ for (var k2 = 0; k2 < keys.length; k2++) {
554
+ var kt = parseFloat(keys[k2].ticks);
555
+ if (kt <= targetTicks && (lowerKey === null || kt > lowerTicks)) {
556
+ lowerKey = keys[k2];
557
+ lowerTicks = kt;
558
+ }
559
+ if (kt >= targetTicks && (upperKey === null || kt < upperTicks)) {
560
+ upperKey = keys[k2];
561
+ upperTicks = kt;
562
+ }
563
+ }
564
+ if (lowerKey !== null && upperKey !== null) {
565
+ var lowerVal = prop.getValueAtKey(lowerKey);
566
+ var upperVal = prop.getValueAtKey(upperKey);
567
+ var span = upperTicks - lowerTicks;
568
+ var ratio = (span === 0) ? 0 : (targetTicks - lowerTicks) / span;
569
+ if (typeof lowerVal === "number" && typeof upperVal === "number") {
570
+ value = lowerVal + (upperVal - lowerVal) * ratio;
571
+ } else if (lowerVal && upperVal && typeof lowerVal.length === "number" && typeof upperVal.length === "number") {
572
+ var arr = [];
573
+ for (var d = 0; d < lowerVal.length; d++) {
574
+ arr.push(lowerVal[d] + (upperVal[d] - lowerVal[d]) * ratio);
575
+ }
576
+ value = arr;
577
+ } else {
578
+ value = lowerVal;
579
+ }
580
+ source = "interpolated";
581
+ } else if (lowerKey !== null) {
582
+ value = prop.getValueAtKey(lowerKey);
583
+ source = "exact-key";
584
+ } else if (upperKey !== null) {
585
+ value = prop.getValueAtKey(upperKey);
586
+ source = "exact-key";
587
+ }
588
+ }
589
+ } else {
590
+ try { value = prop.getValue(); } catch(e) { value = null; }
591
+ source = "static";
592
+ }
593
+ } else {
594
+ try { value = prop.getValue(); } catch(e) { value = null; }
595
+ source = "static";
596
+ }
597
+
598
+ return __result({
599
+ effect: "${escapeForExtendScript(args.effect_name)}",
600
+ property: "${escapeForExtendScript(args.property_name)}",
601
+ time: ${args.time_seconds},
602
+ value: value,
603
+ source: source
604
+ });
605
605
  `);
606
606
  return sendCommand(script, bridgeOptions);
607
607
  },