@synthetic-ai/premiere-mcp 2.0.0 → 2.2.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 (60) hide show
  1. package/CHANGELOG.md +135 -73
  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 -70
  6. package/cep-plugin/CSXS/manifest.xml +49 -49
  7. package/cep-plugin/host.jsx +7 -7
  8. package/cep-plugin/index.html +472 -419
  9. package/cep-plugin/main.js +683 -327
  10. package/cep-plugin/premiere.jsx +24947 -24947
  11. package/dist/bridge/script-builder.js +378 -378
  12. package/dist/index.js +117 -18
  13. package/dist/license.d.ts +22 -0
  14. package/dist/license.js +89 -0
  15. package/dist/server.js +67 -61
  16. package/dist/tools/advanced.js +357 -357
  17. package/dist/tools/audio-advanced.js +1049 -1049
  18. package/dist/tools/audio.js +42 -42
  19. package/dist/tools/captions.js +27 -27
  20. package/dist/tools/clipboard.js +214 -214
  21. package/dist/tools/color-advanced.js +253 -253
  22. package/dist/tools/discovery.js +291 -291
  23. package/dist/tools/effects.js +285 -285
  24. package/dist/tools/export-presets.js +206 -206
  25. package/dist/tools/export.js +255 -255
  26. package/dist/tools/health.js +10 -10
  27. package/dist/tools/inspection.js +885 -885
  28. package/dist/tools/keyframes.js +369 -369
  29. package/dist/tools/markers.js +89 -89
  30. package/dist/tools/media.js +178 -178
  31. package/dist/tools/metadata.js +94 -94
  32. package/dist/tools/multicam.js +50 -50
  33. package/dist/tools/playback.js +15 -15
  34. package/dist/tools/playhead.js +95 -95
  35. package/dist/tools/project-manager.js +21 -21
  36. package/dist/tools/project.js +149 -149
  37. package/dist/tools/scripting.js +319 -319
  38. package/dist/tools/selection.js +202 -202
  39. package/dist/tools/sequence-advanced.js +379 -374
  40. package/dist/tools/sequence-settings.js +564 -556
  41. package/dist/tools/sequence.js +169 -150
  42. package/dist/tools/source-monitor.js +68 -68
  43. package/dist/tools/text.js +58 -58
  44. package/dist/tools/timeline.js +312 -312
  45. package/dist/tools/track-management.js +446 -446
  46. package/dist/tools/track-targeting.js +635 -635
  47. package/dist/tools/tracks.js +87 -87
  48. package/dist/tools/transitions-motion.js +174 -174
  49. package/dist/tools/transitions.js +111 -111
  50. package/dist/tools/utility.js +606 -606
  51. package/dist/tools/workspace.js +29 -29
  52. package/package.json +1 -1
  53. package/scripts/build-chat-dmg.sh +210 -210
  54. package/scripts/build-chat-zip.sh +291 -291
  55. package/scripts/install-cep-windows.ps1 +99 -99
  56. package/scripts/install-cep.sh +66 -66
  57. package/scripts/install-chat-plugin.bat +67 -67
  58. package/scripts/install-chat-plugin.sh +85 -85
  59. package/scripts/install-windows.bat +95 -95
  60. package/scripts/package.mjs +254 -218
