@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
@@ -3,20 +3,20 @@ import { sendCommand } from "../bridge/file-bridge.js";
3
3
  export function getMediaTools(bridgeOptions) {
4
4
  return {
5
5
  import_media: {
6
- description: `Import one or more media files into the Premiere Pro project panel.
7
-
8
- Preconditions: A project must be open. File paths must be absolute paths accessible from the machine running Premiere Pro (not the MCP server).
9
-
10
- After import, use list_project_items to get the node IDs of the imported clips, which are needed for add_to_timeline and other operations.
11
-
12
- Supported formats: Video (MP4, MOV, MXF, AVI, R3D, BRAW), Audio (WAV, AIFF, MP3, AAC), Images (JPG, PNG, TIFF, PSD), and all other formats Premiere Pro supports.
13
-
14
- Parameters:
15
- - file_paths: Array of absolute file paths to import. Use forward slashes on macOS, backslashes on Windows.
16
- - target_bin: Optional bin name to import into (organize media). If omitted, imports to project root.
17
- - suppress_ui: Whether to skip import dialogs (default: true — recommended for automation).
18
-
19
- Example: import_media({ file_paths: ["C:\\\\Media\\\\interview.mp4", "C:\\\\Media\\\\broll.mp4"] })
6
+ description: `Import one or more media files into the Premiere Pro project panel.
7
+
8
+ Preconditions: A project must be open. File paths must be absolute paths accessible from the machine running Premiere Pro (not the MCP server).
9
+
10
+ After import, use list_project_items to get the node IDs of the imported clips, which are needed for add_to_timeline and other operations.
11
+
12
+ Supported formats: Video (MP4, MOV, MXF, AVI, R3D, BRAW), Audio (WAV, AIFF, MP3, AAC), Images (JPG, PNG, TIFF, PSD), and all other formats Premiere Pro supports.
13
+
14
+ Parameters:
15
+ - file_paths: Array of absolute file paths to import. Use forward slashes on macOS, backslashes on Windows.
16
+ - target_bin: Optional bin name to import into (organize media). If omitted, imports to project root.
17
+ - suppress_ui: Whether to skip import dialogs (default: true — recommended for automation).
18
+
19
+ Example: import_media({ file_paths: ["C:\\\\Media\\\\interview.mp4", "C:\\\\Media\\\\broll.mp4"] })
20
20
  Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin: "B-Roll" })`,
21
21
  parameters: {
22
22
  type: "object",
@@ -41,34 +41,34 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
41
41
  const paths = args.file_paths.map((p) => `"${escapeForExtendScript(p)}"`).join(", ");
42
42
  const suppress = args.suppress_ui !== false ? "true" : "false";
43
43
  const binLookup = args.target_bin
44
- ? `var targetBin = __findProjectItem("${escapeForExtendScript(args.target_bin)}");
44
+ ? `var targetBin = __findProjectItem("${escapeForExtendScript(args.target_bin)}");
45
45
  if (!targetBin) return __error("Bin not found: ${escapeForExtendScript(args.target_bin)}");`
46
46
  : `var targetBin = app.project.rootItem;`;
47
- const script = buildToolScript(`
48
- ${binLookup}
49
- var filePaths = [${paths}];
50
- // Check which files actually exist before importing
51
- var existingPaths = [];
52
- var missingPaths = [];
53
- for (var i = 0; i < filePaths.length; i++) {
54
- var f = new File(filePaths[i]);
55
- if (f.exists) {
56
- existingPaths.push(filePaths[i]);
57
- } else {
58
- missingPaths.push(filePaths[i]);
59
- }
60
- }
61
- if (existingPaths.length === 0) {
62
- return __error("No files found on disk. Check paths. Missing: " + missingPaths.join(", "));
63
- }
64
- var countBefore = targetBin.children ? targetBin.children.numItems : app.project.rootItem.children.numItems;
65
- var importSuccess = app.project.importFiles(existingPaths, ${suppress}, targetBin, false);
66
- var countAfter = targetBin.children ? targetBin.children.numItems : app.project.rootItem.children.numItems;
67
- var actualImported = countAfter - countBefore;
68
- var result = { imported: actualImported, requested: filePaths.length, files: existingPaths };
69
- if (missingPaths.length > 0) result.missing = missingPaths;
70
- if (actualImported === 0 && !importSuccess) return __error("Import failed — Premiere rejected all files");
71
- return __result(result);
47
+ const script = buildToolScript(`
48
+ ${binLookup}
49
+ var filePaths = [${paths}];
50
+ // Check which files actually exist before importing
51
+ var existingPaths = [];
52
+ var missingPaths = [];
53
+ for (var i = 0; i < filePaths.length; i++) {
54
+ var f = new File(filePaths[i]);
55
+ if (f.exists) {
56
+ existingPaths.push(filePaths[i]);
57
+ } else {
58
+ missingPaths.push(filePaths[i]);
59
+ }
60
+ }
61
+ if (existingPaths.length === 0) {
62
+ return __error("No files found on disk. Check paths. Missing: " + missingPaths.join(", "));
63
+ }
64
+ var countBefore = targetBin.children ? targetBin.children.numItems : app.project.rootItem.children.numItems;
65
+ var importSuccess = app.project.importFiles(existingPaths, ${suppress}, targetBin, false);
66
+ var countAfter = targetBin.children ? targetBin.children.numItems : app.project.rootItem.children.numItems;
67
+ var actualImported = countAfter - countBefore;
68
+ var result = { imported: actualImported, requested: filePaths.length, files: existingPaths };
69
+ if (missingPaths.length > 0) result.missing = missingPaths;
70
+ if (actualImported === 0 && !importSuccess) return __error("Import failed — Premiere rejected all files");
71
+ return __result(result);
72
72
  `);
73
73
  return sendCommand(script, bridgeOptions);
74
74
  },
@@ -86,25 +86,25 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
86
86
  required: ["folder_path"],
87
87
  },
88
88
  handler: async (args) => {
89
- const script = buildToolScript(`
90
- var folder = new Folder("${escapeForExtendScript(args.folder_path)}");
91
- if (!folder.exists) return __error("Folder not found: ${escapeForExtendScript(args.folder_path)}");
92
-
93
- var files = folder.getFiles();
94
- var filePaths = [];
95
- for (var i = 0; i < files.length; i++) {
96
- if (files[i] instanceof File) {
97
- filePaths.push(files[i].fsName);
98
- }
99
- }
100
-
101
- if (filePaths.length === 0) return __error("No files found in folder");
102
-
103
- var countBefore = app.project.rootItem.children.numItems;
104
- var importSuccess = app.project.importFiles(filePaths, true, app.project.rootItem, false);
105
- var countAfter = app.project.rootItem.children.numItems;
106
- var actualImported = countAfter - countBefore;
107
- return __result({ imported: actualImported, requested: filePaths.length, folder: "${escapeForExtendScript(args.folder_path)}" });
89
+ const script = buildToolScript(`
90
+ var folder = new Folder("${escapeForExtendScript(args.folder_path)}");
91
+ if (!folder.exists) return __error("Folder not found: ${escapeForExtendScript(args.folder_path)}");
92
+
93
+ var files = folder.getFiles();
94
+ var filePaths = [];
95
+ for (var i = 0; i < files.length; i++) {
96
+ if (files[i] instanceof File) {
97
+ filePaths.push(files[i].fsName);
98
+ }
99
+ }
100
+
101
+ if (filePaths.length === 0) return __error("No files found in folder");
102
+
103
+ var countBefore = app.project.rootItem.children.numItems;
104
+ var importSuccess = app.project.importFiles(filePaths, true, app.project.rootItem, false);
105
+ var countAfter = app.project.rootItem.children.numItems;
106
+ var actualImported = countAfter - countBefore;
107
+ return __result({ imported: actualImported, requested: filePaths.length, folder: "${escapeForExtendScript(args.folder_path)}" });
108
108
  `);
109
109
  return sendCommand(script, bridgeOptions);
110
110
  },
@@ -127,13 +127,13 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
127
127
  },
