|
57 | 57 | - `nlp.py` - POST /nlp/command → LLMConfig object (not dict), explanation falls back to param_source |
58 | 58 |
|
59 | 59 | ### Frontend (CEP Panel) |
60 | | -- `extension/com.opencut.panel/client/main.js` (~6169 lines) - Frontend controller. State vars: lastTimelineCuts, sequenceInfo, footageIndex, beatMarkerTimes, seqMarkersData, renameItemsData, multicamCutsData, repeatCutsData, chaptersData. New init functions: initTimelineFeatures, initCaptionNewFeatures, initAudioNewFeatures, initDeliverablesFeatures, initNlpFeatures. LLM settings loaded on startup via loadLlmSettings(). |
61 | | -- `extension/com.opencut.panel/client/index.html` (~2835 lines) - UI layout (sidebar + content-area, 8 tabs: Cut, Captions, Audio, Video, Export, Timeline, NLP, Settings). Settings tab now has LLM config card + Audio/Zoom Defaults card. |
62 | | -- `extension/com.opencut.panel/client/style.css` (~3642 lines) - Themes & styles. New classes: .smart-bin-rule, .footage-result-item, .multicam-track-row, .rename-name-input, .input-row. |
63 | | -- `extension/com.opencut.panel/host/index.jsx` (~2177 lines) - ExtendScript host. **New functions (lines 1315–2177):** ocGetSequenceInfo, ocAddSequenceMarkers, ocGetSequenceMarkers, ocApplySequenceCuts, ocApplyClipKeyframes, ocBatchRenameProjectItems, ocCreateSmartBins, ocAddNativeCaptionTrack, ocGetProjectBins, ocExportSequenceRange. Private helpers: _findByNodeId, _collectMediaItems, _collectBins. |
| 60 | +- `extension/com.opencut.panel/client/main.js` (~6850 lines) - Frontend controller. State vars: lastTimelineCuts, sequenceInfo, footageIndex, beatMarkerTimes, seqMarkersData, renameItemsData, multicamCutsData, repeatCutsData, chaptersData. New init functions: initTimelineFeatures, initCaptionNewFeatures, initAudioNewFeatures, initDeliverablesFeatures, initNlpFeatures. LLM settings loaded on startup via loadLlmSettings(). |
| 61 | +- `extension/com.opencut.panel/client/index.html` (~3115 lines) - UI layout (sidebar + content-area, 8 tabs: Cut, Captions, Audio, Video, Export, Timeline, NLP, Settings). Settings tab now has LLM config card + Audio/Zoom Defaults card. |
| 62 | +- `extension/com.opencut.panel/client/style.css` (~4182 lines) - Themes & styles. New classes: .smart-bin-rule, .footage-result-item, .multicam-track-row, .rename-name-input, .input-row. Design token shadow system (--shadow-sm/md/lg/xl/inner/glow-sm/glow-md). 6 complete themes. |
| 63 | +- `extension/com.opencut.panel/host/index.jsx` (~2230 lines) - ExtendScript host. **New functions (lines 1315–2230):** ocGetSequenceInfo, ocAddSequenceMarkers, ocGetSequenceMarkers, ocApplySequenceCuts, ocApplyClipKeyframes, ocBatchRenameProjectItems, ocCreateSmartBins, ocAddNativeCaptionTrack, ocGetProjectBins, ocExportSequenceRange. Private helpers: _findByNodeId, _collectMediaItems, _collectBins. Markers use getFirstMarker/getNextMarker iterator (not indexed access). |
64 | 64 |
|
65 | 65 | ### UXP Panel (Premiere Pro 25.6+) |
66 | 66 | - `extension/com.opencut.uxp/manifest.json` - UXP plugin manifest, targets PPRO minVersion 25.6, network domains 5679–5689, localFileSystem fullAccess |
|
120 | 120 | - Lint: `ruff check opencut/` — codebase is fully clean, pre-commit enforces on every commit |
121 | 121 |
|
122 | 122 | ## Version |
123 | | -- Current: **v1.5.6** |
| 123 | +- Current: **v1.7.1** |
124 | 124 | - All version strings: `pyproject.toml`, `__init__.py`, `CSXS/manifest.xml` (ExtensionBundleVersion + Version), `com.opencut.uxp/manifest.json`, `com.opencut.uxp/main.js` (VERSION const), `index.html` version display, README badge |
125 | 125 | - Use `python scripts/sync_version.py --set X.Y.Z` to update all 18 targets at once (including UXP files) |
126 | 126 |
|
|
160 | 160 | - **UXP endpoint convention** — UXP handlers MUST use full Blueprint-prefixed paths (`/audio/denoise`, `/video/color-match`, `/captions/chapters`, `/timeline/batch-rename`, `/search/footage`, `/nlp/command`, `/deliverables/vfx-sheet`). Never use bare paths like `/denoise` or `/chapters`. |
161 | 161 | - **ExtendScript data format** — `ocAddSequenceMarkers` expects a JSON array of `{time, name, type}` objects, NOT a wrapper object. `ocBatchRenameProjectItems` reads `{nodeId, newName}`. `ocCreateSmartBins` reads `{binName, rule, field, value}`. Always verify field names match between JS and JSX. |
162 | 162 | - **Queue allowlist** — New async routes MUST be added to `_ALLOWED_QUEUE_ENDPOINTS` in jobs_routes.py, or queue operations silently fail with "Endpoint not queueable". |
| 163 | +- **`run_ffmpeg()` returns `str`, not CompletedProcess** — It raises `RuntimeError` on non-zero exit and returns stderr as a string. Never access `.returncode` or `.stderr` on the return value. If you need the `subprocess.CompletedProcess` fallback path, use `subprocess.run()` directly. |
| 164 | +- **ExtendScript MarkerCollection** — Use `getFirstMarker()`/`getNextMarker()` iterator, NOT `markers[i]` indexed access (unreliable across Premiere versions). Pattern: `var m = markers.getFirstMarker(); while (m) { ... try { m = markers.getNextMarker(m); } catch(e) { m = null; } }` |
| 165 | +- **CSS `hidden` class vs `style.display`** — Setting `style.display=""` does NOT override a `display:none` from a CSS class. Use `classList.toggle("hidden", ...)` or `classList.remove("hidden")` instead. |
| 166 | +- **Workflow preset steps** — Each step must be a self-contained `{endpoint, payload, label}` object. Do NOT rely on `pendingTranslate`/`pendingBurnin` flags for chaining — those only work for manual button clicks, not workflow presets. |
| 167 | +- **Duplicate HTML `class` attributes** — HTML parser silently discards the second `class=` attribute. Always merge into a single `class="cls1 cls2"`. Grep with `class=".+" class="` to detect. |
| 168 | +- **`cancelJob()` order** — Close SSE/poll streams BEFORE nulling `currentJob` to prevent in-flight events from triggering `onJobDone` after cancel. |
163 | 169 | - **Never `git add -A`** — `installer/bin/`, `installer/obj/`, `installer/publish/` are build artifacts NOT in `.gitignore` (they're tracked in the repo). Use specific file paths when staging. |
164 | 170 | - **Frozen builds** — `sys.executable` points to the exe, not Python. `safe_pip_install()` and `_setup_system_site_packages()` detect frozen state and find system Python from PATH instead. |
165 | 171 | - **Ruff CI rules** — CI runs `ruff check opencut/ --select E,F,I --ignore E501`. Codebase is fully lint-clean as of v1.3.0. Use `# noqa: F401` for intentional lazy imports, `# noqa: E402` for delayed imports, `# noqa: F821` for closure-scoped forward refs. |
@@ -777,3 +783,23 @@ enhance = ["resemble-enhance>=0.0.1"] |
777 | 783 | - **async_job thread tracking** — decorator stores thread handle in job dict (`_thread` was always None) |
778 | 784 | - **ExtendScript projectItem safety** — in/out point reset guaranteed even if insert loop throws |
779 | 785 | - **Test fixes** — 5 broken tests fixed (mock paths updated for consolidated helpers, tempdir context scope) |
| 786 | + |
| 787 | +## v1.5.6 Batch 35 Bug Fixes (Subtle Bug Hunt) |
| 788 | +- **color_match.py AttributeError CRASH** — `run_ffmpeg()` returns `str` (stderr) but code accessed `.returncode`/`.stderr` (CompletedProcess attributes). Color matching was **completely broken**. Fixed: `run_ffmpeg` raises on failure (no return check needed), fallback `subprocess.run` checks returncode separately. |
| 789 | +- **auto_edit.py temp dir destroys XML** — `finally: shutil.rmtree(temp_dir)` deleted the XML result file before caller could use it. Fixed: copy XML to persistent temp dir before cleanup. |
| 790 | +- **ExtendScript marker iteration** — `seqMarkers[i]` indexed access is unreliable on Premiere's MarkerCollection. Switched both `ocGetSequenceInfo` and `ocGetSequenceMarkers` to `getFirstMarker()`/`getNextMarker()` iterator pattern. |
| 791 | +- **silenceSpeedGroup permanently hidden** — Element has CSS class `hidden` (`display:none`) but JS used `style.display=""` to show it — inline style removal doesn't override class rule. Speed-up slider was **always invisible**. Fixed: `classList.toggle("hidden", ...)`. |
| 792 | +- **Translate Pipeline workflow** — Only transcribed, never translated. Relied on `pendingTranslate` flag that workflow runner never set. Added explicit `/captions/translate` step. |
| 793 | +- **Social Ready workflow** — Dropdown promised "Burn-in Captions" but workflow had no captions step. Added `/captions/burn-in` step. |
| 794 | +- **Styled captions checkboxes dead** — `captionWordHighlight` and `captionAutoEmoji` checkbox values never included in API payload. Added both to `startJob` payload. |
| 795 | +- **Workflow denoise method mismatch** — `clean_audio` and `pro_video` presets hardcoded `method: "rnnoise"` but UI only offers `afftdn`/`bandpass`. Changed to `afftdn`. |
| 796 | +- **Cancel/complete race condition** — SSE could deliver "complete" event after `cancelJob()` nulled `currentJob` but before it closed the stream, causing unwanted auto-import. Fixed: close SSE/poll **before** nulling `currentJob`. |
| 797 | +- **NLP auto-execute stale selectedPath** — `selectedPath` read at callback time, not command time. If user switches clips during NLP API call, job runs on wrong clip. Fixed: snapshot at command invocation. |
| 798 | +- **ocApplySequenceCuts NaN sort corruption** — Sort comparator `b.start - a.start` ran before Number coercion; string/null/undefined values produce NaN, corrupting sort order and causing wrong clips to be deleted. Fixed: pre-coerce all cut times before sort. |
| 799 | +- **ocExportSequenceRange persistent side effect** — `setInPoint`/`setOutPoint` persist on the sequence after export, constraining all future playback and exports. Fixed: save/restore original in/out points. |
| 800 | +- **ocAddNativeCaptionTrack inflated count** — Returned `segments.length` (original array size) instead of `srtIndex` (actual written count after skipping invalid segments). |
| 801 | +- **Keyframe time coercion** — `kf.time || 0` used without `Number()` coercion; string time values from JSON could cause wrong keyframe placement. Added `Number()`. |
| 802 | +- **export_video no progress** — Missing `-progress pipe:1` flag meant FFmpeg wrote progress to stderr (not stdout), so progress parsing never matched. Progress bar was stuck at 20%. |
| 803 | +- **export_video no timeout** — `proc.wait()` had no timeout; hung FFmpeg process blocked the thread forever. Added scaled timeout with kill. |
| 804 | +- **export_video partial file leak** — Failed FFmpeg runs left corrupt partial output files on disk. Added cleanup on non-zero exit. |
| 805 | +- **10 duplicate class attributes in HTML** — 10 elements had two `class=` attributes; HTML parser silently ignores the second, losing spacing utilities (mt-xs, mt-sm, mb-sm, mt-md). All merged into single attributes. |
0 commit comments