premiere-cli 0.2.0__py3-none-any.whl

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 (247) hide show
  1. premiere_cli/__init__.py +11 -0
  2. premiere_cli/cli.py +3664 -0
  3. premiere_cli/log.py +66 -0
  4. premiere_cli/panel/.debug +8 -0
  5. premiere_cli/panel/CSXS/manifest.xml +52 -0
  6. premiere_cli/panel/css/style.css +53 -0
  7. premiere_cli/panel/host/commands/add-adjustment-layer.jsx +190 -0
  8. premiere_cli/panel/host/commands/add-audio-keyframes.jsx +176 -0
  9. premiere_cli/panel/host/commands/add-custom-metadata-field.jsx +63 -0
  10. premiere_cli/panel/host/commands/add-keyframe.jsx +181 -0
  11. premiere_cli/panel/host/commands/add-marker-to-project-item.jsx +194 -0
  12. premiere_cli/panel/host/commands/add-marker.jsx +129 -0
  13. premiere_cli/panel/host/commands/add-text-overlay.jsx +101 -0
  14. premiere_cli/panel/host/commands/add-to-render-queue.jsx +120 -0
  15. premiere_cli/panel/host/commands/add-to-timeline.jsx +300 -0
  16. premiere_cli/panel/host/commands/add-track.jsx +188 -0
  17. premiere_cli/panel/host/commands/add-transition.jsx +134 -0
  18. premiere_cli/panel/host/commands/adjust-audio-levels.jsx +132 -0
  19. premiere_cli/panel/host/commands/apply-audio-effect.jsx +118 -0
  20. premiere_cli/panel/host/commands/apply-effect.jsx +122 -0
  21. premiere_cli/panel/host/commands/apply-lut.jsx +107 -0
  22. premiere_cli/panel/host/commands/attach-custom-property.jsx +66 -0
  23. premiere_cli/panel/host/commands/auto-reframe-sequence.jsx +124 -0
  24. premiere_cli/panel/host/commands/batch-add-transitions.jsx +158 -0
  25. premiere_cli/panel/host/commands/batch-apply-effect.jsx +182 -0
  26. premiere_cli/panel/host/commands/batch-rename-clips.jsx +170 -0
  27. premiere_cli/panel/host/commands/batch-set-clips-enabled.jsx +145 -0
  28. premiere_cli/panel/host/commands/clear-item-in-out.jsx +117 -0
  29. premiere_cli/panel/host/commands/clear-sequence-in-out.jsx +100 -0
  30. premiere_cli/panel/host/commands/close-all-source-clips.jsx +32 -0
  31. premiere_cli/panel/host/commands/close-sequence.jsx +80 -0
  32. premiere_cli/panel/host/commands/close-source-monitor.jsx +32 -0
  33. premiere_cli/panel/host/commands/color-correct.jsx +164 -0
  34. premiere_cli/panel/host/commands/copy-effect-values.jsx +183 -0
  35. premiere_cli/panel/host/commands/copy-effects-between-clips.jsx +234 -0
  36. premiere_cli/panel/host/commands/create-bars-and-tone.jsx +152 -0
  37. premiere_cli/panel/host/commands/create-bin.jsx +76 -0
  38. premiere_cli/panel/host/commands/create-caption-track.jsx +159 -0
  39. premiere_cli/panel/host/commands/create-sequence-from-clips.jsx +170 -0
  40. premiere_cli/panel/host/commands/create-sequence-from-preset.jsx +90 -0
  41. premiere_cli/panel/host/commands/create-sequence.jsx +166 -0
  42. premiere_cli/panel/host/commands/create-smart-bin.jsx +80 -0
  43. premiere_cli/panel/host/commands/create-subclip.jsx +248 -0
  44. premiere_cli/panel/host/commands/create-subsequence.jsx +136 -0
  45. premiere_cli/panel/host/commands/debug-qe-inspect.jsx +248 -0
  46. premiere_cli/panel/host/commands/debug-qe-try-mutate.jsx +305 -0
  47. premiere_cli/panel/host/commands/delete-marker.jsx +178 -0
  48. premiere_cli/panel/host/commands/deselect-all-clips.jsx +98 -0
  49. premiere_cli/panel/host/commands/detach-proxy.jsx +116 -0
  50. premiere_cli/panel/host/commands/duplicate-clip.jsx +140 -0
  51. premiere_cli/panel/host/commands/duplicate-sequence.jsx +150 -0
  52. premiere_cli/panel/host/commands/encode-file.jsx +86 -0
  53. premiere_cli/panel/host/commands/encode-project-item.jsx +145 -0
  54. premiere_cli/panel/host/commands/export-aaf.jsx +77 -0
  55. premiere_cli/panel/host/commands/export-fcp-xml.jsx +65 -0
  56. premiere_cli/panel/host/commands/export-frame.jsx +381 -0
  57. premiere_cli/panel/host/commands/export-omf.jsx +95 -0
  58. premiere_cli/panel/host/commands/export-sequence-as-project.jsx +65 -0
  59. premiere_cli/panel/host/commands/export-sequence.jsx +100 -0
  60. premiere_cli/panel/host/commands/extract-audio-track.jsx +181 -0
  61. premiere_cli/panel/host/commands/extract-selection.jsx +113 -0
  62. premiere_cli/panel/host/commands/find-items-by-media-path.jsx +112 -0
  63. premiere_cli/panel/host/commands/freeze-frame.jsx +215 -0
  64. premiere_cli/panel/host/commands/get-active-sequence.jsx +103 -0
  65. premiere_cli/panel/host/commands/get-all-project-paths.jsx +72 -0
  66. premiere_cli/panel/host/commands/get-bin-contents.jsx +176 -0
  67. premiere_cli/panel/host/commands/get-clip-adjustment-layer.jsx +83 -0
  68. premiere_cli/panel/host/commands/get-clip-at-playhead.jsx +99 -0
  69. premiere_cli/panel/host/commands/get-clip-at-position.jsx +120 -0
  70. premiere_cli/panel/host/commands/get-clip-links.jsx +135 -0
  71. premiere_cli/panel/host/commands/get-clip-markers.jsx +144 -0
  72. premiere_cli/panel/host/commands/get-clip-speed.jsx +69 -0
  73. premiere_cli/panel/host/commands/get-color-label.jsx +89 -0
  74. premiere_cli/panel/host/commands/get-color-space.jsx +99 -0
  75. premiere_cli/panel/host/commands/get-duplicate-media.jsx +78 -0
  76. premiere_cli/panel/host/commands/get-effect-properties.jsx +129 -0
  77. premiere_cli/panel/host/commands/get-encoder-presets.jsx +131 -0
  78. premiere_cli/panel/host/commands/get-export-file-extension.jsx +56 -0
  79. premiere_cli/panel/host/commands/get-footage-interpretation.jsx +113 -0
  80. premiere_cli/panel/host/commands/get-full-clip-info.jsx +162 -0
  81. premiere_cli/panel/host/commands/get-full-project-overview.jsx +193 -0
  82. premiere_cli/panel/host/commands/get-full-sequence-info.jsx +184 -0
  83. premiere_cli/panel/host/commands/get-graphics-white-luminance.jsx +31 -0
  84. premiere_cli/panel/host/commands/get-insertion-bin.jsx +35 -0
  85. premiere_cli/panel/host/commands/get-item-metadata.jsx +94 -0
  86. premiere_cli/panel/host/commands/get-keyframes.jsx +158 -0
  87. premiere_cli/panel/host/commands/get-mogrt-component.jsx +111 -0
  88. premiere_cli/panel/host/commands/get-next-edit-point.jsx +131 -0
  89. premiere_cli/panel/host/commands/get-offline-media.jsx +67 -0
  90. premiere_cli/panel/host/commands/get-open-projects.jsx +50 -0
  91. premiere_cli/panel/host/commands/get-premiere-state.jsx +164 -0
  92. premiere_cli/panel/host/commands/get-project-info.jsx +63 -0
  93. premiere_cli/panel/host/commands/get-project-item-info.jsx +247 -0
  94. premiere_cli/panel/host/commands/get-project-panel-metadata.jsx +30 -0
  95. premiere_cli/panel/host/commands/get-qe-clip-info.jsx +198 -0
  96. premiere_cli/panel/host/commands/get-render-queue-status.jsx +35 -0
  97. premiere_cli/panel/host/commands/get-sequence-count.jsx +24 -0
  98. premiere_cli/panel/host/commands/get-sequence-in-out.jsx +76 -0
  99. premiere_cli/panel/host/commands/get-sequence-markers-by-type.jsx +89 -0
  100. premiere_cli/panel/host/commands/get-source-monitor-info.jsx +34 -0
  101. premiere_cli/panel/host/commands/get-source-monitor-position.jsx +30 -0
  102. premiere_cli/panel/host/commands/get-target-tracks.jsx +76 -0
  103. premiere_cli/panel/host/commands/get-timeline-gaps.jsx +124 -0
  104. premiere_cli/panel/host/commands/get-timeline-summary.jsx +154 -0
  105. premiere_cli/panel/host/commands/get-total-clip-count.jsx +67 -0
  106. premiere_cli/panel/host/commands/get-track-info.jsx +117 -0
  107. premiere_cli/panel/host/commands/get-unused-media.jsx +99 -0
  108. premiere_cli/panel/host/commands/get-used-media-report.jsx +125 -0
  109. premiere_cli/panel/host/commands/get-value-at-time.jsx +135 -0
  110. premiere_cli/panel/host/commands/get-version-info.jsx +33 -0
  111. premiere_cli/panel/host/commands/get-work-area.jsx +52 -0
  112. premiere_cli/panel/host/commands/get-workspaces.jsx +29 -0
  113. premiere_cli/panel/host/commands/get-xmp-metadata.jsx +107 -0
  114. premiere_cli/panel/host/commands/import-ae-comps.jsx +129 -0
  115. premiere_cli/panel/host/commands/import-fcp-xml.jsx +103 -0
  116. premiere_cli/panel/host/commands/import-folder.jsx +193 -0
  117. premiere_cli/panel/host/commands/import-image-sequence.jsx +171 -0
  118. premiere_cli/panel/host/commands/import-media.jsx +217 -0
  119. premiere_cli/panel/host/commands/import-mogrt-from-library.jsx +105 -0
  120. premiere_cli/panel/host/commands/import-mogrt.jsx +111 -0
  121. premiere_cli/panel/host/commands/import-sequences-from-project.jsx +80 -0
  122. premiere_cli/panel/host/commands/insert-from-source.jsx +162 -0
  123. premiere_cli/panel/host/commands/inspect-dom-object.jsx +162 -0
  124. premiere_cli/panel/host/commands/invert-selection.jsx +114 -0
  125. premiere_cli/panel/host/commands/is-work-area-enabled.jsx +88 -0
  126. premiere_cli/panel/host/commands/lift-selection.jsx +106 -0
  127. premiere_cli/panel/host/commands/link-selection.jsx +111 -0
  128. premiere_cli/panel/host/commands/list-available-audio-effects.jsx +33 -0
  129. premiere_cli/panel/host/commands/list-available-audio-transitions.jsx +35 -0
  130. premiere_cli/panel/host/commands/list-available-effects.jsx +33 -0
  131. premiere_cli/panel/host/commands/list-available-transitions.jsx +74 -0
  132. premiere_cli/panel/host/commands/list-markers.jsx +69 -0
  133. premiere_cli/panel/host/commands/list-project-items.jsx +105 -0
  134. premiere_cli/panel/host/commands/lock-track.jsx +114 -0
  135. premiere_cli/panel/host/commands/manage-proxies.jsx +176 -0
  136. premiere_cli/panel/host/commands/match-frame.jsx +141 -0
  137. premiere_cli/panel/host/commands/move-clip-to-track.jsx +220 -0
  138. premiere_cli/panel/host/commands/move-clip.jsx +97 -0
  139. premiere_cli/panel/host/commands/move-items-to-bin.jsx +194 -0
  140. premiere_cli/panel/host/commands/move-playhead-to-edit.jsx +174 -0
  141. premiere_cli/panel/host/commands/move-playhead.jsx +137 -0
  142. premiere_cli/panel/host/commands/nest-clips.jsx +179 -0
  143. premiere_cli/panel/host/commands/open-in-source.jsx +117 -0
  144. premiere_cli/panel/host/commands/open-project.jsx +61 -0
  145. premiere_cli/panel/host/commands/overwrite-clip-at.jsx +350 -0
  146. premiere_cli/panel/host/commands/overwrite-from-source.jsx +150 -0
  147. premiere_cli/panel/host/commands/play-source-monitor.jsx +36 -0
  148. premiere_cli/panel/host/commands/play-timeline.jsx +24 -0
  149. premiere_cli/panel/host/commands/razor-all-tracks.jsx +171 -0
  150. premiere_cli/panel/host/commands/redo.jsx +69 -0
  151. premiere_cli/panel/host/commands/refresh-media.jsx +101 -0
  152. premiere_cli/panel/host/commands/relink-media.jsx +132 -0
  153. premiere_cli/panel/host/commands/remove-all-effects.jsx +114 -0
  154. premiere_cli/panel/host/commands/remove-effect-by-name.jsx +143 -0
  155. premiere_cli/panel/host/commands/remove-effect.jsx +122 -0
  156. premiere_cli/panel/host/commands/remove-from-timeline.jsx +93 -0
  157. premiere_cli/panel/host/commands/remove-keyframe-range.jsx +173 -0
  158. premiere_cli/panel/host/commands/remove-keyframe.jsx +192 -0
  159. premiere_cli/panel/host/commands/remove-selected-clips.jsx +126 -0
  160. premiere_cli/panel/host/commands/remove-track-intervals.jsx +254 -0
  161. premiere_cli/panel/host/commands/remove-transition.jsx +164 -0
  162. premiere_cli/panel/host/commands/rename-bin.jsx +88 -0
  163. premiere_cli/panel/host/commands/rename-clip.jsx +127 -0
  164. premiere_cli/panel/host/commands/rename-project-item.jsx +111 -0
  165. premiere_cli/panel/host/commands/rename-track.jsx +84 -0
  166. premiere_cli/panel/host/commands/replace-clip-media.jsx +140 -0
  167. premiere_cli/panel/host/commands/replace-clip.jsx +188 -0
  168. premiere_cli/panel/host/commands/reverse-clip.jsx +187 -0
  169. premiere_cli/panel/host/commands/ripple-delete-clip.jsx +156 -0
  170. premiere_cli/panel/host/commands/roll-edit.jsx +162 -0
  171. premiere_cli/panel/host/commands/save-project-as.jsx +55 -0
  172. premiere_cli/panel/host/commands/save-project.jsx +57 -0
  173. premiere_cli/panel/host/commands/scene-edit-detection.jsx +128 -0
  174. premiere_cli/panel/host/commands/search-project-items.jsx +180 -0
  175. premiere_cli/panel/host/commands/select-all-clips.jsx +107 -0
  176. premiere_cli/panel/host/commands/select-clips-by-color.jsx +142 -0
  177. premiere_cli/panel/host/commands/select-clips-by-name.jsx +133 -0
  178. premiere_cli/panel/host/commands/select-clips-in-range.jsx +133 -0
  179. premiere_cli/panel/host/commands/select-disabled-clips.jsx +127 -0
  180. premiere_cli/panel/host/commands/select-project-item.jsx +115 -0
  181. premiere_cli/panel/host/commands/set-active-project.jsx +184 -0
  182. premiere_cli/panel/host/commands/set-active-sequence.jsx +87 -0
  183. premiere_cli/panel/host/commands/set-all-tracks-targeted.jsx +112 -0
  184. premiere_cli/panel/host/commands/set-anti-alias-quality.jsx +125 -0
  185. premiere_cli/panel/host/commands/set-blend-mode.jsx +111 -0
  186. premiere_cli/panel/host/commands/set-clip-anchor-point.jsx +102 -0
  187. premiere_cli/panel/host/commands/set-clip-enabled.jsx +127 -0
  188. premiere_cli/panel/host/commands/set-clip-opacity.jsx +102 -0
  189. premiere_cli/panel/host/commands/set-clip-pan.jsx +107 -0
  190. premiere_cli/panel/host/commands/set-clip-position.jsx +103 -0
  191. premiere_cli/panel/host/commands/set-clip-properties.jsx +221 -0
  192. premiere_cli/panel/host/commands/set-clip-rotation.jsx +102 -0
  193. premiere_cli/panel/host/commands/set-clip-scale.jsx +102 -0
  194. premiere_cli/panel/host/commands/set-clip-selection.jsx +144 -0
  195. premiere_cli/panel/host/commands/set-clip-speed.jsx +160 -0
  196. premiere_cli/panel/host/commands/set-clip-volume.jsx +128 -0
  197. premiere_cli/panel/host/commands/set-color-label.jsx +123 -0
  198. premiere_cli/panel/host/commands/set-color-value.jsx +155 -0
  199. premiere_cli/panel/host/commands/set-effect-property.jsx +124 -0
  200. premiere_cli/panel/host/commands/set-footage-interpretation.jsx +173 -0
  201. premiere_cli/panel/host/commands/set-frame-blend.jsx +145 -0
  202. premiere_cli/panel/host/commands/set-graphics-white-luminance.jsx +73 -0
  203. premiere_cli/panel/host/commands/set-item-in-out.jsx +180 -0
  204. premiere_cli/panel/host/commands/set-item-metadata.jsx +134 -0
  205. premiere_cli/panel/host/commands/set-item-offline.jsx +109 -0
  206. premiere_cli/panel/host/commands/set-item-start-time.jsx +139 -0
  207. premiere_cli/panel/host/commands/set-keyframe-interpolation.jsx +186 -0
  208. premiere_cli/panel/host/commands/set-override-frame-rate.jsx +123 -0
  209. premiere_cli/panel/host/commands/set-override-pixel-aspect-ratio.jsx +129 -0
  210. premiere_cli/panel/host/commands/set-poster-frame.jsx +192 -0
  211. premiere_cli/panel/host/commands/set-project-panel-metadata.jsx +69 -0
  212. premiere_cli/panel/host/commands/set-scale-to-frame-size.jsx +101 -0
  213. premiere_cli/panel/host/commands/set-scale-width-height.jsx +140 -0
  214. premiere_cli/panel/host/commands/set-sequence-in-out.jsx +65 -0
  215. premiere_cli/panel/host/commands/set-sequence-settings.jsx +184 -0
  216. premiere_cli/panel/host/commands/set-source-in-out.jsx +98 -0
  217. premiere_cli/panel/host/commands/set-target-track.jsx +91 -0
  218. premiere_cli/panel/host/commands/set-time-interpolation.jsx +141 -0
  219. premiere_cli/panel/host/commands/set-track-mute.jsx +91 -0
  220. premiere_cli/panel/host/commands/set-track-visibility.jsx +94 -0
  221. premiere_cli/panel/host/commands/set-transcode-on-ingest.jsx +78 -0
  222. premiere_cli/panel/host/commands/set-uniform-scale.jsx +104 -0
  223. premiere_cli/panel/host/commands/set-work-area.jsx +76 -0
  224. premiere_cli/panel/host/commands/set-workspace.jsx +35 -0
  225. premiere_cli/panel/host/commands/set-xmp-metadata.jsx +157 -0
  226. premiere_cli/panel/host/commands/slide-edit.jsx +162 -0
  227. premiere_cli/panel/host/commands/slip-edit.jsx +167 -0
  228. premiere_cli/panel/host/commands/split-clip.jsx +144 -0
  229. premiere_cli/panel/host/commands/stabilize-clip.jsx +139 -0
  230. premiere_cli/panel/host/commands/stop-playback.jsx +23 -0
  231. premiere_cli/panel/host/commands/trim-clip.jsx +111 -0
  232. premiere_cli/panel/host/commands/undo.jsx +114 -0
  233. premiere_cli/panel/host/commands/unlink-selection.jsx +106 -0
  234. premiere_cli/panel/host/commands/unnest-sequence.jsx +207 -0
  235. premiere_cli/panel/host/commands/update-marker.jsx +120 -0
  236. premiere_cli/panel/host/index.jsx +1227 -0
  237. premiere_cli/panel/host/presets/default-4k-25fps.sqpreset +63 -0
  238. premiere_cli/panel/index.html +16 -0
  239. premiere_cli/panel/js/cs-interface.js +11 -0
  240. premiere_cli/panel/js/main.js +409 -0
  241. premiere_cli/panel_install.py +220 -0
  242. premiere_cli-0.2.0.dist-info/METADATA +127 -0
  243. premiere_cli-0.2.0.dist-info/RECORD +247 -0
  244. premiere_cli-0.2.0.dist-info/WHEEL +5 -0
  245. premiere_cli-0.2.0.dist-info/entry_points.txt +3 -0
  246. premiere_cli-0.2.0.dist-info/licenses/LICENSE +428 -0
  247. premiere_cli-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,145 @@