128
128
  handler: async (args) => {
129
129
  const parentLookup = args.parent_bin
130
- ? `var parent = __findProjectItem("${escapeForExtendScript(args.parent_bin)}");
130
+ ? `var parent = __findProjectItem("${escapeForExtendScript(args.parent_bin)}");
131
131
  if (!parent) return __error("Parent bin not found");`
132
132
  : `var parent = app.project.rootItem;`;
133
- const script = buildToolScript(`
134
- ${parentLookup}
135
- var newBin = parent.createBin("${escapeForExtendScript(args.name)}");
136
- return __result({ created: true, name: "${escapeForExtendScript(args.name)}", nodeId: newBin.nodeId });
133
+ const script = buildToolScript(`
134
+ ${parentLookup}
135
+ var newBin = parent.createBin("${escapeForExtendScript(args.name)}");
136
+ return __result({ created: true, name: "${escapeForExtendScript(args.name)}", nodeId: newBin.nodeId });
137
137
  `);
138
138
  return sendCommand(script, bridgeOptions);
139
139
  },
@@ -155,15 +155,15 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
155
155
  required: ["item_id", "target_bin"],
156
156
  },
157
157
  handler: async (args) => {
158
- const script = buildToolScript(`
159
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
160
- if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
161
-
162
- var targetBin = __findProjectItem("${escapeForExtendScript(args.target_bin)}");
163
- if (!targetBin) return __error("Target bin not found: ${escapeForExtendScript(args.target_bin)}");
164
-
165
- item.moveBin(targetBin);
166
- return __result({ moved: true, item: item.name, toBin: targetBin.name });
158
+ const script = buildToolScript(`
159
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
160
+ if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
161
+
162
+ var targetBin = __findProjectItem("${escapeForExtendScript(args.target_bin)}");
163
+ if (!targetBin) return __error("Target bin not found: ${escapeForExtendScript(args.target_bin)}");
164
+
165
+ item.moveBin(targetBin);
166
+ return __result({ moved: true, item: item.name, toBin: targetBin.name });
167
167
  `);
168
168
  return sendCommand(script, bridgeOptions);
169
169
  },
@@ -185,12 +185,12 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
185
185
  required: ["item_id", "new_path"],
186
186
  },
187
187
  handler: async (args) => {
188
- const script = buildToolScript(`
189
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
190
- if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
191
-
192
- var success = item.changeMediaPath("${escapeForExtendScript(args.new_path)}", true);
193
- return __result({ relinked: success, item: item.name, newPath: "${escapeForExtendScript(args.new_path)}" });
188
+ const script = buildToolScript(`
189
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
190
+ if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
191
+
192
+ var success = item.changeMediaPath("${escapeForExtendScript(args.new_path)}", true);
193
+ return __result({ relinked: success, item: item.name, newPath: "${escapeForExtendScript(args.new_path)}" });
194
194
  `);
195
195
  return sendCommand(script, bridgeOptions);
196
196
  },
@@ -208,11 +208,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
208
208
  required: ["item_id"],
209
209
  },
