@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,45 +3,45 @@ import { sendCommand, sendRawCommand } from "../bridge/file-bridge.js";
3
3
  export function getScriptingTools(bridgeOptions) {
4
4
  return {
5
5
  execute_extendscript: {
6
- description: `Execute custom ExtendScript code in Premiere Pro. The code runs inside an IIFE with helper functions available.
7
-
8
- IMPORTANT: You MUST write ES3 syntax (var instead of let/const, no arrow functions, no template literals, no destructuring).
9
-
10
- Available helpers (auto-prepended):
11
- - __ticksToSeconds(ticks) / __secondsToTicks(seconds) — time conversion
12
- - __ticksToTimecode(ticks, fps) — timecode string
13
- - __findSequence(idOrName) — find sequence by name or ID
14
- - __findProjectItem(nodeIdOrName) — find project item recursively
15
- - __findClip(nodeId) — find clip in active sequence, returns {clip, trackIndex, clipIndex, trackType}
16
- - __getAllClips(seq) — get all clips in a sequence
17
- - __result(data) — return success with data (MUST call this or __error)
18
- - __error(msg) — return error message
19
- - TICKS_PER_SECOND — constant 254016000000
20
- - app.enableQE() — enable QE DOM access
21
-
22
- Your code MUST end with: return __result({...}) or return __error("message")
23
-
24
- Example: Set opacity to 50% on all video clips
25
- var seq = app.project.activeSequence;
26
- if (!seq) return __error("No active sequence");
27
- var count = 0;
28
- for (var t = 0; t < seq.videoTracks.numTracks; t++) {
29
- var track = seq.videoTracks[t];
30
- for (var c = 0; c < track.clips.numItems; c++) {
31
- var clip = track.clips[c];
32
- for (var i = 0; i < clip.components.numItems; i++) {
33
- var comp = clip.components[i];
34
- if (comp.displayName === "Opacity") {
35
- for (var p = 0; p < comp.properties.numItems; p++) {
36
- if (comp.properties[p].displayName === "Opacity") {
37
- comp.properties[p].setValue(50, true);
38
- count++;
39
- }
40
- }
41
- }
42
- }
43
- }
44
- }
6
+ description: `Execute custom ExtendScript code in Premiere Pro. The code runs inside an IIFE with helper functions available.
7
+
8
+ IMPORTANT: You MUST write ES3 syntax (var instead of let/const, no arrow functions, no template literals, no destructuring).
9
+
10
+ Available helpers (auto-prepended):
11
+ - __ticksToSeconds(ticks) / __secondsToTicks(seconds) — time conversion
12
+ - __ticksToTimecode(ticks, fps) — timecode string
13
+ - __findSequence(idOrName) — find sequence by name or ID
14
+ - __findProjectItem(nodeIdOrName) — find project item recursively
15
+ - __findClip(nodeId) — find clip in active sequence, returns {clip, trackIndex, clipIndex, trackType}
16
+ - __getAllClips(seq) — get all clips in a sequence
17
+ - __result(data) — return success with data (MUST call this or __error)
18
+ - __error(msg) — return error message
19
+ - TICKS_PER_SECOND — constant 254016000000
20
+ - app.enableQE() — enable QE DOM access
21
+
22
+ Your code MUST end with: return __result({...}) or return __error("message")
23
+
24
+ Example: Set opacity to 50% on all video clips
25
+ var seq = app.project.activeSequence;
26
+ if (!seq) return __error("No active sequence");
27
+ var count = 0;
28
+ for (var t = 0; t < seq.videoTracks.numTracks; t++) {
29
+ var track = seq.videoTracks[t];
30
+ for (var c = 0; c < track.clips.numItems; c++) {
31
+ var clip = track.clips[c];
32
+ for (var i = 0; i < clip.components.numItems; i++) {
33
+ var comp = clip.components[i];
34
+ if (comp.displayName === "Opacity") {
35
+ for (var p = 0; p < comp.properties.numItems; p++) {
36
+ if (comp.properties[p].displayName === "Opacity") {
37
+ comp.properties[p].setValue(50, true);
38
+ count++;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }
45
45
  return __result({updated: count});`,
46
46
  parameters: {
47
47
  type: "object",
@@ -67,13 +67,13 @@ Example: Set opacity to 50% on all video clips
67
67
  },
68
68
  },
69
69
  evaluate_expression: {
70
- description: `Evaluate a simple ExtendScript expression and return its value. Use for quick queries like checking a property, getting a count, or reading state. The expression should be a single value/call — NOT a full script.
71
-
72
- Examples:
73
- - "app.project.name" → project name
74
- - "app.project.activeSequence.name" → active sequence name
75
- - "app.project.rootItem.children.numItems" → number of root items
76
- - "app.project.activeSequence.videoTracks.numTracks" → number of video tracks
70
+ description: `Evaluate a simple ExtendScript expression and return its value. Use for quick queries like checking a property, getting a count, or reading state. The expression should be a single value/call — NOT a full script.
71
+
72
+ Examples:
73
+ - "app.project.name" → project name
74
+ - "app.project.activeSequence.name" → active sequence name
75
+ - "app.project.rootItem.children.numItems" → number of root items
76
+ - "app.project.activeSequence.videoTracks.numTracks" → number of video tracks
77
77
  - "app.version" → Premiere Pro version`,
78
78
  parameters: {
79
79
  type: "object",
@@ -86,24 +86,24 @@ Examples:
86
86
  required: ["expression"],
87
87
  },
88
88
  handler: async (args) => {
89
- const script = buildToolScript(`
90
- try {
91
- var val = ${args.expression};
92
- return __result({ value: val, type: typeof val });
93
- } catch(e) {
94
- return __error("Expression error: " + e.toString());
95
- }
89
+ const script = buildToolScript(`
90
+ try {
91
+ var val = ${args.expression};
92
+ return __result({ value: val, type: typeof val });
93
+ } catch(e) {
94
+ return __error("Expression error: " + e.toString());
95
+ }
96
96
  `);
97
97
  return sendRawCommand(script, bridgeOptions);
98
98
  },
99
99
  },
100
100
  inspect_dom_object: {
101
- description: `Inspect a Premiere Pro DOM object and list its properties, methods, and values. Useful for exploring the API and debugging.
102
-
103
- Examples:
104
- - "app.project" → project properties
105
- - "app.project.activeSequence" → sequence properties
106
- - "app.project.activeSequence.videoTracks[0].clips[0]" → first clip on V1
101
+ description: `Inspect a Premiere Pro DOM object and list its properties, methods, and values. Useful for exploring the API and debugging.
102
+
103
+ Examples:
104
+ - "app.project" → project properties
105
+ - "app.project.activeSequence" → sequence properties
106
+ - "app.project.activeSequence.videoTracks[0].clips[0]" → first clip on V1
107
107
  - "app.project.activeSequence.videoTracks[0].clips[0].components[0]" → first component of a clip`,
108
108
  parameters: {
109
109
  type: "object",
@@ -121,70 +121,70 @@ Examples:
121
121
  },
122
122
  handler: async (args) => {
123
123
  const maxDepth = Math.min(args.max_depth ?? 1, 3);
124
- const script = buildToolScript(`
125
- function inspectObj(obj, depth, maxD) {
126
- if (depth > maxD) return "<max depth>";
127
- if (obj === null) return null;
128
- if (obj === undefined) return undefined;
129
- var t = typeof obj;
130
- if (t === "string" || t === "number" || t === "boolean") return obj;
131
-
132
- var result = {};
133
- var propCount = 0;
134
- try {
135
- for (var key in obj) {
136
- if (propCount > 50) {
137
- result["__truncated"] = true;
138
- break;
139
- }
140
- try {
141
- var val = obj[key];
142
- var vt = typeof val;
143
- if (vt === "function") {
144
- result[key] = "[function]";
145
- } else if (vt === "object" && val !== null) {
146
- if (depth < maxD) {
147
- result[key] = inspectObj(val, depth + 1, maxD);
148
- } else {
149
- result[key] = "[object]";
150
- }
151
- } else {
152
- result[key] = val;
153
- }
154
- } catch(e) {
155
- result[key] = "[error: " + e.toString() + "]";
156
- }
157
- propCount++;
158
- }
159
- } catch(e) {
160
- return { __error: e.toString() };
161
- }
162
-
163
- // Also try common collection properties
164
- try { if (obj.numItems !== undefined) result["numItems"] = obj.numItems; } catch(e) {}
165
- try { if (obj.numTracks !== undefined) result["numTracks"] = obj.numTracks; } catch(e) {}
166
- try { if (obj.numSequences !== undefined) result["numSequences"] = obj.numSequences; } catch(e) {}
167
- try { if (obj.length !== undefined) result["length"] = obj.length; } catch(e) {}
168
- try { if (obj.name !== undefined) result["name"] = obj.name; } catch(e) {}
169
- try { if (obj.displayName !== undefined) result["displayName"] = obj.displayName; } catch(e) {}
170
- try { if (obj.matchName !== undefined) result["matchName"] = obj.matchName; } catch(e) {}
171
- try { if (obj.nodeId !== undefined) result["nodeId"] = obj.nodeId; } catch(e) {}
172
-
173
- return result;
174
- }
175
-
176
- try {
177
- var obj = ${args.object_path};
178
- if (obj === null || obj === undefined) return __error("Object is null or undefined: ${args.object_path}");
179
- var inspection = inspectObj(obj, 0, ${maxDepth});
180
- return __result({
181
- path: "${args.object_path}",
182
- type: typeof obj,
183
- inspection: inspection
184
- });
185
- } catch(e) {
186
- return __error("Cannot access: ${args.object_path} — " + e.toString());
187
- }
124
+ const script = buildToolScript(`
125
+ function inspectObj(obj, depth, maxD) {
126
+ if (depth > maxD) return "<max depth>";
127
+ if (obj === null) return null;
128
+ if (obj === undefined) return undefined;
129
+ var t = typeof obj;
130
+ if (t === "string" || t === "number" || t === "boolean") return obj;
131
+
132
+ var result = {};
133
+ var propCount = 0;
134
+ try {
135
+ for (var key in obj) {
136
+ if (propCount > 50) {
137
+ result["__truncated"] = true;
138
+ break;
139
+ }
140
+ try {
141
+ var val = obj[key];
142
+ var vt = typeof val;
143
+ if (vt === "function") {
144
+ result[key] = "[function]";
145
+ } else if (vt === "object" && val !== null) {
146
+ if (depth < maxD) {
147
+ result[key] = inspectObj(val, depth + 1, maxD);
148
+ } else {
149
+ result[key] = "[object]";
150
+ }
151
+ } else {
152
+ result[key] = val;
153
+ }
154
+ } catch(e) {
155
+ result[key] = "[error: " + e.toString() + "]";
156
+ }
157
+ propCount++;
158
+ }
159
+ } catch(e) {
160
+ return { __error: e.toString() };
161
+ }
162
+
163
+ // Also try common collection properties
164
+ try { if (obj.numItems !== undefined) result["numItems"] = obj.numItems; } catch(e) {}
165
+ try { if (obj.numTracks !== undefined) result["numTracks"] = obj.numTracks; } catch(e) {}
166
+ try { if (obj.numSequences !== undefined) result["numSequences"] = obj.numSequences; } catch(e) {}
167
+ try { if (obj.length !== undefined) result["length"] = obj.length; } catch(e) {}
168
+ try { if (obj.name !== undefined) result["name"] = obj.name; } catch(e) {}
169
+ try { if (obj.displayName !== undefined) result["displayName"] = obj.displayName; } catch(e) {}
170
+ try { if (obj.matchName !== undefined) result["matchName"] = obj.matchName; } catch(e) {}
171
+ try { if (obj.nodeId !== undefined) result["nodeId"] = obj.nodeId; } catch(e) {}
172
+
173
+ return result;
174
+ }
175
+
176
+ try {
177
+ var obj = ${args.object_path};
178
+ if (obj === null || obj === undefined) return __error("Object is null or undefined: ${args.object_path}");
179
+ var inspection = inspectObj(obj, 0, ${maxDepth});
180
+ return __result({
181
+ path: "${args.object_path}",
182
+ type: typeof obj,
183
+ inspection: inspection
184
+ });
185
+ } catch(e) {
186
+ return __error("Cannot access: ${args.object_path} — " + e.toString());
187
+ }
188
188
  `);
189
189
  return sendRawCommand(script, bridgeOptions);
190
190
  },
@@ -202,45 +202,45 @@ Examples:
202
202
  required: ["node_id"],
203
203
  },
204
204
  handler: async (args) => {
205
- const script = buildToolScript(`
206
- var result = __findClip("${escapeForExtendScript(args.node_id)}");
207
- if (!result) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
208
-
209
- var clip = result.clip;
210
- var components = [];
211
-
212
- for (var i = 0; i < clip.components.numItems; i++) {
213
- var comp = clip.components[i];
214
- var props = [];
215
- for (var p = 0; p < comp.properties.numItems; p++) {
216
- var prop = comp.properties[p];
217
- var info = {
218
- index: p,
219
- displayName: prop.displayName,
220
- matchName: ""
221
- };
222
- try { info.matchName = prop.matchName; } catch(e) {}
223
- try { info.value = prop.getValue(0, 0); } catch(e) {}
224
- try { info.isTimeVarying = prop.isTimeVarying(); } catch(e) {}
225
- try { info.keyframesSupported = prop.areKeyframesSupported(); } catch(e) {}
226
- props.push(info);
227
- }
228
- components.push({
229
- index: i,
230
- displayName: comp.displayName,
231
- matchName: comp.matchName,
232
- properties: props
233
- });
234
- }
235
-
236
- return __result({
237
- clipName: clip.name,
238
- nodeId: clip.nodeId,
239
- trackType: result.trackType,
240
- trackIndex: result.trackIndex,
241
- componentCount: components.length,
242
- components: components
243
- });
205
+ const script = buildToolScript(`
206
+ var result = __findClip("${escapeForExtendScript(args.node_id)}");
207
+ if (!result) return __error("Clip not found: ${escapeForExtendScript(args.node_id)}");
208
+
209
+ var clip = result.clip;
210
+ var components = [];
211
+
212
+ for (var i = 0; i < clip.components.numItems; i++) {
213
+ var comp = clip.components[i];
214
+ var props = [];
215
+ for (var p = 0; p < comp.properties.numItems; p++) {
216
+ var prop = comp.properties[p];
217
+ var info = {
218
+ index: p,
219
+ displayName: prop.displayName,
220
+ matchName: ""
221
+ };
222
+ try { info.matchName = prop.matchName; } catch(e) {}
223
+ try { info.value = prop.getValue(0, 0); } catch(e) {}
224
+ try { info.isTimeVarying = prop.isTimeVarying(); } catch(e) {}
225
+ try { info.keyframesSupported = prop.areKeyframesSupported(); } catch(e) {}
226
+ props.push(info);
227
+ }
228
+ components.push({
229
+ index: i,
230
+ displayName: comp.displayName,
231
+ matchName: comp.matchName,
232
+ properties: props
233
+ });
234
+ }
235
+
236
+ return __result({
237
+ clipName: clip.name,
238
+ nodeId: clip.nodeId,
239
+ trackType: result.trackType,
240
+ trackIndex: result.trackIndex,
241
+ componentCount: components.length,
242
+ components: components
243
+ });
244
244
  `);
245
245
  return sendCommand(script, bridgeOptions);
246
246
  },
@@ -260,78 +260,78 @@ Examples:
260
260
  const seqLookup = args.sequence_id
261
261
  ? `var seq = __findSequence("${args.sequence_id}"); if (!seq) return __error("Sequence not found");`
262
262
  : `var seq = app.project.activeSequence; if (!seq) return __error("No active sequence");`;
263
- const script = buildToolScript(`
264
- ${seqLookup}
265
-
266
- var videoTracks = [];
267
- for (var t = 0; t < seq.videoTracks.numTracks; t++) {
268
- var track = seq.videoTracks[t];
269
- var clips = [];
270
- for (var c = 0; c < track.clips.numItems; c++) {
271
- var clip = track.clips[c];
272
- var clipInfo = {
273
- index: c,
274
- nodeId: clip.nodeId,
275
- name: clip.name,
276
- startSeconds: __ticksToSeconds(clip.start.ticks),
277
- endSeconds: __ticksToSeconds(clip.end.ticks),
278
- durationSeconds: __ticksToSeconds(clip.duration.ticks),
279
- inPointSeconds: __ticksToSeconds(clip.inPoint.ticks),
280
- outPointSeconds: __ticksToSeconds(clip.outPoint.ticks),
281
- mediaType: clip.mediaType,
282
- enabled: true
283
- };
284
- try { clipInfo.enabled = !clip.isDisabled(); } catch(e) {}
285
- try { clipInfo.speed = clip.getSpeed(); } catch(e) {}
286
- clips.push(clipInfo);
287
- }
288
- videoTracks.push({
289
- index: t,
290
- name: track.name,
291
- clipCount: clips.length,
292
- clips: clips,
293
- isMuted: track.isMuted(),
294
- isLocked: track.isLocked()
295
- });
296
- }
297
-
298
- var audioTracks = [];
299
- for (var t = 0; t < seq.audioTracks.numTracks; t++) {
300
- var track = seq.audioTracks[t];
301
- var clips = [];
302
- for (var c = 0; c < track.clips.numItems; c++) {
303
- var clip = track.clips[c];
304
- clips.push({
305
- index: c,
306
- nodeId: clip.nodeId,
307
- name: clip.name,
308
- startSeconds: __ticksToSeconds(clip.start.ticks),
309
- endSeconds: __ticksToSeconds(clip.end.ticks),
310
- durationSeconds: __ticksToSeconds(clip.duration.ticks),
311
- inPointSeconds: __ticksToSeconds(clip.inPoint.ticks),
312
- outPointSeconds: __ticksToSeconds(clip.outPoint.ticks),
313
- mediaType: clip.mediaType
314
- });
315
- }
316
- audioTracks.push({
317
- index: t,
318
- name: track.name,
319
- clipCount: clips.length,
320
- clips: clips,
321
- isMuted: track.isMuted(),
322
- isLocked: track.isLocked()
323
- });
324
- }
325
-
326
- return __result({
327
- name: seq.name,
328
- id: seq.sequenceID,
329
- durationSeconds: __ticksToSeconds(seq.end),
330
- videoTrackCount: videoTracks.length,
331
- audioTrackCount: audioTracks.length,
332
- videoTracks: videoTracks,
333
- audioTracks: audioTracks
334
- });
263
+ const script = buildToolScript(`
264
+ ${seqLookup}
265
+
266
+ var videoTracks = [];
267
+ for (var t = 0; t < seq.videoTracks.numTracks; t++) {
268
+ var track = seq.videoTracks[t];
269
+ var clips = [];
270
+ for (var c = 0; c < track.clips.numItems; c++) {
271
+ var clip = track.clips[c];
272
+ var clipInfo = {
273
+ index: c,
274
+ nodeId: clip.nodeId,
275
+ name: clip.name,
276
+ startSeconds: __ticksToSeconds(clip.start.ticks),
277
+ endSeconds: __ticksToSeconds(clip.end.ticks),
278
+ durationSeconds: __ticksToSeconds(clip.duration.ticks),
279
+ inPointSeconds: __ticksToSeconds(clip.inPoint.ticks),
280
+ outPointSeconds: __ticksToSeconds(clip.outPoint.ticks),
281
+ mediaType: clip.mediaType,
282
+ enabled: true
283
+ };
284
+ try { clipInfo.enabled = !clip.isDisabled(); } catch(e) {}
285
+ try { clipInfo.speed = clip.getSpeed(); } catch(e) {}
286
+ clips.push(clipInfo);
287
+ }
288
+ videoTracks.push({
289
+ index: t,
290
+ name: track.name,
291
+ clipCount: clips.length,
292
+ clips: clips,
293
+ isMuted: track.isMuted(),
294
+ isLocked: track.isLocked()
295
+ });
296
+ }
297
+
298
+ var audioTracks = [];
299
+ for (var t = 0; t < seq.audioTracks.numTracks; t++) {
300
+ var track = seq.audioTracks[t];
301
+ var clips = [];
302
+ for (var c = 0; c < track.clips.numItems; c++) {
303
+ var clip = track.clips[c];
304
+ clips.push({
305
+ index: c,
306
+ nodeId: clip.nodeId,
307
+ name: clip.name,
308
+ startSeconds: __ticksToSeconds(clip.start.ticks),
309
+ endSeconds: __ticksToSeconds(clip.end.ticks),
310
+ durationSeconds: __ticksToSeconds(clip.duration.ticks),
311
+ inPointSeconds: __ticksToSeconds(clip.inPoint.ticks),
312
+ outPointSeconds: __ticksToSeconds(clip.outPoint.ticks),
313
+ mediaType: clip.mediaType
314
+ });
315
+ }
316
+ audioTracks.push({
317
+ index: t,
318
+ name: track.name,
319
+ clipCount: clips.length,
320
+ clips: clips,
321
+ isMuted: track.isMuted(),
322
+ isLocked: track.isLocked()
323
+ });
324
+ }
325
+
326
+ return __result({
327
+ name: seq.name,
328
+ id: seq.sequenceID,
329
+ durationSeconds: __ticksToSeconds(seq.end),
330
+ videoTrackCount: videoTracks.length,
331
+ audioTrackCount: audioTracks.length,
332
+ videoTracks: videoTracks,
333
+ audioTracks: audioTracks
334
+ });
335
335
  `);
336
336
  return sendCommand(script, bridgeOptions);
337
337
  },
@@ -340,91 +340,91 @@ Examples:
340
340
  description: "Get a comprehensive snapshot of the current Premiere Pro state: project info, active sequence, playhead position, selected clips, and available sequences. The best first call to understand the current context.",
341
341
  parameters: {},
342
342
  handler: async () => {
343
- const script = buildToolScript(`
344
- var state = {};
345
-
346
- // Project info
347
- var project = app.project;
348
- if (!project) return __error("No project is open");
349
- state.project = {
350
- name: project.name,
351
- path: project.path,
352
- rootItemCount: project.rootItem.children.numItems,
353
- sequenceCount: project.sequences.numSequences
354
- };
355
-
356
- // List all sequences
357
- state.sequences = [];
358
- for (var i = 0; i < project.sequences.numSequences; i++) {
359
- var seq = project.sequences[i];
360
- var seqDuration = null;
361
- try {
362
- if (seq.end != null) {
363
- seqDuration = __ticksToSeconds(seq.end);
364
- }
365
- } catch(e) { seqDuration = null; }
366
- state.sequences.push({
367
- name: seq.name,
368
- id: seq.sequenceID,
369
- duration: seqDuration
370
- });
371
- }
372
-
373
- // Active sequence
374
- var active = project.activeSequence;
375
- if (active) {
376
- var activeDuration = null;
377
- try {
378
- if (active.end != null) {
379
- activeDuration = __ticksToSeconds(active.end);
380
- }
381
- } catch(e) { activeDuration = null; }
382
- state.activeSequence = {
383
- name: active.name,
384
- id: active.sequenceID,
385
- durationSeconds: activeDuration,
386
- videoTrackCount: active.videoTracks.numTracks,
387
- audioTrackCount: active.audioTracks.numTracks
388
- };
389
-
390
- // Playhead
391
- try {
392
- var playerPos = active.getPlayerPosition();
393
- state.playheadSeconds = __ticksToSeconds(playerPos.ticks);
394
- } catch(e) {}
395
-
396
- // Selected clips
397
- try {
398
- var sel = active.getSelection();
399
- state.selectedClips = [];
400
- for (var i = 0; i < sel.length; i++) {
401
- state.selectedClips.push({
402
- nodeId: sel[i].nodeId,
403
- name: sel[i].name
404
- });
405
- }
406
- } catch(e) {
407
- state.selectedClips = [];
408
- }
409
-
410
- // Quick clip count
411
- var totalClips = 0;
412
- for (var t = 0; t < active.videoTracks.numTracks; t++) {
413
- totalClips += active.videoTracks[t].clips.numItems;
414
- }
415
- for (var t = 0; t < active.audioTracks.numTracks; t++) {
416
- totalClips += active.audioTracks[t].clips.numItems;
417
- }
418
- state.activeSequence.totalClipCount = totalClips;
419
- } else {
420
- state.activeSequence = null;
421
- }
422
-
423
- // Premiere version
424
- try { state.version = app.version; } catch(e) {}
425
- try { state.buildNumber = app.build; } catch(e) {}
426
-
427
- return __result(state);
343
+ const script = buildToolScript(`
344
+ var state = {};
345
+
346
+ // Project info
347
+ var project = app.project;
348
+ if (!project) return __error("No project is open");
349
+ state.project = {
350
+ name: project.name,
351
+ path: project.path,
352
+ rootItemCount: project.rootItem.children.numItems,
353
+ sequenceCount: project.sequences.numSequences
354
+ };
355
+
356
+ // List all sequences
357
+ state.sequences = [];
358
+ for (var i = 0; i < project.sequences.numSequences; i++) {
359
+ var seq = project.sequences[i];
360
+ var seqDuration = null;
361
+ try {
362
+ if (seq.end != null) {
363
+ seqDuration = __ticksToSeconds(seq.end);
364
+ }
365
+ } catch(e) { seqDuration = null; }
366
+ state.sequences.push({
367
+ name: seq.name,
368
+ id: seq.sequenceID,
369
+ duration: seqDuration
370
+ });
371
+ }
372
+
373
+ // Active sequence
374
+ var active = project.activeSequence;
375
+ if (active) {
376
+ var activeDuration = null;
377
+ try {
378
+ if (active.end != null) {
379
+ activeDuration = __ticksToSeconds(active.end);
380
+ }
381
+ } catch(e) { activeDuration = null; }
382
+ state.activeSequence = {
383
+ name: active.name,
384
+ id: active.sequenceID,
385
+ durationSeconds: activeDuration,
386
+ videoTrackCount: active.videoTracks.numTracks,
387
+ audioTrackCount: active.audioTracks.numTracks
388
+ };
389
+
390
+ // Playhead
391
+ try {
392
+ var playerPos = active.getPlayerPosition();
393
+ state.playheadSeconds = __ticksToSeconds(playerPos.ticks);
394
+ } catch(e) {}
395
+
396
+ // Selected clips
397
+ try {
398
+ var sel = active.getSelection();
399
+ state.selectedClips = [];
400
+ for (var i = 0; i < sel.length; i++) {
401
+ state.selectedClips.push({
402
+ nodeId: sel[i].nodeId,
403
+ name: sel[i].name
404
+ });
405
+ }
406
+ } catch(e) {
407
+ state.selectedClips = [];
408
+ }
409
+
410
+ // Quick clip count
411
+ var totalClips = 0;
412
+ for (var t = 0; t < active.videoTracks.numTracks; t++) {
413
+ totalClips += active.videoTracks[t].clips.numItems;
414
+ }
415
+ for (var t = 0; t < active.audioTracks.numTracks; t++) {
416
+ totalClips += active.audioTracks[t].clips.numItems;
417
+ }
418
+ state.activeSequence.totalClipCount = totalClips;
419
+ } else {
420
+ state.activeSequence = null;
421
+ }
422
+
423
+ // Premiere version
424
+ try { state.version = app.version; } catch(e) {}
425
+ try { state.buildNumber = app.build; } catch(e) {}
426
+
427
+ return __result(state);
428
428
  `);
429
429
  return sendCommand(script, bridgeOptions);
430
430
  },