@synthetic-ai/premiere-mcp 2.1.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 (58) hide show
  1. package/CHANGELOG.md +135 -123
  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/index.js +103 -4
  12. package/dist/license.js +38 -0
  13. package/dist/server.js +60 -60
  14. package/dist/tools/advanced.js +357 -357
  15. package/dist/tools/audio-advanced.js +1049 -1049
  16. package/dist/tools/audio.js +42 -42
  17. package/dist/tools/captions.js +27 -27
  18. package/dist/tools/clipboard.js +214 -214
  19. package/dist/tools/color-advanced.js +253 -253
  20. package/dist/tools/discovery.js +291 -291
  21. package/dist/tools/effects.js +285 -285
  22. package/dist/tools/export-presets.js +206 -206
  23. package/dist/tools/export.js +255 -255
  24. package/dist/tools/health.js +10 -10
  25. package/dist/tools/inspection.js +885 -885
  26. package/dist/tools/keyframes.js +369 -369
  27. package/dist/tools/markers.js +89 -89
  28. package/dist/tools/media.js +178 -178
  29. package/dist/tools/metadata.js +94 -94
  30. package/dist/tools/multicam.js +50 -50
  31. package/dist/tools/playback.js +15 -15
  32. package/dist/tools/playhead.js +95 -95
  33. package/dist/tools/project-manager.js +21 -21
  34. package/dist/tools/project.js +149 -149
  35. package/dist/tools/scripting.js +319 -319
  36. package/dist/tools/selection.js +202 -202
  37. package/dist/tools/sequence-advanced.js +379 -379
  38. package/dist/tools/sequence-settings.js +564 -564
  39. package/dist/tools/sequence.js +167 -167
  40. package/dist/tools/source-monitor.js +68 -68
  41. package/dist/tools/text.js +58 -58
  42. package/dist/tools/timeline.js +312 -312
  43. package/dist/tools/track-management.js +446 -446
  44. package/dist/tools/track-targeting.js +635 -635
  45. package/dist/tools/tracks.js +87 -87
  46. package/dist/tools/transitions-motion.js +174 -174
  47. package/dist/tools/transitions.js +111 -111
  48. package/dist/tools/utility.js +606 -606
  49. package/dist/tools/workspace.js +29 -29
  50. package/package.json +66 -66
  51. package/scripts/build-chat-dmg.sh +210 -210
  52. package/scripts/build-chat-zip.sh +291 -291
  53. package/scripts/install-cep-windows.ps1 +99 -99
  54. package/scripts/install-cep.sh +66 -66
  55. package/scripts/install-chat-plugin.bat +67 -67
  56. package/scripts/install-chat-plugin.sh +85 -85
  57. package/scripts/install-windows.bat +95 -95
  58. 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
  },