210
210
  handler: async (args) => {
211
- const script = buildToolScript(`
212
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
213
- if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
214
- item.refreshMedia();
215
- return __result({ refreshed: true, item: item.name });
211
+ const script = buildToolScript(`
212
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
213
+ if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
214
+ item.refreshMedia();
215
+ return __result({ refreshed: true, item: item.name });
216
216
  `);
217
217
  return sendCommand(script, bridgeOptions);
218
218
  },
@@ -221,34 +221,34 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
221
221
  description: "Check for offline (missing) media in the project",
222
222
  parameters: {},
223
223
  handler: async () => {
224
- const script = buildToolScript(`
225
- var offlineItems = [];
226
-
227
- function checkItem(item) {
228
- if (item.type === 1) {
229
- try {
230
- if (__readMaybe(item, "isOffline", false)) {
231
- offlineItems.push({
232
- nodeId: item.nodeId,
233
- name: item.name,
234
- mediaPath: item.getMediaPath ? item.getMediaPath() : ""
235
- });
236
- }
237
- } catch(e) {}
238
- }
239
- if (item.type === 2 && item.children) {
240
- for (var i = 0; i < item.children.numItems; i++) {
241
- checkItem(item.children[i]);
242
- }
243
- }
244
- }
245
-
246
- var root = app.project.rootItem;
247
- for (var i = 0; i < root.children.numItems; i++) {
248
- checkItem(root.children[i]);
249
- }
250
-
251
- return __result({ offlineCount: offlineItems.length, items: offlineItems });
224
+ const script = buildToolScript(`
225
+ var offlineItems = [];
226
+
227
+ function checkItem(item) {
228
+ if (item.type === 1) {
229
+ try {
230
+ if (__readMaybe(item, "isOffline", false)) {
231
+ offlineItems.push({
232
+ nodeId: item.nodeId,
233
+ name: item.name,
234
+ mediaPath: item.getMediaPath ? item.getMediaPath() : ""
235
+ });
236
+ }
237
+ } catch(e) {}
238
+ }
239
+ if (item.type === 2 && item.children) {
240
+ for (var i = 0; i < item.children.numItems; i++) {
241
+ checkItem(item.children[i]);
242
+ }
243
+ }
244
+ }
245
+
246
+ var root = app.project.rootItem;
247
+ for (var i = 0; i < root.children.numItems; i++) {
248
+ checkItem(root.children[i]);
249
+ }
250
+
251
+ return __result({ offlineCount: offlineItems.length, items: offlineItems });
252
252
  `);
253
253
  return sendCommand(script, bridgeOptions);
254
254
  },
@@ -266,11 +266,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
266
266
  required: ["item_id"],
267
267
  },