@@ -3,17 +3,17 @@ import { sendCommand } from "../bridge/file-bridge.js";
3
3
  export function getSequenceTools(bridgeOptions) {
4
4
  return {
5
5
  create_sequence: {
6
- description: `Create a new empty sequence in the project and make it the active sequence.
7
-
8
- Uses qe.project.newSequence() which works without dialogs in Premiere Pro 2026.
9
-
10
- If no preset_path is provided, uses the HD 1080p 23.976fps preset. To create a specific format, pass the full path to a .sqpreset file.
11
-
12
- Common preset paths on Windows:
13
- - 1920x1080 24fps: C:\\Program Files\\Adobe\\Adobe Premiere Pro 2026\\Settings\\SequencePresets\\HD 1080p\\HD 1080p 23.976 fps.sqpreset
14
- - 1080x1920 (9:16): C:\\Program Files\\Adobe\\Adobe Premiere Pro 2026\\Settings\\SequencePresets\\Social\\Social Media Portrait 9x16 30 fps.sqpreset
15
-
16
- Example: create_sequence({ name: "Main Edit" })
6
+ description: `Create a new empty sequence in the project and make it the active sequence.
7
+
8
+ Uses qe.project.newSequence() which works without dialogs in Premiere Pro 2026.
9
+
10
+ If no preset_path is provided, uses the HD 1080p 23.976fps preset. To create a specific format, pass the full path to a .sqpreset file.
11
+
12
+ Common preset paths on Windows:
13
+ - 1920x1080 24fps: C:\\Program Files\\Adobe\\Adobe Premiere Pro 2026\\Settings\\SequencePresets\\HD 1080p\\HD 1080p 23.976 fps.sqpreset
14
+ - 1080x1920 (9:16): C:\\Program Files\\Adobe\\Adobe Premiere Pro 2026\\Settings\\SequencePresets\\Social\\Social Media Portrait 9x16 30 fps.sqpreset
15
+
16
+ Example: create_sequence({ name: "Main Edit" })
17
17
  Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\\\Adobe\\\\Adobe Premiere Pro 2026\\\\Settings\\\\SequencePresets\\\\Social\\\\Social Media Portrait 9x16 30 fps.sqpreset" })`,
18
18
  parameters: {
19
19
  type: "object",
@@ -30,26 +30,45 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
30
30
  required: ["name"],
31
31
  },
32
32
  handler: async (args) => {
33
- const defaultPreset = "C:\\\\Program Files\\\\Adobe\\\\Adobe Premiere Pro 2026\\\\Settings\\\\SequencePresets\\\\HD 1080p\\\\HD 1080p 23.976 fps.sqpreset";
34
- const preset = args.preset_path ? escapeForExtendScript(args.preset_path) : defaultPreset;
35
- const script = buildToolScript(`
36
- app.enableQE();
37
- var seqName = "${escapeForExtendScript(args.name)}";
38
- var presetPath = "${preset}";
39
- var countBefore = app.project.sequences.numSequences;
40
- var ok = qe.project.newSequence(seqName, presetPath);
41
- if (!ok) return __error("qe.project.newSequence returned false — check preset path exists");
42
- // Find the newly created sequence by name
43
- var newSeq = null;
44
- for (var i = 0; i < app.project.sequences.numSequences; i++) {
45
- if (app.project.sequences[i].name === seqName) {
46
- newSeq = app.project.sequences[i];
47
- break;
48
- }
49
- }
50
- if (!newSeq) return __error("Sequence created but not found by name");
51
- app.project.activeSequence = newSeq;
52
- return __result({ created: true, name: newSeq.name, id: newSeq.sequenceID, width: newSeq.frameSizeHorizontal, height: newSeq.frameSizeVertical });
33
+ const script = buildToolScript(`
34
+ app.enableQE();
35
+ var seqName = "${escapeForExtendScript(args.name)}";
36
+ ${args.preset_path
37
+ ? `var presetPath = "${escapeForExtendScript(args.preset_path)}";`
38
+ : `// No preset_path given — probe known install locations (Windows and
39
+ // macOS, PP 2026 down to CC 2023) for the HD 1080p 23.976fps preset.
40
+ var presetPath = "";
41
+ var presetCandidates = [
42
+ "C:\\\\Program Files\\\\Adobe\\\\Adobe Premiere Pro 2026\\\\Settings\\\\SequencePresets\\\\HD 1080p\\\\HD 1080p 23.976 fps.sqpreset",
43
+ "C:\\\\Program Files\\\\Adobe\\\\Adobe Premiere Pro 2025\\\\Settings\\\\SequencePresets\\\\HD 1080p\\\\HD 1080p 23.976 fps.sqpreset",
44
+ "C:\\\\Program Files\\\\Adobe\\\\Adobe Premiere Pro 2024\\\\Settings\\\\SequencePresets\\\\HD 1080p\\\\HD 1080p 23.976 fps.sqpreset",
45
+ "C:\\\\Program Files\\\\Adobe\\\\Adobe Premiere Pro CC 2023\\\\Settings\\\\SequencePresets\\\\HD 1080p\\\\HD 1080p 23.976 fps.sqpreset",
46
+ "/Applications/Adobe Premiere Pro 2026/Adobe Premiere Pro 2026.app/Contents/SequencePresets/HD 1080p/HD 1080p 23.976 fps.sqpreset",
47
+ "/Applications/Adobe Premiere Pro 2025/Adobe Premiere Pro 2025.app/Contents/SequencePresets/HD 1080p/HD 1080p 23.976 fps.sqpreset",
48
+ "/Applications/Adobe Premiere Pro 2024/Adobe Premiere Pro 2024.app/Contents/SequencePresets/HD 1080p/HD 1080p 23.976 fps.sqpreset",
49
+ "/Applications/Adobe Premiere Pro CC 2023/Adobe Premiere Pro CC 2023.app/Contents/SequencePresets/HD 1080p/HD 1080p 23.976 fps.sqpreset"
50
+ ];
51
+ for (var pi = 0; pi < presetCandidates.length; pi++) {
52
+ var pf = new File(presetCandidates[pi]);
53
+ if (pf.exists) { presetPath = pf.fsName; break; }
54
+ }
55
+ if (presetPath === "") {
56
+ return __error("No default sequence preset (.sqpreset) could be found on this system. Pass preset_path with an absolute path to a .sqpreset file.");
57
+ }`}
58
+ var countBefore = app.project.sequences.numSequences;
59
+ var ok = qe.project.newSequence(seqName, presetPath);
60
+ if (!ok) return __error("qe.project.newSequence returned false — check preset path exists");
61
+ // Find the newly created sequence by name
62
+ var newSeq = null;
63
+ for (var i = 0; i < app.project.sequences.numSequences; i++) {
64
+ if (app.project.sequences[i].name === seqName) {
65
+ newSeq = app.project.sequences[i];
66
+ break;
67
+ }
68
+ }
69
+ if (!newSeq) return __error("Sequence created but not found by name");
70
+ app.project.activeSequence = newSeq;
71
+ return __result({ created: true, name: newSeq.name, id: newSeq.sequenceID, width: newSeq.frameSizeHorizontal, height: newSeq.frameSizeVertical });
53
72
  `);
54
73
  return sendCommand(script, bridgeOptions);
55
74
  },
@@ -67,12 +86,12 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
67
86
  required: ["sequence_id"],
68
87
  },
69
88
  handler: async (args) => {
70
- const script = buildToolScript(`
71
- var seq = __findSequence("${escapeForExtendScript(args.sequence_id)}");
72
- if (!seq) return __error("Sequence not found: ${escapeForExtendScript(args.sequence_id)}");
73
-
74
- seq.clone();
75
- return __result({ duplicated: true, originalName: seq.name });
89
+ const script = buildToolScript(`
90
+ var seq = __findSequence("${escapeForExtendScript(args.sequence_id)}");
91
+ if (!seq) return __error("Sequence not found: ${escapeForExtendScript(args.sequence_id)}");
92
+
93
+ seq.clone();
94
+ return __result({ duplicated: true, originalName: seq.name });
76
95
  `);
77
96
  return sendCommand(script, bridgeOptions);
78
97
  },
@@ -90,26 +109,26 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
90
109
  required: ["sequence_id"],
91
110
  },
92
111
  handler: async (args) => {
93
- const script = buildToolScript(`
94
- var targetId = "${escapeForExtendScript(args.sequence_id)}";
95
- var seq = __findSequence(targetId);
96
- if (!seq) return __error("Sequence not found: " + targetId);
97
- var seqName = seq.name;
98
-
99
- function findProjectItemByName(parent, name) {
100
- for (var i = 0; i < parent.children.numItems; i++) {
101
- var item = parent.children[i];
102
- if (item.name === name && item.type !== 2) return item;
103
- if (item.type === 2) {
104
- var found = findProjectItemByName(item, name);
105
- if (found) return found;
106
- }
107
- }
108
- return null;
109
- }
110
-
111
- app.project.deleteSequence(seq);
112
- return __result({ deleted: true, name: seqName });
112
+ const script = buildToolScript(`
113
+ var targetId = "${escapeForExtendScript(args.sequence_id)}";
114
+ var seq = __findSequence(targetId);
115
+ if (!seq) return __error("Sequence not found: " + targetId);
116
+ var seqName = seq.name;
117
+
118
+ function findProjectItemByName(parent, name) {
119
+ for (var i = 0; i < parent.children.numItems; i++) {
120
+ var item = parent.children[i];
121
+ if (item.name === name && item.type !== 2) return item;
122
+ if (item.type === 2) {
123
+ var found = findProjectItemByName(item, name);
124
+ if (found) return found;
125
+ }
126
+ }
127
+ return null;
128
+ }
129
+
130
+ app.project.deleteSequence(seq);
131
+ return __result({ deleted: true, name: seqName });
113
132
  `);
114
133
  return sendCommand(script, bridgeOptions);
115
134
  },
@@ -139,14 +158,14 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
139
158
  : `var seq = app.project.activeSequence; if (!seq) return __error("No active sequence");`;
140
159
  const width = args.width ?? -1;
141
160
  const height = args.height ?? -1;
142
- const script = buildToolScript(`
143
- ${seqLookup}
144
- var settings = seq.getSettings();
145
- if (${width} !== -1) settings.videoFrameWidth = ${width};
146
- if (${height} !== -1) settings.videoFrameHeight = ${height};
147
- seq.setSettings(settings);
148
- var updated = seq.getSettings();
149
- return __result({ updated: true, name: seq.name, width: updated.videoFrameWidth, height: updated.videoFrameHeight });
161
+ const script = buildToolScript(`
162
+ ${seqLookup}
163
+ var settings = seq.getSettings();
164
+ if (${width} !== -1) settings.videoFrameWidth = ${width};
165
+ if (${height} !== -1) settings.videoFrameHeight = ${height};
166
+ seq.setSettings(settings);
167
+ var updated = seq.getSettings();
168
+ return __result({ updated: true, name: seq.name, width: updated.videoFrameWidth, height: updated.videoFrameHeight });
150
169
  `);
151
170
  return sendCommand(script, bridgeOptions);
152
171
  },
@@ -163,13 +182,13 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
163
182
  },
164
183
  },
165
184
  handler: async (args) => {
166
- const script = buildToolScript(`
167
- var seq = app.project.activeSequence;
168
- if (!seq) return __error("No active sequence");
169
-
170
- var newSeq = seq.createSubsequence(${args.ignore_track_targeting ? "true" : "false"});
171
- if (!newSeq) return __error("Failed to create subsequence");
172
- return __result({ created: true, name: newSeq.name, id: newSeq.sequenceID });
185
+ const script = buildToolScript(`
186
+ var seq = app.project.activeSequence;
187
+ if (!seq) return __error("No active sequence");
188
+
189
+ var newSeq = seq.createSubsequence(${args.ignore_track_targeting ? "true" : "false"});
190
+ if (!newSeq) return __error("Failed to create subsequence");
191
+ return __result({ created: true, name: newSeq.name, id: newSeq.sequenceID });
173
192
  `);
174
193
  return sendCommand(script, bridgeOptions);
175
194
  },
@@ -204,14 +223,14 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
204
223
  ? `var seq = __findSequence("${escapeForExtendScript(args.sequence_id)}"); if (!seq) return __error("Sequence not found");`
205
224
  : `var seq = app.project.activeSequence; if (!seq) return __error("No active sequence");`;
206
225
  const quality = args.quality === 1 || args.quality === 2 ? args.quality : 0;
207
- const script = buildToolScript(`
208
- ${seqLookup}
209
- // autoReframeSequence(numerator, denominator, motionPresetString). arg1/arg2 are
210
- // the aspect-ratio fraction (target_width:target_height preserves the ratio);
211
- // the 3rd arg is a STRING preset, not an integer.
212
- var __mp = (${quality} === 1 ? "slower" : (${quality} === 2 ? "faster" : "default"));
213
- seq.autoReframeSequence(${args.target_width}, ${args.target_height}, __mp);
214
- return __result({ reframed: true, name: seq.name, targetSize: "${args.target_width}x${args.target_height}", motionPreset: __mp });
226
+ const script = buildToolScript(`
227
+ ${seqLookup}
228
+ // autoReframeSequence(numerator, denominator, motionPresetString). arg1/arg2 are
229
+ // the aspect-ratio fraction (target_width:target_height preserves the ratio);
230
+ // the 3rd arg is a STRING preset, not an integer.
231
+ var __mp = (${quality} === 1 ? "slower" : (${quality} === 2 ? "faster" : "default"));
232
+ seq.autoReframeSequence(${args.target_width}, ${args.target_height}, __mp);
233
+ return __result({ reframed: true, name: seq.name, targetSize: "${args.target_width}x${args.target_height}", motionPreset: __mp });
215
234
  `);
216
235
  return sendCommand(script, bridgeOptions);
217
236
  },
@@ -229,29 +248,29 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
229
248
  required: ["node_id"],
230
249
  },
231
250
  handler: async (args) => {
232
- const script = buildToolScript(`
233
- var seq = app.project.activeSequence;
234
- if (!seq) return __error("No active sequence");
235
- var targetClip = null;
236
- for (var t = 0; t < seq.videoTracks.numTracks; t++) {
237
- for (var c = 0; c < seq.videoTracks[t].clips.numItems; c++) {
238
- var clip = seq.videoTracks[t].clips[c];
239
- if (clip.nodeId === "${escapeForExtendScript(args.node_id)}") { targetClip = clip; break; }
240
- }
241
- if (targetClip) break;
242
- }
243
- if (!targetClip) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
244
- // Try QE DOM unnest
245
- app.enableQE();
246
- try {
247
- targetClip.setSelected(true, true);
248
- var qeSeq = qe.project.getActiveSequence();
249
- if (qeSeq && qeSeq.flattenSelectedNest) {
250
- qeSeq.flattenSelectedNest();
251
- return __result({ unnested: true, clipName: targetClip.name });
252
- }
253
- } catch(e) {}
254
- return __error("Could not unnest via QE DOM in this PP version. Select the nested clip and use Clip > Nest > Unnest in the UI.");
251
+ const script = buildToolScript(`
252
+ var seq = app.project.activeSequence;
253
+ if (!seq) return __error("No active sequence");
254
+ var targetClip = null;
255
+ for (var t = 0; t < seq.videoTracks.numTracks; t++) {
256
+ for (var c = 0; c < seq.videoTracks[t].clips.numItems; c++) {
257
+ var clip = seq.videoTracks[t].clips[c];
258
+ if (clip.nodeId === "${escapeForExtendScript(args.node_id)}") { targetClip = clip; break; }
259
+ }
260
+ if (targetClip) break;
261
+ }
262
+ if (!targetClip) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
263
+ // Try QE DOM unnest
264
+ app.enableQE();
265
+ try {
266
+ targetClip.setSelected(true, true);
267
+ var qeSeq = qe.project.getActiveSequence();
268
+ if (qeSeq && qeSeq.flattenSelectedNest) {
269
+ qeSeq.flattenSelectedNest();
270
+ return __result({ unnested: true, clipName: targetClip.name });
271
+ }
272
+ } catch(e) {}
273
+ return __error("Could not unnest via QE DOM in this PP version. Select the nested clip and use Clip > Nest > Unnest in the UI.");
255
274
  `);
256
275
  return sendCommand(script, bridgeOptions);
257
276
  },
@@ -273,22 +292,22 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
273
292
  required: ["name", "preset_path"],
274
293
  },
275
294
  handler: async (args) => {
276
- const script = buildToolScript(`
277
- app.enableQE();
278
- var seqName = "${escapeForExtendScript(args.name)}";
279
- var presetPath = "${escapeForExtendScript(args.preset_path)}";
280
- var ok = qe.project.newSequence(seqName, presetPath);
281
- if (!ok) return __error("qe.project.newSequence returned false — check preset path: " + presetPath);
282
- var newSeq = null;
283
- for (var i = 0; i < app.project.sequences.numSequences; i++) {
284
- if (app.project.sequences[i].name === seqName) {
285
- newSeq = app.project.sequences[i];
286
- break;
287
- }
288
- }
289
- if (!newSeq) return __error("Sequence created but not found by name");
290
- app.project.activeSequence = newSeq;
291
- return __result({ created: true, name: newSeq.name, id: newSeq.sequenceID, width: newSeq.frameSizeHorizontal, height: newSeq.frameSizeVertical });
295
+ const script = buildToolScript(`
296
+ app.enableQE();
297
+ var seqName = "${escapeForExtendScript(args.name)}";
298
+ var presetPath = "${escapeForExtendScript(args.preset_path)}";
299
+ var ok = qe.project.newSequence(seqName, presetPath);
300
+ if (!ok) return __error("qe.project.newSequence returned false — check preset path: " + presetPath);
301
+ var newSeq = null;
302
+ for (var i = 0; i < app.project.sequences.numSequences; i++) {
303
+ if (app.project.sequences[i].name === seqName) {
304
+ newSeq = app.project.sequences[i];
305
+ break;
306
+ }
307
+ }
308
+ if (!newSeq) return __error("Sequence created but not found by name");
309
+ app.project.activeSequence = newSeq;
310
+ return __result({ created: true, name: newSeq.name, id: newSeq.sequenceID, width: newSeq.frameSizeHorizontal, height: newSeq.frameSizeVertical });
292
311
  `);
293
312
  return sendCommand(script, bridgeOptions);
294
313
  },
@@ -310,11 +329,11 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
310
329
  required: ["property_id", "property_value"],
311
330
  },
312
331
  handler: async (args) => {
313
- const script = buildToolScript(`
314
- var seq = app.project.activeSequence;
315
- if (!seq) return __error("No active sequence");
316
- seq.attachCustomProperty("${escapeForExtendScript(args.property_id)}", "${escapeForExtendScript(args.property_value)}");
317
- return __result({ attached: true, propertyId: "${escapeForExtendScript(args.property_id)}", value: "${escapeForExtendScript(args.property_value)}" });
332
+ const script = buildToolScript(`
333
+ var seq = app.project.activeSequence;
334
+ if (!seq) return __error("No active sequence");
335
+ seq.attachCustomProperty("${escapeForExtendScript(args.property_id)}", "${escapeForExtendScript(args.property_value)}");
336
+ return __result({ attached: true, propertyId: "${escapeForExtendScript(args.property_id)}", value: "${escapeForExtendScript(args.property_value)}" });
318
337
  `);
319
338
  return sendCommand(script, bridgeOptions);
320
339
  },
@@ -326,27 +345,27 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
326
345
  properties: {},
327
346
  },
328
347
  handler: async () => {
329
- const script = buildToolScript(`
330
- var seq = app.project.activeSequence;
331
- if (!seq) return __error("No active sequence");
332
- var enabled = false;
333
- var available = false;
334
- try {
335
- if (typeof seq.isWorkAreaEnabled === "function") {
336
- available = true;
337
- enabled = seq.isWorkAreaEnabled();
338
- } else if (typeof seq.isWorkAreaBarEnabled === "function") {
339
- available = true;
340
- enabled = seq.isWorkAreaBarEnabled();
341
- } else if (seq.workAreaEnabled !== undefined) {
342
- available = true;
343
- enabled = seq.workAreaEnabled;
344
- }
345
- } catch(e) {
346
- // API exists but threw, or not found — report disabled + unavailable so callers can distinguish
347
- return __result({ sequenceName: seq.name, enabled: false, available: false, workAreaEnabled: false });
348
- }
349
- return __result({ sequenceName: seq.name, enabled: enabled, available: available, workAreaEnabled: enabled });
348
+ const script = buildToolScript(`
349
+ var seq = app.project.activeSequence;
350
+ if (!seq) return __error("No active sequence");
351
+ var enabled = false;
352
+ var available = false;
353
+ try {
354
+ if (typeof seq.isWorkAreaEnabled === "function") {
355
+ available = true;
356
+ enabled = seq.isWorkAreaEnabled();
357
+ } else if (typeof seq.isWorkAreaBarEnabled === "function") {
358
+ available = true;
359
+ enabled = seq.isWorkAreaBarEnabled();
360
+ } else if (seq.workAreaEnabled !== undefined) {
361
+ available = true;
362
+ enabled = seq.workAreaEnabled;
363
+ }
364
+ } catch(e) {
365
+ // API exists but threw, or not found — report disabled + unavailable so callers can distinguish
366
+ return __result({ sequenceName: seq.name, enabled: false, available: false, workAreaEnabled: false });
367
+ }
368
+ return __result({ sequenceName: seq.name, enabled: enabled, available: available, workAreaEnabled: enabled });
350
369
  `);
351
370
  return sendCommand(script, bridgeOptions);
352
371
  },
@@ -364,11 +383,11 @@ Example: create_sequence({ name: "Vertical", preset_path: "C:\\\\Program Files\\
364
383
  required: ["preset_path"],
365
384
  },
366
385
  handler: async (args) => {
367
- const script = buildToolScript(`
368
- var seq = app.project.activeSequence;
369
- if (!seq) return __error("No active sequence");
370
- var ext = seq.getExportFileExtension("${escapeForExtendScript(args.preset_path)}");
371
- return __result({ sequenceName: seq.name, presetPath: "${escapeForExtendScript(args.preset_path)}", extension: ext });
386
+ const script = buildToolScript(`
387
+ var seq = app.project.activeSequence;
388
+ if (!seq) return __error("No active sequence");
389
+ var ext = seq.getExportFileExtension("${escapeForExtendScript(args.preset_path)}");
390
+ return __result({ sequenceName: seq.name, presetPath: "${escapeForExtendScript(args.preset_path)}", extension: ext });
372
391
  `);
373
392
  return sendCommand(script, bridgeOptions);
374
393
  },
@@ -15,11 +15,11 @@ export function getSourceMonitorTools(bridgeOptions) {
15
15
  required: ["item_id"],
16
16
  },
17
17
  handler: async (args) => {
18
- const script = buildToolScript(`
19
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
20
- if (!item) return __error("Project item not found");
21
- app.sourceMonitor.openProjectItem(item);
22
- return __result({ opened: true, item: item.name });
18
+ const script = buildToolScript(`
19
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
20
+ if (!item) return __error("Project item not found");
21
+ app.sourceMonitor.openProjectItem(item);
22
+ return __result({ opened: true, item: item.name });
23
23
  `);
24
24
  return sendCommand(script, bridgeOptions);
25
25
  },
@@ -28,9 +28,9 @@ export function getSourceMonitorTools(bridgeOptions) {
28
28
  description: "Close the clip currently open in the Source Monitor.",
29
29
  parameters: {},
30
30
  handler: async () => {
31
- const script = buildToolScript(`
32
- app.sourceMonitor.closeClip();
33
- return __result({ closed: true });
31
+ const script = buildToolScript(`
32
+ app.sourceMonitor.closeClip();
33
+ return __result({ closed: true });
34
34
  `);
35
35
  return sendCommand(script, bridgeOptions);
36
36
  },
@@ -39,9 +39,9 @@ export function getSourceMonitorTools(bridgeOptions) {
39
39
  description: "Close all clips in the Source Monitor.",
40
40
  parameters: {},
41
41
  handler: async () => {
42
- const script = buildToolScript(`
43
- app.sourceMonitor.closeAllClips();
44
- return __result({ closed: true });
42
+ const script = buildToolScript(`
43
+ app.sourceMonitor.closeAllClips();
44
+ return __result({ closed: true });
45
45
  `);
46
46
  return sendCommand(script, bridgeOptions);
47
47
  },
@@ -62,27 +62,27 @@ export function getSourceMonitorTools(bridgeOptions) {
62
62
  },
63
63
  },
64
64
  handler: async (args) => {
65
- const script = buildToolScript(`
66
- var item = app.sourceMonitor.getProjectItem();
67
- if (!item) return __error("No clip open in Source Monitor");
68
-
69
- ${args.in_seconds !== undefined ? `
70
- var inTime = new Time();
71
- inTime.seconds = ${args.in_seconds};
72
- item.setInPoint(inTime.ticks, 4);
73
- ` : ""}
74
-
75
- ${args.out_seconds !== undefined ? `
76
- var outTime = new Time();
77
- outTime.seconds = ${args.out_seconds};
78
- item.setOutPoint(outTime.ticks, 4);
79
- ` : ""}
80
-
81
- return __result({
82
- item: item.name,
83
- inSet: ${args.in_seconds !== undefined},
84
- outSet: ${args.out_seconds !== undefined}
85
- });
65
+ const script = buildToolScript(`
66
+ var item = app.sourceMonitor.getProjectItem();
67
+ if (!item) return __error("No clip open in Source Monitor");
68
+
69
+ ${args.in_seconds !== undefined ? `
70
+ var inTime = new Time();
71
+ inTime.seconds = ${args.in_seconds};
72
+ item.setInPoint(inTime.ticks, 4);
73
+ ` : ""}
74
+
75
+ ${args.out_seconds !== undefined ? `
76
+ var outTime = new Time();
77
+ outTime.seconds = ${args.out_seconds};
78
+ item.setOutPoint(outTime.ticks, 4);
79
+ ` : ""}
80
+
81
+ return __result({
82
+ item: item.name,
83
+ inSet: ${args.in_seconds !== undefined},
84
+ outSet: ${args.out_seconds !== undefined}
85
+ });
86
86
  `);
87
87
  return sendCommand(script, bridgeOptions);
88
88
  },
@@ -105,17 +105,17 @@ export function getSourceMonitorTools(bridgeOptions) {
105
105
  handler: async (args) => {
106
106
  const vTrack = args.video_track_index ?? 0;
107
107
  const aTrack = args.audio_track_index ?? 0;
108
- const script = buildToolScript(`
109
- var seq = app.project.activeSequence;
110
- if (!seq) return __error("No active sequence");
111
-
112
- var item = app.sourceMonitor.getProjectItem();
113
- if (!item) return __error("No clip open in Source Monitor");
114
-
115
- var pos = seq.getPlayerPosition().ticks;
116
- seq.insertClip(item, pos, ${vTrack}, ${aTrack});
117
-
118
- return __result({ inserted: true, item: item.name, atSeconds: __ticksToSeconds(pos) });
108
+ const script = buildToolScript(`
109
+ var seq = app.project.activeSequence;
110
+ if (!seq) return __error("No active sequence");
111
+
112
+ var item = app.sourceMonitor.getProjectItem();
113
+ if (!item) return __error("No clip open in Source Monitor");
114
+
115
+ var pos = seq.getPlayerPosition().ticks;
116
+ seq.insertClip(item, pos, ${vTrack}, ${aTrack});
117
+
118
+ return __result({ inserted: true, item: item.name, atSeconds: __ticksToSeconds(pos) });
119
119
  `);
120
120
  return sendCommand(script, bridgeOptions);
121
121
  },
@@ -138,17 +138,17 @@ export function getSourceMonitorTools(bridgeOptions) {
138
138
  handler: async (args) => {
139
139
  const vTrack = args.video_track_index ?? 0;
140
140
  const aTrack = args.audio_track_index ?? 0;
141
- const script = buildToolScript(`
142
- var seq = app.project.activeSequence;
143
- if (!seq) return __error("No active sequence");
144
-
145
- var item = app.sourceMonitor.getProjectItem();
146
- if (!item) return __error("No clip open in Source Monitor");
147
-
148
- var pos = seq.getPlayerPosition().ticks;
149
- seq.overwriteClip(item, pos, ${vTrack}, ${aTrack});
150
-
151
- return __result({ overwritten: true, item: item.name, atSeconds: __ticksToSeconds(pos) });
141
+ const script = buildToolScript(`
142
+ var seq = app.project.activeSequence;
143
+ if (!seq) return __error("No active sequence");
144
+
145
+ var item = app.sourceMonitor.getProjectItem();
146
+ if (!item) return __error("No clip open in Source Monitor");
147
+
148
+ var pos = seq.getPlayerPosition().ticks;
149
+ seq.overwriteClip(item, pos, ${vTrack}, ${aTrack});
150
+
151
+ return __result({ overwritten: true, item: item.name, atSeconds: __ticksToSeconds(pos) });
152
152
  `);
153
153
  return sendCommand(script, bridgeOptions);
154
154
  },
@@ -157,20 +157,20 @@ export function getSourceMonitorTools(bridgeOptions) {
157
157
  description: "Get information about the clip currently loaded in the Source Monitor.",
158
158
  parameters: {},
159
159
  handler: async () => {
160
- const script = buildToolScript(`
161
- var item = app.sourceMonitor.getProjectItem();
162
- if (!item) return __result({ loaded: false });
163
-
164
- var info = {
165
- loaded: true,
166
- nodeId: item.nodeId,
167
- name: item.name
168
- };
169
- try { info.mediaPath = item.getMediaPath(); } catch(e) {}
170
- try { info.inPoint = __ticksToSeconds(item.getInPoint().ticks); } catch(e) {}
171
- try { info.outPoint = __ticksToSeconds(item.getOutPoint().ticks); } catch(e) {}
172
-
173
- return __result(info);
160
+ const script = buildToolScript(`
161
+ var item = app.sourceMonitor.getProjectItem();
162
+ if (!item) return __result({ loaded: false });
163
+
164
+ var info = {
165
+ loaded: true,
166
+ nodeId: item.nodeId,
167
+ name: item.name
168
+ };
169
+ try { info.mediaPath = item.getMediaPath(); } catch(e) {}
170
+ try { info.inPoint = __ticksToSeconds(item.getInPoint().ticks); } catch(e) {}
171
+ try { info.outPoint = __ticksToSeconds(item.getOutPoint().ticks); } catch(e) {}
172
+
173
+ return __result(info);
174
174
  `);
175
175
  return sendCommand(script, bridgeOptions);
176
176
  },