1
+ // Command: batch-set-clips-enabled → ppb_batchSetClipsEnabled
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (findSequenceByName,
4
+ // ...) are already defined there.
5
+ //
6
+ // Standard-DOM mutation. Ported from leancoderkavy's premiere-pro-mcp
7
+ // `batch_enable_disable` tool (track-targeting.ts), which supports
8
+ // target: "selected"|"track"|"all" — collapsed here to two filters
9
+ // (`nameContains`, `trackType`) since this bridge otherwise always exposes
10
+ // filters rather than a target enum (matching batch-rename-clips'
11
+ // convention); omit both to affect every clip in the sequence, matching
12
+ // the reference's "all" target. There is no `target: "selected"`
13
+ // equivalent — use select-clips-by-name / set-clip-selection first, then
14
+ // filter batch-set-clips-enabled by the same `nameContains` if that
15
+ // combination is needed. Same `clip.disabled`/`setDisabled()` dual-probe
16
+ // as set-clip-enabled, capped at 200 clips per call, with a per-track
17
+ // read-back verification summary rather than trusting the mutation calls.
18
+ var BATCH_SET_CLIPS_ENABLED_MAX = 200;
19
+
20
+ function ppb_batchSetClipsEnabledOnTrack(track, trackType, trackIndex, nameContainsLower, enabled, budget, results) {
21
+ var affected = 0;
22
+ var verifiedCount = 0;
23
+ var numClips = track.clips.numItems;
24
+ var requestedDisabled = !enabled;
25
+
26
+ for (var c = 0; c < numClips; c++) {
27
+ if (budget.remaining <= 0) {
28
+ budget.cappedAtLimit = true;
29
+ break;
30
+ }
31
+
32
+ var clip = track.clips[c];
33
+ var clipName = null;
34
+ try { clipName = clip.name; } catch (e) { clipName = null; }
35
+
36
+ if (nameContainsLower !== null) {
37
+ var haystack = clipName === null ? "" : String(clipName).toLowerCase();
38
+ if (haystack.indexOf(nameContainsLower) === -1) {
39
+ continue;
40
+ }
41
+ }
42
+
43
+ var entry = { trackType: trackType, trackIndex: trackIndex, clipIndex: c, clipName: clipName, verified: false };
44
+
45
+ try {
46
+ clip.disabled = requestedDisabled;
47
+ } catch (e1) {
48
+ try {
49
+ clip.setDisabled(requestedDisabled);
50
+ } catch (e2) {
51
+ entry.error = e1.toString() + " / " + e2.toString();
52
+ }
53
+ }
54
+
55
+ var newDisabled = null;
56
+ try { newDisabled = clip.disabled; } catch (e) { newDisabled = null; }
57
+ entry.verified = newDisabled === requestedDisabled;
58
+
59
+ if (entry.verified) {
60
+ verifiedCount++;
61
+ }
62
+ affected++;
63
+ budget.remaining--;
64
+ results.push(entry);
65
+ }
66
+
67
+ return { affected: affected, verifiedCount: verifiedCount };
68
+ }
69
+
70
+ function ppb_batchSetClipsEnabled(argsJson) {
71
+ try {
72
+ var args;
73
+ try {
74
+ args = JSON.parse(argsJson);
75
+ } catch (e) {
76
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
77
+ }
78
+
79
+ if (typeof args.enabled !== "boolean") {
80
+ return JSON.stringify({ ok: false, error: "enabled must be a boolean" });
81
+ }
82
+ var trackTypeFilter = args.trackType || "both";
83
+ if (trackTypeFilter !== "video" && trackTypeFilter !== "audio" && trackTypeFilter !== "both") {
84
+ return JSON.stringify({ ok: false, error: "trackType must be \"video\", \"audio\", or \"both\"" });
85
+ }
86
+ var nameContainsLower = null;
87
+ if (typeof args.nameContains === "string" && args.nameContains.length > 0) {
88
+ nameContainsLower = args.nameContains.toLowerCase();
89
+ }
90
+
91
+ if (!app.project) {
92
+ return JSON.stringify({ ok: false, error: "no project open" });
93
+ }
94
+
95
+ var seq = null;
96
+ if (args.sequenceName && typeof args.sequenceName === "string") {
97
+ seq = findSequenceByName(args.sequenceName);
98
+ if (!seq) {
99
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
100
+ }
101
+ } else {
102
+ seq = app.project.activeSequence;
103
+ if (!seq) {
104
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
105
+ }
106
+ }
107
+
108
+ var results = [];
109
+ var budget = { remaining: BATCH_SET_CLIPS_ENABLED_MAX, cappedAtLimit: false };
110
+ var totalAffected = 0;
111
+ var totalVerified = 0;
112
+
113
+ if (trackTypeFilter === "video" || trackTypeFilter === "both") {
114
+ for (var vt = 0; vt < seq.videoTracks.numTracks; vt++) {
115
+ var vRes = ppb_batchSetClipsEnabledOnTrack(seq.videoTracks[vt], "video", vt, nameContainsLower, args.enabled, budget, results);
116
+ totalAffected += vRes.affected;
117
+ totalVerified += vRes.verifiedCount;
118
+ if (budget.cappedAtLimit) { break; }
119
+ }
120
+ }
121
+ if (!budget.cappedAtLimit && (trackTypeFilter === "audio" || trackTypeFilter === "both")) {
122
+ for (var at = 0; at < seq.audioTracks.numTracks; at++) {
123
+ var aRes = ppb_batchSetClipsEnabledOnTrack(seq.audioTracks[at], "audio", at, nameContainsLower, args.enabled, budget, results);
124
+ totalAffected += aRes.affected;
125
+ totalVerified += aRes.verifiedCount;
126
+ if (budget.cappedAtLimit) { break; }
127
+ }
128
+ }
129
+
130
+ var result = {
131
+ sequenceName: seq.name,
132
+ trackType: trackTypeFilter,
133
+ nameContains: args.nameContains || null,
134
+ requestedEnabled: args.enabled,
135
+ affected: totalAffected,
136
+ verifiedCount: totalVerified,
137
+ cappedAtLimit: budget.cappedAtLimit,
138
+ results: results
139
+ };
140
+
141
+ return JSON.stringify({ ok: true, result: result });
142
+ } catch (e) {
143
+ return JSON.stringify({ ok: false, error: e.toString() });
144
+ }
145
+ }
@@ -0,0 +1,117 @@
1
+ // Command: clear-item-in-out → ppb_clearItemInOut
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context.
4
+ //
5
+ // Ported from leancoderkavy/premiere-pro-mcp's track-targeting.ts
6
+ // clear_item_in_out — clears in and/or out points on a PROJECT item via
7
+ // item.clearInPoint()/clearOutPoint(), resetting it to its full source
8
+ // duration. Both default to true (clear both) unless explicitly set false.
9
+ //
10
+ // Project-item addressing/lookup duplicated per command file, same
11
+ // convention as get-item-metadata.jsx / set-item-in-out.jsx.
12
+
13
+ function ppbFindItemClearItemInOut_walk(item, args, depth) {
14
+ if (depth > 32) {
15
+ return null;
16
+ }
17
+ var isBin = false;
18
+ try {
19
+ isBin = typeof ProjectItemType !== "undefined" && item.type === ProjectItemType.BIN;
20
+ } catch (e) {
21
+ isBin = false;
22
+ }
23
+ var matched = false;
24
+ if (args.nodeId !== null) {
25
+ try { matched = item.nodeId === args.nodeId; } catch (e) { matched = false; }
26
+ } else if (args.name !== null) {
27
+ try { matched = item.name === args.name; } catch (e) { matched = false; }
28
+ }
29
+ if (matched) {
30
+ return item;
31
+ }
32
+ if (isBin && item.children) {
33
+ for (var i = 0; i < item.children.numItems; i++) {
34
+ var found = ppbFindItemClearItemInOut_walk(item.children[i], args, depth + 1);
35
+ if (found) {
36
+ return found;
37
+ }
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+
43
+ function ppbFindItemClearItemInOut_resolve(args) {
44
+ var root = app.project.rootItem;
45
+ for (var i = 0; i < root.children.numItems; i++) {
46
+ var found = ppbFindItemClearItemInOut_walk(root.children[i], args, 1);
47
+ if (found) {
48
+ return found;
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+
54
+ function ppb_clearItemInOut(argsJson) {
55
+ try {
56
+ var args;
57
+ try {
58
+ args = JSON.parse(argsJson);
59
+ } catch (e) {
60
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
61
+ }
62
+
63
+ var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
64
+ var hasName = typeof args.name === "string" && args.name.length > 0;
65
+ if (!hasNodeId && !hasName) {
66
+ return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
67
+ }
68
+
69
+ if (!app.project) {
70
+ return JSON.stringify({ ok: false, error: "no project open" });
71
+ }
72
+
73
+ var item = ppbFindItemClearItemInOut_resolve({
74
+ nodeId: hasNodeId ? args.nodeId : null,
75
+ name: hasNodeId ? null : args.name
76
+ });
77
+ if (!item) {
78
+ return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
79
+ }
80
+
81
+ var clearIn = args.clearIn !== false;
82
+ var clearOut = args.clearOut !== false;
83
+
84
+ var inClearError = null;
85
+ var outClearError = null;
86
+
87
+ if (clearIn) {
88
+ try {
89
+ item.clearInPoint();
90
+ } catch (e) {
91
+ inClearError = e.toString();
92
+ }
93
+ }
94
+ if (clearOut) {
95
+ try {
96
+ item.clearOutPoint();
97
+ } catch (e) {
98
+ outClearError = e.toString();
99
+ }
100
+ }
101
+
102
+ return JSON.stringify({
103
+ ok: (clearIn ? inClearError === null : true) && (clearOut ? outClearError === null : true),
104
+ result: {
105
+ name: item.name,
106
+ nodeId: item.nodeId,
107
+ clearedIn: clearIn && inClearError === null,
108
+ clearedOut: clearOut && outClearError === null,
109
+ inClearError: inClearError,
110
+ outClearError: outClearError,
111
+ note: "no getInPoint/getOutPoint-style getter is confirmed available on this build (see set-item-in-out.jsx) — this only confirms the clear call(s) did not throw"
112
+ }
113
+ });
114
+ } catch (e) {
115
+ return JSON.stringify({ ok: false, error: e.toString() });
116
+ }
117
+ }
@@ -0,0 +1,100 @@
1
+ // Command: clear-sequence-in-out → ppb_clearSequenceInOut
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (findSequenceByName,
4
+ // trySetSequenceRange, timeValueToSeconds, ...) are already defined there.
5
+ //
6
+ // Ported from leancoderkavy/premiere-pro-mcp's track-targeting.ts
7
+ // clear_sequence_in_out. The reference implementation sets in=zeroPoint,
8
+ // out=seq.end — but per get-sequence-in-out.jsx's live finding, an actually
9
+ // UNSET in/out point reads back as Premiere's internal -400000 sentinel,
10
+ // not a real in/out range spanning the whole sequence. This command sets
11
+ // that literal -400000 sentinel value via the shared trySetSequenceRange()
12
+ // helper (its first attempt is the raw "seconds" form — i.e.
13
+ // seq.setInPoint(-400000) — which is exactly the value get-sequence-in-out
14
+ // reads back for "no point set", live-confirmed working on this build) so
15
+ // a subsequent get-sequence-in-out reports {inSeconds: null, outSeconds: null}.
16
+ var CLEAR_SEQUENCE_IN_OUT_SENTINEL = -400000;
17
+
18
+ // Duplicated from get-sequence-in-out.jsx's ppb_pointValueToSeconds (each
19
+ // command file loads independently and cannot rely on another command
20
+ // file's helpers) — treats Premiere's -400000-ish sentinel as "unset".
21
+ function ppbSentinelPointToSeconds(value) {
22
+ if (value === null || typeof value === "undefined") {
23
+ return null;
24
+ }
25
+ if (typeof value === "object") {
26
+ return timeValueToSeconds(value);
27
+ }
28
+ var seconds = Number(value);
29
+ if (isNaN(seconds)) {
30
+ return null;
31
+ }
32
+ if (seconds <= -399999) {
33
+ return null;
34
+ }
35
+ return seconds;
36
+ }
37
+
38
+ function ppb_clearSequenceInOut(argsJson) {
39
+ try {
40
+ var args;
41
+ try {
42
+ args = JSON.parse(argsJson);
43
+ } catch (e) {
44
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
45
+ }
46
+
47
+ if (!app.project) {
48
+ return JSON.stringify({ ok: false, error: "no project open" });
49
+ }
50
+
51
+ var seq = null;
52
+ if (args.sequenceName && typeof args.sequenceName === "string") {
53
+ seq = findSequenceByName(args.sequenceName);
54
+ if (!seq) {
55
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
56
+ }
57
+ } else {
58
+ seq = app.project.activeSequence;
59
+ if (!seq) {
60
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
61
+ }
62
+ }
63
+
64
+ var previousIn = null;
65
+ var previousOut = null;
66
+ try { previousIn = ppbSentinelPointToSeconds(seq.getInPoint()); } catch (e) { previousIn = null; }
67
+ try { previousOut = ppbSentinelPointToSeconds(seq.getOutPoint()); } catch (e) { previousOut = null; }
68
+
69
+ var rangeResult = trySetSequenceRange(seq, CLEAR_SEQUENCE_IN_OUT_SENTINEL, CLEAR_SEQUENCE_IN_OUT_SENTINEL);
70
+ if (!rangeResult.ok) {
71
+ return JSON.stringify({
72
+ ok: false,
73
+ error: "could not clear sequence in/out points with any known argument form",
74
+ attempts: rangeResult.attempts,
75
+ previousInSeconds: previousIn,
76
+ previousOutSeconds: previousOut
77
+ });
78
+ }
79
+
80
+ var newIn = null;
81
+ var newOut = null;
82
+ try { newIn = ppbSentinelPointToSeconds(seq.getInPoint()); } catch (e) { newIn = null; }
83
+ try { newOut = ppbSentinelPointToSeconds(seq.getOutPoint()); } catch (e) { newOut = null; }
84
+
85
+ return JSON.stringify({
86
+ ok: true,
87
+ result: {
88
+ sequenceName: seq.name,
89
+ previousInSeconds: previousIn,
90
+ previousOutSeconds: previousOut,
91
+ inSeconds: newIn,
92
+ outSeconds: newOut,
93
+ verified: newIn === null && newOut === null,
94
+ attempts: rangeResult.attempts
95
+ }
96
+ });
97
+ } catch (e) {
98
+ return JSON.stringify({ ok: false, error: e.toString() });
99
+ }
100
+ }
@@ -0,0 +1,32 @@
1
+ // Command: close-all-source-clips → ppb_closeAllSourceClips
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use.
3
+ //
4
+ // Ported from leancoderkavy's premiere-pro-mcp source-monitor.ts
5
+ // close_all_source_clips. Closes every clip currently open across the
6
+ // Source Monitor's tabs via app.sourceMonitor.closeAllClips().
7
+ //
8
+ // MUTATION RULE: verified the same way as close-source-monitor — a null
9
+ // getProjectItem() read-back afterward confirms nothing is left loaded.
10
+ function ppb_closeAllSourceClips() {
11
+ try {
12
+ try {
13
+ app.sourceMonitor.closeAllClips();
14
+ } catch (e) {
15
+ return JSON.stringify({ ok: false, error: "app.sourceMonitor.closeAllClips() failed: " + e.toString() });
16
+ }
17
+
18
+ var stillLoaded = null;
19
+ try {
20
+ stillLoaded = app.sourceMonitor.getProjectItem();
21
+ } catch (e2) {
22
+ stillLoaded = null;
23
+ }
24
+
25
+ return JSON.stringify({
26
+ ok: true,
27
+ result: { closed: true, verified: !stillLoaded }
28
+ });
29
+ } catch (e) {
30
+ return JSON.stringify({ ok: false, error: e.toString() });
31
+ }
32
+ }
@@ -0,0 +1,80 @@
1
+ // Command: close-sequence → ppb_closeSequence
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (findSequenceByName,
4
+ // ...) are already defined there.
5
+ //
6
+ // Ported from leancoderkavy/premiere-pro-mcp's advanced.ts close_sequence
7
+ // tool: `seq.close()` per PREMIERE_API_NOTES.md's Sequences table.
8
+ //
9
+ // UI-TAB SEMANTICS PROBE: seq.close() is expected to close the sequence's
10
+ // TAB in the Timeline panel, not delete the sequence from the project —
11
+ // there is a separate app.project.deleteSequence(seq) for that. This
12
+ // command probes exactly that distinction rather than assuming it: after
13
+ // calling close(), it re-scans app.project.sequences (a collection
14
+ // distinct from open timeline tabs) for the closed sequence's own
15
+ // sequenceID and reports stillInProjectSequences accordingly.
16
+ function ppb_closeSequence(argsJson) {
17
+ try {
18
+ var args;
19
+ try {
20
+ args = JSON.parse(argsJson);
21
+ } catch (e) {
22
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
23
+ }
24
+
25
+ if (!app.project) {
26
+ return JSON.stringify({ ok: false, error: "no project open" });
27
+ }
28
+
29
+ var seq;
30
+ if (args.sequenceName && typeof args.sequenceName === "string") {
31
+ seq = findSequenceByName(args.sequenceName);
32
+ if (!seq) {
33
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
34
+ }
35
+ } else {
36
+ seq = app.project.activeSequence;
37
+ if (!seq) {
38
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
39
+ }
40
+ }
41
+
42
+ var closedName = seq.name;
43
+ var closedSequenceID = null;
44
+ try { closedSequenceID = seq.sequenceID; } catch (e) { closedSequenceID = null; }
45
+
46
+ var numSequencesBefore = app.project.sequences.numSequences;
47
+
48
+ try {
49
+ seq.close();
50
+ } catch (e) {
51
+ return JSON.stringify({ ok: false, error: "seq.close() failed: " + e.toString() });
52
+ }
53
+
54
+ var numSequencesAfter = app.project.sequences.numSequences;
55
+ var stillInProjectSequences = false;
56
+ for (var i = 0; i < app.project.sequences.numSequences; i++) {
57
+ var candidateId = null;
58
+ try { candidateId = app.project.sequences[i].sequenceID; } catch (e2) { candidateId = null; }
59
+ if (candidateId !== null && candidateId === closedSequenceID) {
60
+ stillInProjectSequences = true;
61
+ break;
62
+ }
63
+ }
64
+
65
+ return JSON.stringify({
66
+ ok: true,
67
+ result: {
68
+ sequenceName: closedName,
69
+ sequenceID: closedSequenceID,
70
+ closed: true,
71
+ numSequencesBefore: numSequencesBefore,
72
+ numSequencesAfter: numSequencesAfter,
73
+ stillInProjectSequences: stillInProjectSequences,
74
+ note: "seq.close() closes the sequence's UI TAB in the Timeline panel — this is NOT the same as deleting the sequence from the project (that is app.project.deleteSequence(seq), not exposed by this command). stillInProjectSequences reports whether app.project.sequences — a collection distinct from open timeline tabs — still lists the closed sequence afterward, the only available probe of this UI-tab-vs-project-item distinction."
75
+ }
76
+ });
77
+ } catch (e) {
78
+ return JSON.stringify({ ok: false, error: e.toString() });
79
+ }
80
+ }
@@ -0,0 +1,32 @@
1
+ // Command: close-source-monitor → ppb_closeSourceMonitor
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use.
3
+ //
4
+ // Ported from leancoderkavy's premiere-pro-mcp source-monitor.ts
5
+ // close_source_monitor. Closes whichever single clip is open in the
6
+ // Source Monitor via app.sourceMonitor.closeClip().
7
+ //
8
+ // MUTATION RULE: verified by reading app.sourceMonitor.getProjectItem()
9
+ // back afterward — a null result confirms the monitor is now empty.
10
+ function ppb_closeSourceMonitor() {
11
+ try {
12
+ try {
13
+ app.sourceMonitor.closeClip();
14
+ } catch (e) {
15
+ return JSON.stringify({ ok: false, error: "app.sourceMonitor.closeClip() failed: " + e.toString() });
16
+ }
17
+
18
+ var stillLoaded = null;
19
+ try {
20
+ stillLoaded = app.sourceMonitor.getProjectItem();
21
+ } catch (e2) {
22
+ stillLoaded = null;
23
+ }
24
+
25
+ return JSON.stringify({
26
+ ok: true,
27
+ result: { closed: true, verified: !stillLoaded }
28
+ });
29
+ } catch (e) {
30
+ return JSON.stringify({ ok: false, error: e.toString() });
31
+ }
32
+ }
@@ -0,0 +1,164 @@
1
+ // Command: color-correct → ppb_colorCorrect
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (findSequenceByName,
4
+ // resolveTimelineClip, serializeClipComponents,
5
+ // ensureLumetriColorComponent, valuesApproximatelyEqual, ...) are already
6
+ // defined there.
7
+ //
8
+ // Ensures Lumetri Color is applied (via ensureLumetriColorComponent, adding
9
+ // it through the standard QE dance if missing), then sets any of
10
+ // exposure/contrast/saturation/temperature/tint by displayName. Per
11
+ // PREMIERE_API_NOTES.md, Lumetri repeats display names across its
12
+ // sub-sections (Basic Correction, Creative, HSL Secondary, ...) and not
13
+ // every match is writable — for each requested control, every matching
14
+ // property is tried in order until one setValue() doesn't throw ("first
15
+ // writable match wins"); previous/new values are read from that exact
16
+ // property index, not re-scanned from the top (which could otherwise grab
17
+ // an unrelated same-named property). 0 is a legitimate value for every one
18
+ // of these controls (e.g. full desaturate) — never falsy-checked.
19
+ function ppb_colorCorrect(argsJson) {
20
+ try {
21
+ var args;
22
+ try {
23
+ args = JSON.parse(argsJson);
24
+ } catch (e) {
25
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
26
+ }
27
+
28
+ if (args.trackType !== "video") {
29
+ return JSON.stringify({ ok: false, error: "trackType must be \"video\" — Lumetri Color is a video effect" });
30
+ }
31
+ if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
32
+ return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
33
+ }
34
+ if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
35
+ return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
36
+ }
37
+
38
+ var CONTROLS = [
39
+ { key: "exposure", label: "Exposure" },
40
+ { key: "contrast", label: "Contrast" },
41
+ { key: "saturation", label: "Saturation" },
42
+ { key: "temperature", label: "Temperature" },
43
+ { key: "tint", label: "Tint" }
44
+ ];
45
+ var requested = [];
46
+ for (var c = 0; c < CONTROLS.length; c++) {
47
+ if (typeof args[CONTROLS[c].key] === "number") {
48
+ requested.push(CONTROLS[c]);
49
+ }
50
+ }
51
+ if (requested.length === 0) {
52
+ return JSON.stringify({ ok: false, error: "at least one of exposure, contrast, saturation, temperature, tint is required" });
53
+ }
54
+
55
+ if (!app.project) {
56
+ return JSON.stringify({ ok: false, error: "no project open" });
57
+ }
58
+
59
+ var seq = null;
60
+ if (args.sequenceName && typeof args.sequenceName === "string") {
61
+ seq = findSequenceByName(args.sequenceName);
62
+ if (!seq) {
63
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
64
+ }
65
+ } else {
66
+ seq = app.project.activeSequence;
67
+ if (!seq) {
68
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
69
+ }
70
+ }
71
+
72
+ var resolvedClip = resolveTimelineClip(seq, "video", args.trackIndex, args.clipIndex);
73
+ if (resolvedClip.error) {
74
+ return JSON.stringify({ ok: false, error: resolvedClip.error });
75
+ }
76
+ var clip = resolvedClip.clip;
77
+ var clipName = null;
78
+ try { clipName = clip.name; } catch (e) { clipName = null; }
79
+
80
+ var previousComponents = serializeClipComponents(clip);
81
+
82
+ var lumetri = ensureLumetriColorComponent(seq, "video", args.trackIndex, args.clipIndex, clip);
83
+ if (lumetri.error) {
84
+ return JSON.stringify({ ok: false, error: lumetri.error });
85
+ }
86
+ var lumetriComp = lumetri.component;
87
+
88
+ var changes = {};
89
+ var numProps;
90
+ try {
91
+ numProps = lumetriComp.properties.numItems;
92
+ } catch (e) {
93
+ return JSON.stringify({ ok: false, error: "could not read Lumetri Color's properties: " + e.toString() });
94
+ }
95
+
96
+ for (var r = 0; r < requested.length; r++) {
97
+ var key = requested[r].key;
98
+ var label = requested[r].label;
99
+ var value = args[key];
100
+
101
+ var previousValue = null;
102
+ var havePrevious = false;
103
+ var applied = false;
104
+ var appliedIndex = -1;
105
+ var errorMsg = null;
106
+
107
+ for (var p = 0; p < numProps; p++) {
108
+ var prop = lumetriComp.properties[p];
109
+ var dn = null;
110
+ try { dn = prop.displayName; } catch (e2) { dn = null; }
111
+ if (dn !== label) {
112
+ continue;
113
+ }
114
+ if (!havePrevious) {
115
+ try { previousValue = prop.getValue(); } catch (e3) { previousValue = null; }
116
+ havePrevious = true;
117
+ }
118
+ if (!applied) {
119
+ try {
120
+ prop.setValue(value, true);
121
+ applied = true;
122
+ appliedIndex = p;
123
+ } catch (e4) {
124
+ errorMsg = e4.toString();
125
+ }
126
+ }
127
+ }
128
+
129
+ var newValue = null;
130
+ if (applied) {
131
+ try { newValue = lumetriComp.properties[appliedIndex].getValue(); } catch (e5) { newValue = null; }
132
+ }
133
+
134
+ changes[key] = {
135
+ displayName: label,
136
+ previousValue: previousValue,
137
+ requestedValue: value,
138
+ newValue: newValue,
139
+ applied: applied,
140
+ verified: applied && valuesApproximatelyEqual(newValue, value),
141
+ error: applied ? null : (errorMsg || "no writable property named \"" + label + "\" found on Lumetri Color")
142
+ };
143
+ }
144
+
145
+ var newComponents = serializeClipComponents(clip);
146
+
147
+ return JSON.stringify({
148
+ ok: true,
149
+ result: {
150
+ sequenceName: seq.name,
151
+ trackType: "video",
152
+ trackIndex: args.trackIndex,
153
+ clipIndex: args.clipIndex,
154
+ clipName: clipName,
155
+ lumetriApplied: lumetri.applied,
156
+ changes: changes,
157
+ previousComponents: previousComponents,
158
+ newComponents: newComponents
159
+ }
160
+ });
161
+ } catch (e) {
162
+ return JSON.stringify({ ok: false, error: e.toString() });
163
+ }
164
+ }