268
268
  handler: async (args) => {
269
- const script = buildToolScript(`
270
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
271
- if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
272
- item.setOffline();
273
- return __result({ offline: true, item: item.name });
269
+ const script = buildToolScript(`
270
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
271
+ if (!item) return __error("Item not found: ${escapeForExtendScript(args.item_id)}");
272
+ item.setOffline();
273
+ return __result({ offline: true, item: item.name });
274
274
  `);
275
275
  return sendCommand(script, bridgeOptions);
276
276
  },
@@ -288,16 +288,16 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
288
288
  required: ["item_id"],
289
289
  },
290
290
  handler: async (args) => {
291
- const script = buildToolScript(`
292
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
293
- if (!item) return __error("Item not found");
294
-
295
- var info = { item: item.name };
296
- try { info.hasProxy = item.hasProxy(); } catch(e) { info.hasProxy = false; }
297
- try { info.canProxy = item.canProxy(); } catch(e) { info.canProxy = false; }
298
- try { info.proxyPath = item.getProxyPath(); } catch(e) {}
299
-
300
- return __result(info);
291
+ const script = buildToolScript(`
292
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
293
+ if (!item) return __error("Item not found");
294
+
295
+ var info = { item: item.name };
296
+ try { info.hasProxy = item.hasProxy(); } catch(e) { info.hasProxy = false; }
297
+ try { info.canProxy = item.canProxy(); } catch(e) { info.canProxy = false; }
298
+ try { info.proxyPath = item.getProxyPath(); } catch(e) {}
299
+
300
+ return __result(info);
301
301
  `);
302
302
  return sendCommand(script, bridgeOptions);
303
303
  },
@@ -315,11 +315,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
315
315
  required: ["item_id"],
316
316
  },
317
317
  handler: async (args) => {
318
- const script = buildToolScript(`
319
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
320
- if (!item) return __error("Item not found");
321
- item.detachProxy();
322
- return __result({ detached: true, item: item.name });
318
+ const script = buildToolScript(`
319
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
320
+ if (!item) return __error("Item not found");
321
+ item.detachProxy();
322
+ return __result({ detached: true, item: item.name });
323
323
  `);
324
324
  return sendCommand(script, bridgeOptions);
325
325
  },
@@ -341,11 +341,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
341
341
  required: ["item_id", "frame_rate"],
342
342
  },
343
343
  handler: async (args) => {
344
- const script = buildToolScript(`
345
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
346
- if (!item) return __error("Item not found");
347
- item.setOverrideFrameRate(${args.frame_rate});
348
- return __result({ set: true, item: item.name, frameRate: ${args.frame_rate} });
344
+ const script = buildToolScript(`
345
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
346
+ if (!item) return __error("Item not found");
347
+ item.setOverrideFrameRate(${args.frame_rate});
348
+ return __result({ set: true, item: item.name, frameRate: ${args.frame_rate} });
349
349
  `);
350
350
  return sendCommand(script, bridgeOptions);
351
351
  },
@@ -371,11 +371,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
371
371
  required: ["item_id", "numerator", "denominator"],
372
372
  },
