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,171 @@
1
+
2
+ // seconds -> "HH:MM:SS:FF" — the razor argument form PROVEN working on
3
+ // this build (remove-track-intervals live-validated it); the ticksString
4
+ // form silently no-ops (live-tested 2026-07-17).
5
+ function ppbRazorAll_secondsToQeTimecode(seconds, fps) {
6
+ var totalFrames = Math.round(seconds * fps);
7
+ var ff = totalFrames % Math.round(fps);
8
+ var totalSeconds = Math.floor(totalFrames / Math.round(fps));
9
+ var ss = totalSeconds % 60;
10
+ var totalMinutes = Math.floor(totalSeconds / 60);
11
+ var mm = totalMinutes % 60;
12
+ var hh = Math.floor(totalMinutes / 60);
13
+ function pad2(n) { return (n < 10 ? "0" : "") + n; }
14
+ return pad2(hh) + ":" + pad2(mm) + ":" + pad2(ss) + ":" + pad2(ff);
15
+ }
16
+ // Command: razor-all-tracks → ppb_razorAllTracks
17
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
18
+ // same global ExtendScript context — shared helpers (ensureQEEnabled,
19
+ // findSequenceByName, TICKS_PER_SECOND, activateSequenceForQE, ...) are
20
+ // already defined there.
21
+ //
22
+ // Ported from leancoderkavy/premiere-pro-mcp's track-targeting.ts
23
+ // razor_all_tracks. Razors (splits) every video+audio track at a given
24
+ // time (defaults to the sequence's own playhead if `seconds` is omitted)
25
+ // via QE `track.razor(ticksString)` — same razor mechanism as
26
+ // remove-track-intervals, but applied to every track instead of one.
27
+ // Destructive-ish: a razor cut cannot be undone (undo is non-functional on
28
+ // this build per README.md), and callers should not run this against real
29
+ // footage without first duplicating the sequence.
30
+ //
31
+ // Verification: per-track clip-item-COUNT before/after (via the QE
32
+ // track's numItems) rather than trusting razor()'s own return value —
33
+ // same "never trust the call's return value" rule as every other QE
34
+ // command in this panel.
35
+ function ppb_razorAllTracks(argsJson) {
36
+ try {
37
+ var args;
38
+ try {
39
+ args = JSON.parse(argsJson);
40
+ } catch (e) {
41
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
42
+ }
43
+
44
+ if (!app.project) {
45
+ return JSON.stringify({ ok: false, error: "no project open" });
46
+ }
47
+
48
+ var seq = null;
49
+ if (args.sequenceName && typeof args.sequenceName === "string") {
50
+ seq = findSequenceByName(args.sequenceName);
51
+ if (!seq) {
52
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
53
+ }
54
+ } else {
55
+ seq = app.project.activeSequence;
56
+ if (!seq) {
57
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
58
+ }
59
+ }
60
+
61
+ try {
62
+ ensureQEEnabled();
63
+ activateSequenceForQE(seq);
64
+ } catch (e) {
65
+ return JSON.stringify({ ok: false, error: "app.enableQE()/sequence activation failed: " + e.toString() });
66
+ }
67
+ if (typeof qe === "undefined" || !qe.project) {
68
+ return JSON.stringify({ ok: false, error: "QE DOM not available after enableQE()" });
69
+ }
70
+ var qeSeq = qe.project.getActiveSequence();
71
+ if (!qeSeq) {
72
+ return JSON.stringify({ ok: false, error: "qe.project.getActiveSequence() returned nothing after activating the sequence" });
73
+ }
74
+
75
+ var atSeconds;
76
+ if (typeof args.seconds === "number" && !isNaN(args.seconds)) {
77
+ atSeconds = args.seconds;
78
+ } else {
79
+ try {
80
+ atSeconds = seq.getPlayerPosition().seconds;
81
+ } catch (e) {
82
+ return JSON.stringify({ ok: false, error: "seconds was omitted and the playhead position could not be read: " + e.toString() });
83
+ }
84
+ }
85
+ var ticksString = String(Math.round(atSeconds * TICKS_PER_SECOND));
86
+ var fps = getSequenceFps(seq);
87
+ var qeTimecode = ppbRazorAll_secondsToQeTimecode(args.seconds, fps);
88
+
89
+ var perTrack = [];
90
+ var totalRazored = 0;
91
+
92
+ var numVideoTracks = 0;
93
+ try { numVideoTracks = qeSeq.numVideoTracks; } catch (e) { numVideoTracks = 0; }
94
+ for (var v = 0; v < numVideoTracks; v++) {
95
+ var vTrack = null;
96
+ try { vTrack = qeSeq.getVideoTrackAt(v); } catch (e) { vTrack = null; }
97
+ if (!vTrack) {
98
+ perTrack.push({ trackType: "video", trackIndex: v, error: "QE track lookup failed" });
99
+ continue;
100
+ }
101
+ var vBefore = null;
102
+ try { vBefore = vTrack.numItems; } catch (e) { vBefore = null; }
103
+ var vRazorError = null;
104
+ try {
105
+ vTrack.razor(qeTimecode);
106
+ } catch (e) {
107
+ vRazorError = e.toString();
108
+ }
109
+ var vAfter = null;
110
+ try { vAfter = vTrack.numItems; } catch (e) { vAfter = null; }
111
+ var vChanged = vBefore !== null && vAfter !== null && vAfter > vBefore;
112
+ if (vChanged) {
113
+ totalRazored++;
114
+ }
115
+ perTrack.push({
116
+ trackType: "video",
117
+ trackIndex: v,
118
+ itemCountBefore: vBefore,
119
+ itemCountAfter: vAfter,
120
+ razored: vChanged,
121
+ error: vRazorError
122
+ });
123
+ }
124
+
125
+ var numAudioTracks = 0;
126
+ try { numAudioTracks = qeSeq.numAudioTracks; } catch (e) { numAudioTracks = 0; }
127
+ for (var a = 0; a < numAudioTracks; a++) {
128
+ var aTrack = null;
129
+ try { aTrack = qeSeq.getAudioTrackAt(a); } catch (e) { aTrack = null; }
130
+ if (!aTrack) {
131
+ perTrack.push({ trackType: "audio", trackIndex: a, error: "QE track lookup failed" });
132
+ continue;
133
+ }
134
+ var aBefore = null;
135
+ try { aBefore = aTrack.numItems; } catch (e) { aBefore = null; }
136
+ var aRazorError = null;
137
+ try {
138
+ aTrack.razor(qeTimecode);
139
+ } catch (e) {
140
+ aRazorError = e.toString();
141
+ }
142
+ var aAfter = null;
143
+ try { aAfter = aTrack.numItems; } catch (e) { aAfter = null; }
144
+ var aChanged = aBefore !== null && aAfter !== null && aAfter > aBefore;
145
+ if (aChanged) {
146
+ totalRazored++;
147
+ }
148
+ perTrack.push({
149
+ trackType: "audio",
150
+ trackIndex: a,
151
+ itemCountBefore: aBefore,
152
+ itemCountAfter: aAfter,
153
+ razored: aChanged,
154
+ error: aRazorError
155
+ });
156
+ }
157
+
158
+ return JSON.stringify({
159
+ ok: true,
160
+ result: {
161
+ sequenceName: seq.name,
162
+ atSeconds: atSeconds,
163
+ tracksAttempted: perTrack.length,
164
+ tracksRazored: totalRazored,
165
+ tracks: perTrack
166
+ }
167
+ });
168
+ } catch (e) {
169
+ return JSON.stringify({ ok: false, error: e.toString() });
170
+ }
171
+ }
@@ -0,0 +1,69 @@
1
+ // Command: redo → ppb_redo
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (ensureQEEnabled, ...)
4
+ // are already defined there.
5
+ //
6
+ // REWRITTEN 2026-07-17 after the probe session (see BUILD_FINDINGS.md
7
+ // corrections): qe.project.redo() WORKS on this build — live-verified
8
+ // re-applying an undone setSpeed, with qe.project.undoStackIndex()
9
+ // (an int-returning function) incrementing on a real redo. That index
10
+ // is the verification primitive; app.project.redo() does not exist here.
11
+
12
+ function ppb_redo(argsJson) {
13
+ try {
14
+ if (!app.project) {
15
+ return JSON.stringify({ ok: false, error: "no project open" });
16
+ }
17
+
18
+ try {
19
+ ensureQEEnabled();
20
+ } catch (e) {
21
+ return JSON.stringify({ ok: false, error: "app.enableQE() failed: " + e.toString() });
22
+ }
23
+ if (typeof qe === "undefined" || !qe.project || typeof qe.project.redo !== "function") {
24
+ return JSON.stringify({ ok: false, error: "qe.project.redo is not available on this Premiere build" });
25
+ }
26
+
27
+ function readStackIndex() {
28
+ try {
29
+ if (typeof qe.project.undoStackIndex === "function") {
30
+ return qe.project.undoStackIndex();
31
+ }
32
+ } catch (e2) {
33
+ // fall through
34
+ }
35
+ return null;
36
+ }
37
+
38
+ var indexBefore = readStackIndex();
39
+ try {
40
+ qe.project.redo();
41
+ } catch (e3) {
42
+ return JSON.stringify({ ok: false, error: "qe.project.redo() threw: " + e3.toString() });
43
+ }
44
+ var indexAfter = readStackIndex();
45
+
46
+ var verified = null;
47
+ if (indexBefore !== null && indexAfter !== null) {
48
+ verified = indexAfter > indexBefore;
49
+ }
50
+
51
+ return JSON.stringify({
52
+ ok: true,
53
+ result: {
54
+ redone: verified !== false,
55
+ verified: verified,
56
+ method: "qe.project.redo",
57
+ undoStackIndexBefore: indexBefore,
58
+ undoStackIndexAfter: indexAfter,
59
+ note: verified === null
60
+ ? "undoStackIndex() unavailable — this only confirms the call did not throw"
61
+ : (verified
62
+ ? "verified via qe.project.undoStackIndex() incrementing"
63
+ : "the stack index did not move — there was nothing to redo")
64
+ }
65
+ });
66
+ } catch (e) {
67
+ return JSON.stringify({ ok: false, error: e.toString() });
68
+ }
69
+ }
@@ -0,0 +1,101 @@
1
+ // Command: refresh-media → ppb_refreshMedia
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (TICKS_PER_SECOND, ...)
4
+ // are already defined there.
5
+ //
6
+ // Ports the reference project's media.ts refresh_media tool. Item
7
+ // resolution by nodeId/name uses children-presence recursion (NOT an
8
+ // isBin() gate), per get-project-item-info.jsx's live-debugged finding.
9
+ // item.refreshMedia() has no confirmed getter to detect a real content
10
+ // change, so success here only confirms the call didn't throw — the same
11
+ // honesty pattern as select-project-item's "called: true" result.
12
+
13
+ function ppbRefreshMedia_findByNodeId(item, nodeId, depth) {
14
+ if (depth > 32) {
15
+ return null;
16
+ }
17
+ try {
18
+ if (item.nodeId === nodeId) {
19
+ return item;
20
+ }
21
+ } catch (e) {
22
+ // fall through
23
+ }
24
+ if (item.children && item.children.numItems > 0) {
25
+ for (var i = 0; i < item.children.numItems; i++) {
26
+ var found = ppbRefreshMedia_findByNodeId(item.children[i], nodeId, depth + 1);
27
+ if (found) {
28
+ return found;
29
+ }
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+
35
+ function ppbRefreshMedia_findByName(item, name, depth) {
36
+ if (depth > 32) {
37
+ return null;
38
+ }
39
+ try {
40
+ if (item.name === name) {
41
+ return item;
42
+ }
43
+ } catch (e) {
44
+ // fall through
45
+ }
46
+ if (item.children && item.children.numItems > 0) {
47
+ for (var i = 0; i < item.children.numItems; i++) {
48
+ var found = ppbRefreshMedia_findByName(item.children[i], name, depth + 1);
49
+ if (found) {
50
+ return found;
51
+ }
52
+ }
53
+ }
54
+ return null;
55
+ }
56
+
57
+ function ppb_refreshMedia(argsJson) {
58
+ try {
59
+ var args;
60
+ try {
61
+ args = JSON.parse(argsJson);
62
+ } catch (e) {
63
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
64
+ }
65
+
66
+ var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
67
+ var hasName = typeof args.name === "string" && args.name.length > 0;
68
+ if (!hasNodeId && !hasName) {
69
+ return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
70
+ }
71
+
72
+ if (!app.project) {
73
+ return JSON.stringify({ ok: false, error: "no project open" });
74
+ }
75
+
76
+ var item = hasNodeId
77
+ ? ppbRefreshMedia_findByNodeId(app.project.rootItem, args.nodeId, 0)
78
+ : ppbRefreshMedia_findByName(app.project.rootItem, args.name, 0);
79
+ if (!item) {
80
+ return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
81
+ }
82
+
83
+ try {
84
+ item.refreshMedia();
85
+ } catch (e) {
86
+ return JSON.stringify({ ok: false, error: "refreshMedia() failed: " + e.toString() });
87
+ }
88
+
89
+ return JSON.stringify({
90
+ ok: true,
91
+ result: {
92
+ nodeId: item.nodeId,
93
+ name: item.name,
94
+ called: true,
95
+ note: "refreshMedia() has no confirmed getter to detect a content change — this only confirms the call didn't throw"
96
+ }
97
+ });
98
+ } catch (e) {
99
+ return JSON.stringify({ ok: false, error: e.toString() });
100
+ }
101
+ }
@@ -0,0 +1,132 @@
1
+ // Command: relink-media → ppb_relinkMedia
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (TICKS_PER_SECOND, ...)
4
+ // are already defined there.
5
+ //
6
+ // Ports the reference project's media.ts relink_media tool. Item
7
+ // resolution by nodeId/name uses children-presence recursion (NOT an
8
+ // isBin() gate), per get-project-item-info.jsx's live-debugged finding
9
+ // that the ROOT item's type is ROOT, not BIN. Checks canChangeMediaPath()
10
+ // first, then calls item.changeMediaPath(newPath, true) per
11
+ // PREMIERE_API_NOTES.md, verified via a getMediaPath() read-back against
12
+ // the requested path.
13
+
14
+ function ppbRelinkMedia_findByNodeId(item, nodeId, depth) {
15
+ if (depth > 32) {
16
+ return null;
17
+ }
18
+ try {
19
+ if (item.nodeId === nodeId) {
20
+ return item;
21
+ }
22
+ } catch (e) {
23
+ // fall through
24
+ }
25
+ if (item.children && item.children.numItems > 0) {
26
+ for (var i = 0; i < item.children.numItems; i++) {
27
+ var found = ppbRelinkMedia_findByNodeId(item.children[i], nodeId, depth + 1);
28
+ if (found) {
29
+ return found;
30
+ }
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+
36
+ function ppbRelinkMedia_findByName(item, name, depth) {
37
+ if (depth > 32) {
38
+ return null;
39
+ }
40
+ try {
41
+ if (item.name === name) {
42
+ return item;
43
+ }
44
+ } catch (e) {
45
+ // fall through
46
+ }
47
+ if (item.children && item.children.numItems > 0) {
48
+ for (var i = 0; i < item.children.numItems; i++) {
49
+ var found = ppbRelinkMedia_findByName(item.children[i], name, depth + 1);
50
+ if (found) {
51
+ return found;
52
+ }
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ function ppbRelinkMedia_resolveItem(args) {
59
+ if (args.nodeId) {
60
+ return ppbRelinkMedia_findByNodeId(app.project.rootItem, args.nodeId, 0);
61
+ }
62
+ return ppbRelinkMedia_findByName(app.project.rootItem, args.name, 0);
63
+ }
64
+
65
+ function ppb_relinkMedia(argsJson) {
66
+ try {
67
+ var args;
68
+ try {
69
+ args = JSON.parse(argsJson);
70
+ } catch (e) {
71
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
72
+ }
73
+
74
+ var hasNodeId = typeof args.nodeId === "string" && args.nodeId.length > 0;
75
+ var hasName = typeof args.name === "string" && args.name.length > 0;
76
+ if (!hasNodeId && !hasName) {
77
+ return JSON.stringify({ ok: false, error: "either nodeId or name is required" });
78
+ }
79
+ if (!args.newPath || typeof args.newPath !== "string") {
80
+ return JSON.stringify({ ok: false, error: "newPath is required" });
81
+ }
82
+
83
+ if (!app.project) {
84
+ return JSON.stringify({ ok: false, error: "no project open" });
85
+ }
86
+
87
+ var item = ppbRelinkMedia_resolveItem({ nodeId: hasNodeId ? args.nodeId : null, name: hasNodeId ? null : args.name });
88
+ if (!item) {
89
+ return JSON.stringify({ ok: false, error: "no project item found matching the given nodeId/name" });
90
+ }
91
+
92
+ var canChange = null;
93
+ try { canChange = item.canChangeMediaPath(); } catch (e) { canChange = null; }
94
+ if (canChange === false) {
95
+ return JSON.stringify({
96
+ ok: false,
97
+ error: "canChangeMediaPath() returned false — this item's media path cannot be changed",
98
+ nodeId: item.nodeId,
99
+ name: item.name
100
+ });
101
+ }
102
+
103
+ var previousValue = null;
104
+ try { previousValue = item.getMediaPath(); } catch (e) { previousValue = null; }
105
+
106
+ var callResult = null;
107
+ try {
108
+ callResult = item.changeMediaPath(args.newPath, true);
109
+ } catch (e) {
110
+ return JSON.stringify({ ok: false, error: "changeMediaPath() failed: " + e.toString() });
111
+ }
112
+
113
+ var newValue = null;
114
+ try { newValue = item.getMediaPath(); } catch (e) { newValue = null; }
115
+
116
+ return JSON.stringify({
117
+ ok: true,
118
+ result: {
119
+ nodeId: item.nodeId,
120
+ name: item.name,
121
+ canChangeMediaPath: canChange,
122
+ callResult: callResult,
123
+ previousValue: previousValue,
124
+ requestedValue: args.newPath,
125
+ newValue: newValue,
126
+ verified: newValue === args.newPath
127
+ }
128
+ });
129
+ } catch (e) {
130
+ return JSON.stringify({ ok: false, error: e.toString() });
131
+ }
132
+ }
@@ -0,0 +1,114 @@
1
+ // Command: remove-all-effects → ppb_removeAllEffects
2
+ // Loaded lazily by ppb_dispatch (host/index.jsx) on first use, into the
3
+ // same global ExtendScript context — shared helpers (findSequenceByName,
4
+ // ensureQEEnabled, activateSequenceForQE, resolveTimelineClip,
5
+ // resolveQeClip, serializeClipComponents, ...) are already defined there.
6
+ //
7
+ // QE-only: qeClip.removeEffects() — per PREMIERE_API_NOTES.md, this strips
8
+ // ALL applied effects from a clip in one call, but the built-in components
9
+ // (Motion/Opacity/Volume/Panner) survive per QE semantics and are NOT
10
+ // removed. Verified by reading standard-DOM clip.components before/after —
11
+ // the count should drop to (at most) the built-in baseline, never to zero
12
+ // on a normal clip.
13
+ function ppb_removeAllEffects(argsJson) {
14
+ try {
15
+ var args;
16
+ try {
17
+ args = JSON.parse(argsJson);
18
+ } catch (e) {
19
+ return JSON.stringify({ ok: false, error: "invalid args JSON: " + e.toString() });
20
+ }
21
+
22
+ if (args.trackType !== "video" && args.trackType !== "audio") {
23
+ return JSON.stringify({ ok: false, error: "trackType must be \"video\" or \"audio\"" });
24
+ }
25
+ if (typeof args.trackIndex !== "number" || args.trackIndex < 0 || Math.floor(args.trackIndex) !== args.trackIndex) {
26
+ return JSON.stringify({ ok: false, error: "trackIndex must be a non-negative integer" });
27
+ }
28
+ if (typeof args.clipIndex !== "number" || args.clipIndex < 0 || Math.floor(args.clipIndex) !== args.clipIndex) {
29
+ return JSON.stringify({ ok: false, error: "clipIndex must be a non-negative integer" });
30
+ }
31
+
32
+ if (!app.project) {
33
+ return JSON.stringify({ ok: false, error: "no project open" });
34
+ }
35
+
36
+ var seq = null;
37
+ if (args.sequenceName && typeof args.sequenceName === "string") {
38
+ seq = findSequenceByName(args.sequenceName);
39
+ if (!seq) {
40
+ return JSON.stringify({ ok: false, error: "no sequence named \"" + args.sequenceName + "\" is open" });
41
+ }
42
+ } else {
43
+ seq = app.project.activeSequence;
44
+ if (!seq) {
45
+ return JSON.stringify({ ok: false, error: "no active sequence, and no sequenceName given" });
46
+ }
47
+ }
48
+
49
+ var resolvedClip = resolveTimelineClip(seq, args.trackType, args.trackIndex, args.clipIndex);
50
+ if (resolvedClip.error) {
51
+ return JSON.stringify({ ok: false, error: resolvedClip.error });
52
+ }
53
+ var clip = resolvedClip.clip;
54
+ var clipName = null;
55
+ try { clipName = clip.name; } catch (e) { clipName = null; }
56
+
57
+ var previousComponents = serializeClipComponents(clip);
58
+ var previousCount = previousComponents.length;
59
+
60
+ try {
61
+ ensureQEEnabled();
62
+ activateSequenceForQE(seq);
63
+ } catch (e) {
64
+ return JSON.stringify({ ok: false, error: "app.enableQE()/sequence activation failed: " + e.toString() });
65
+ }
66
+ if (typeof qe === "undefined" || !qe.project) {
67
+ return JSON.stringify({ ok: false, error: "QE DOM not available after enableQE()" });
68
+ }
69
+
70
+ var qeSeq;
71
+ try {
72
+ qeSeq = qe.project.getActiveSequence();
73
+ } catch (e) {
74
+ return JSON.stringify({ ok: false, error: "qe.project.getActiveSequence() failed: " + e.toString() });
75
+ }
76
+
77
+ var qeResolved = resolveQeClip(qeSeq, args.trackType, args.trackIndex, args.clipIndex);
78
+ if (qeResolved.error) {
79
+ return JSON.stringify({ ok: false, error: qeResolved.error });
80
+ }
81
+
82
+ try {
83
+ qeResolved.qeClip.removeEffects();
84
+ } catch (e) {
85
+ return JSON.stringify({ ok: false, error: "qeClip.removeEffects() failed: " + e.toString() });
86
+ }
87
+
88
+ var newComponents = serializeClipComponents(clip);
89
+ var newCount = newComponents.length;
90
+ var removedCount = previousCount - newCount;
91
+ var verified = removedCount > 0;
92
+
93
+ var result = {
94
+ sequenceName: seq.name,
95
+ trackType: args.trackType,
96
+ trackIndex: args.trackIndex,
97
+ clipIndex: args.clipIndex,
98
+ clipName: clipName,
99
+ verified: verified,
100
+ removedCount: removedCount,
101
+ previousComponentCount: previousCount,
102
+ newComponentCount: newCount,
103
+ previousComponents: previousComponents,
104
+ remainingComponents: newComponents
105
+ };
106
+ if (!verified) {
107
+ result.note = "qeClip.removeEffects() did not throw, but components.numItems did not drop — either the clip had no removable (non-built-in) effects applied, or removeEffects() is non-functional on this build.";
108
+ }
109
+
110
+ return JSON.stringify({ ok: true, result: result });
111
+ } catch (e) {
112
+ return JSON.stringify({ ok: false, error: e.toString() });
113
+ }
114
+ }