373
373
  handler: async (args) => {
374
- const script = buildToolScript(`
375
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
376
- if (!item) return __error("Item not found");
377
- item.setOverridePixelAspectRatio(${args.numerator}, ${args.denominator});
378
- return __result({ set: true, item: item.name, par: "${args.numerator}:${args.denominator}" });
374
+ const script = buildToolScript(`
375
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
376
+ if (!item) return __error("Item not found");
377
+ item.setOverridePixelAspectRatio(${args.numerator}, ${args.denominator});
378
+ return __result({ set: true, item: item.name, par: "${args.numerator}:${args.denominator}" });
379
379
  `);
380
380
  return sendCommand(script, bridgeOptions);
381
381
  },
@@ -393,11 +393,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
393
393
  required: ["item_id"],
394
394
  },
395
395
  handler: async (args) => {
396
- const script = buildToolScript(`
397
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
398
- if (!item) return __error("Item not found");
399
- item.setScaleToFrameSize();
400
- return __result({ set: true, item: item.name });
396
+ const script = buildToolScript(`
397
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
398
+ if (!item) return __error("Item not found");
399
+ item.setScaleToFrameSize();
400
+ return __result({ set: true, item: item.name });
401
401
  `);
402
402
  return sendCommand(script, bridgeOptions);
403
403
  },
@@ -415,25 +415,25 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
415
415
  required: ["item_id"],
416
416
  },
417
417
  handler: async (args) => {
418
- const script = buildToolScript(`
419
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
420
- if (!item) return __error("Item not found");
421
-
422
- var info = {
423
- name: item.name,
424
- nodeId: item.nodeId,
425
- type: item.type === 1 ? "clip" : item.type === 2 ? "bin" : item.type === 3 ? "sequence" : "unknown",
426
- treePath: item.treePath
427
- };
428
- info.isSequence = __readMaybe(item, "isSequence", false);
429
- info.isMulticamClip = __readMaybe(item, "isMulticamClip", false);
430
- info.isMergedClip = __readMaybe(item, "isMergedClip", false);
431
- info.isOffline = __readMaybe(item, "isOffline", false);
432
- try { info.mediaPath = item.getMediaPath(); } catch(e) {}
433
- try { info.hasProxy = item.hasProxy(); } catch(e) {}
434
- try { info.canProxy = item.canProxy(); } catch(e) {}
435
-
436
- return __result(info);
418
+ const script = buildToolScript(`
419
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
420
+ if (!item) return __error("Item not found");
421
+
422
+ var info = {
423
+ name: item.name,
424
+ nodeId: item.nodeId,
425
+ type: item.type === 1 ? "clip" : item.type === 2 ? "bin" : item.type === 3 ? "sequence" : "unknown",
426
+ treePath: item.treePath
427
+ };
428
+ info.isSequence = __readMaybe(item, "isSequence", false);
429
+ info.isMulticamClip = __readMaybe(item, "isMulticamClip", false);
430
+ info.isMergedClip = __readMaybe(item, "isMergedClip", false);
431
+ info.isOffline = __readMaybe(item, "isOffline", false);
432
+ try { info.mediaPath = item.getMediaPath(); } catch(e) {}
433
+ try { info.hasProxy = item.hasProxy(); } catch(e) {}
434
+ try { info.canProxy = item.canProxy(); } catch(e) {}
435
+
436
+ return __result(info);
437
437
  `);
438
438
  return sendCommand(script, bridgeOptions);
439
439
  },
@@ -451,11 +451,11 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
451
451
  required: ["item_id"],
452
452
  },
453
453
  handler: async (args) => {
454
- const script = buildToolScript(`
455
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
456
- if (!item) return __error("Item not found");
457
- item.select();
458
- return __result({ selected: true, item: item.name });
454
+ const script = buildToolScript(`
455
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
456
+ if (!item) return __error("Item not found");
457
+ item.select();
458
+ return __result({ selected: true, item: item.name });
459
459
  `);
460
460
  return sendCommand(script, bridgeOptions);
461
461
  },
@@ -477,13 +477,13 @@ Example: import_media({ file_paths: ["/Users/me/footage/clip.mov"], target_bin:
477
477
  required: ["item_id", "start_seconds"],
478
478
  },
479
479
  handler: async (args) => {
480
- const script = buildToolScript(`
481
- var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
482
- if (!item) return __error("Item not found");
483
-
484
- var ticks = __secondsToTicks(${args.start_seconds}).toString();
485
- item.setStartTime(ticks);
486
- return __result({ set: true, item: item.name, startSeconds: ${args.start_seconds} });
480
+ const script = buildToolScript(`
481
+ var item = __findProjectItem("${escapeForExtendScript(args.item_id)}");
482
+ if (!item) return __error("Item not found");
483
+
484
+ var ticks = __secondsToTicks(${args.start_seconds}).toString();
485
+ item.setStartTime(ticks);
486
+ return __result({ set: true, item: item.name, startSeconds: ${args.start_seconds} });
487
487
  `);
488
488
  return sendCommand(script, bridgeOptions);
489
489
  },