Back to home

Changelog

All notable changes to CUTFORGE are documented in this file.

Fixed

  • Public site - pricing/changelog segmented toggles readable; Fonctionnalités nav links to `/#why` with sticky offset.

Changed

  • Public site (cutforge.app) - migrate to Next.js 15 (App Router) + Tailwind with an Apple-style marketing landing (EN/FR/RU); keep API contracts via `pages/api/`; restyle pricing, manual, changelog, and legal pages; minimal `/ops` dashboard.
  • Landing principles copy - clearer local-disk / honest-pricing lines; drop the FFmpeg tagline (EN/FR/RU).
  • Landing motion - full-bleed hero with scroll scale, two sticky feature moments, cinematic reveals on principles and sections.

[0.9.15] - 2026-07-09

Fixed

  • Trim undo/redo - keep `trimClip` delta ops on the opposite stack (was converting to slim checkpoints and dropping waveforms / live fields); restore face-filter and linked captions with the trim patch.
  • Start-handle trim at 0s - dragging the left handle left when the clip is already at timeline 0 no longer expands/pushes the clip to the right (clamp order: source head before timeline edge).

Changed

  • `src/lib` modularization (phases 2-8) - `ui-shell/`, `telemetry/`, `export/`, `media/`, `face-filter/`, `preview/`, `project-io/`, `timeline/` (hub + leaves) with shims at old `@/lib/*` paths (ADR 010).
  • Domain timing/mask - pure implementations in `src/lib/domain/` (`reverse-source-time`, dual-versus geometry, mask geometry); face-filter mask re-exports domain.
  • Undo history - dynamic depth by snapshot size; v2 typed ops (`checkpoint` + `trimClip`); trim drag and playhead trim push compact `trimClip` ops.
  • Export compositor - full-timeline audio, face-mask inputs, HW helpers, and video/sticker layer chains extracted from `render.rs` (`audio.rs`, `mask_inputs.rs`, `render_helpers.rs`, `video_layers.rs`).
  • Shared types codegen - production TS re-exports generated `FaceFilter` (full object), `FaceFilterPoint` / `FaceFilterKeyframe`, and `TextClipWord`; Rust field-name parity tests (structs still hand-written).
  • Domain shims - removed flat `@/lib/reverse-source-time` shim (imports use `@/lib/domain/reverse-source-time`).

[0.9.14] - 2026-07-09

Fixed

  • FFmpeg auto-install loop - invalidate status cache after managed install / path changes so a successful download is recognized in the same session (was stuck on Configuration FFmpeg after download).

Changed

  • R2 private channel - latest only - after each upload, purge older objects so only one app installer (plus `latest.json` / checksums) and one tracking/STT pack version remain (`purge-stale`).

[0.9.13] - 2026-07-09

Fixed

  • FFmpeg auto-install - bump pinned BtbN win64-gpl zip (`autobuild-2026-07-09-14-21`); previous June pin returned HTTP 404 after BtbN pruned the release.

Changed

  • Private channel downloads (R2-only) - installer TEST, tracking pack, STT pack, and updater `latest.json`: gate on `cutforge.app`, 307 redirect to Cloudflare R2 only (no GitHub `releases-private` stream/fallback). Publish scripts upload directly to R2 (`CUTFORGE_RELEASES_CHANNEL=r2`). See `docs/R2-PRIVATE-ASSETS.md`.
  • Pack download pins (CI) - shared URL policy + live gate/R2 checks for tracking and STT (same resilience pattern as FFmpeg pin); FFmpeg Rust↔sidecar sync test; publish script defaults aligned to embedded pack versions; docs/Rules aligned to R2-only private channel.
  • Gated pack APIs - `Cache-Control: no-store` on tracking/STT download redirects so CDN cannot cache a 307 without the gate.

[0.9.12] - 2026-07-09

Changed

  • FFmpeg PATH (docs + regression tests) - release PATH gate documented for bundled builds; contract test asserts debug-only PATH probing; Rust regression `path_fallback_disabled_in_release_builds`.

Fixed

  • Undo history - regression tests lock the 100-entry cap and heavy-project (STT words + face-filter keyframes) serialization.
  • Export / tracking cancel - additional Rust tests for mid-job `EXPORT_CANCELLED` / `FACE_TRACKING_CANCELLED` and isolated cancel flags; export hook test asserts `exportJob` cleared after cancel.
  • Media probe edge cases - regression tests for zero dimensions, corrupt stream JSON fields, and scrubbed invalid-JSON errors (no panic on import).
  • Rotated phone media (displaymatrix) - `probe_media` and tracker `probe_dimensions` store display-oriented width/height from ffprobe rotation metadata; preview face pick and tracker RGB pipe aligned with WebView / FFmpeg autorotate.

[0.9.11] - 2026-07-09

Changed

  • Site machine_id validation - checkout, Paddle fulfillment, and app-event accept only hashed machine id (64-hex) or legacy UUID, aligned with `/api/license` and `/ops`.
  • Face tracking vs privacy blur - SMART DETECT / Analyze store track-only keyframes (`amount: 0`) by default so smart reframe no longer implies blur; privacy blur is an explicit opt-in in the Face filter panel (kind/intensity when enabled). Preview skips the blur replica when `amount ≤ 1` and still shows the tracking outline.

Fixed

  • Face filter preview playback - when the active video visual is not loaded (`readyState < 2`), the playhead no longer advances on wall-clock time (mask/badge no longer animate while the frame stays frozen).
  • Face blur replica sync - blur duplicate video receives its ref before `useFaceBlurMediaSync` attaches, so playback stays aligned with the sharp preview.
  • Face blur layout - nested `.preview-media` fills the contain box (`object-fit: fill`); blur replica matches so the oval stays on the face instead of drifting right.

[0.9.10] - 2026-07-09

Added

  • Preview↔export parity (Phase 0-1) - inventory and export golden luma fixtures under `fixtures/parity/` (color, opacity, reverse, dual-versus, face-filter), `npm run test:parity:export` in `test:ci`.
  • Preview↔export parity (Phase 2) - TS↔Rust contracts for reverse source-time and dual-versus geometry; `merge_segments` keeps keyframe subdivision cuts.
  • Preview↔export parity (Phase 3) - soft parity without WebView: CSS color contract locks, reverse preview product-decision tests, dual-versus preview uses shared slot geometry helpers, `npm run test:parity:soft` (FFmpeg filter-chain luma vs Phase 1 color golden).

[0.9.5] - 2026-07-08

Fixed

  • WebM / VP9 import - waveform peak extraction no longer panics on `i16::MIN` PCM; `probe_media` catches waveform failures without crashing the app.
  • Face blur preview - ellipse mask from tracked bbox (not tiny landmark polygon); clipped duplicate video blur in WebView2; playback sync via `useFaceBlurMediaSync`.
  • Face tracking `--all-faces` - dev tracker binary probe + friendly error when an outdated pack lacks the flag; falls back to installed pack when needed.
  • Preview playback - pause guards (`shouldResumePreviewPlayback`) and overlay video sync reduce double-audio / stale autoplay after pause.
  • STT trim - caption `text` / `words` stay aligned when trimming linked text clips to the playhead.

Added

  • Tests - face blur preview media, dual versus / frame fit / smart reframe UI, `useFaceBlurMediaSync`, `project-meta`, playback pause; extended caption-sync and video-seek coverage.

[0.9.4] - 2026-07-07

Fixed

  • STT pack download (private builds) - `stt-pack-index.json` again uses `cutforge.app/api/download-stt-pack` (gate header) instead of a direct `releases-private` GitHub URL that fails without GitHub auth in-app.

Added

  • Regression - `scripts/stt-pack-index-url.mjs` + contract/gate tests lock STT proxy URL policy before every `test:ci`.

[0.9.3] - 2026-07-07

Added

  • Caption re-sync - STT captions stay aligned after media split/trim and global silence cut (`caption-sync.ts`, `sourceClipId`).
  • YouTube chapters - generate timeline markers from subtitle gaps; export `MM:SS` chapter file from the Pro panel.
  • Speaker zoom - auto keyframes punch-in on speech segments (waveform VAD + face center when available).
  • Multi-face blur - `all-faces` mode blurs every detected face per frame (crowd anonymization).

Docs

  • Phase B differentiation items #8, #10, #11, #12 marked complete in product TODO and status docs.

[0.9.2] - 2026-07-07

Added

  • Captions word-pop export - ASS `\t` bounce transform on active words (export parity with preview pop).
  • Caption word editor - merge adjacent words and split a word (text + timings) in the Text inspector.
  • Timeline silence markers - shaded regions on the ruler from waveform peaks; click to seek.
  • STT on public builds - `stt-pack-index.json` uses direct GitHub Releases URL so `downloadReady` works without the private gate.
  • Dual versus layout - split preview (top/bottom tracks), inspector section, export compositor path.
  • Transcript edit - remove spoken ranges from the transcript panel; ripple cuts on linked clips.
  • Clip frame fit - contain vs pan for aspect mismatch; preview drag pan; export compositor support.
  • New project templates - Shorts 9:16, YouTube 16:9, podcast audio picker on File -> New.

Fixed

  • E2E - `new-project.e2e.cjs` dismisses template dialog after the picker assertion (unblocks second test).
  • Deps - `crossbeam-epoch` 0.9.20 (RUSTSEC-2026-0204); document `memmap2` transitive ignore in `.cargo/audit.toml`.

Docs

  • Phase A short-form items marked complete in product TODO and status docs.
  • Doc hub: docs index, decisions, research, refreshed roadmap and V1 checklist.

[0.9.1] - 2026-07-05

UI

  • Frameless window (Windows) - custom title bar with minimize, maximize, close, and drag; Tauri ACL permissions for window chrome IPC
  • Smart reframe - disabling "Follow face on 9:16 export" restores project preview/export aspect to 16:9 when no other clip uses smart reframe
  • STT progress - subtitle generation overlay shows per-phase status (module check, download, install, audio extract, WhisperX load / transcribe / word alignment)

Fixed

  • Startup - remove React `StrictMode` in production (avoided double FFmpeg bootstrap on launch)
  • i18n - `windowChrome.*` message keys typed in `MessageKey`
  • STT (WhisperX) - skip `__pycache__` / `.pyc` in pack integrity checks so Python imports no longer invalidate the installed pack and force a full re-download on every subtitle run; stream WhisperX stderr for live progress; `stt` app log lines per step

Tests / dev

  • E2E - `window-chrome.e2e.cjs` (launch, minimize, maximize, drag, close when isolated); `test:e2e:window-chrome` script
  • Startup profiling - dev-only `[startup]` marks; Rust `check_ffmpeg_tools` wall-clock regression test (~337 ms budget)

[0.9.0] - 2026-07-04

Security (audit v6)

  • CSP / theme - anti-flash script moved to `public/theme-init.js` (no inline script in `index.html`); `theme.css` design tokens loaded before `App.css`
  • FFmpeg PATH - release builds no longer fall back to system `PATH` unless `CUTFORGE_ALLOW_PATH_FFMPEG=1`
  • License machine id - SHA-256 hashed id (`machine_id.rs`) with legacy UUID compatibility; revocation check uses `X-Cutforge-Machine-Id` header (site coordinated)
  • Activation - refuse license activation when machine uid cannot be resolved
  • Private download gate - STT/tracking pack URLs no longer append `?k=` query; header auth only
  • Repo hygiene - `target-karaoke-test/` gitignored; smart-reframe e2e writes to OS temp
  • IPC / media - path traversal guard comments; `probe_media` errors when duration missing (no silent 5s default); extra extensions in `guess_kind_from_path`
  • Progress events - Tauri progress channels suffixed by request session id (`progress_events.rs`, frontend `invokeWithProgressSession`)
  • FFmpeg tooling - undated git snapshot builds no longer assumed year 2024

UI

  • Appearance - View menu: Dark, Light, and Auto (follow OS `prefers-color-scheme`); choice persisted in `localStorage`
  • Light theme - full Slate Canvas palette (soft #F8F9FA canvas, white surfaces, blue accent family shared with dark); timeline lanes, menus, modals, inspector, and media bin tokenized
  • Stickers (light theme) - darker SVG fills for sparkle/thumbs-up/camera/music; drop-shadow on preview overlays
  • Sticker drag - pointer mapping uses export canvas (1:1 with preview); stickers always composited as overlays (draggable even without V1 video); hit-testing on sticker pixels only (selected sticker on top)

[0.8.84] - 2026-07-03

Export

  • Face mask encode progress - `export-progress` events during face-mask FFmpeg prep (`Encoding face mask N of M (P%)`) update overlay bar + phase text

Tracking quality (cutforge-tracker)

  • Analyze loop - full-frame `detect_rgb` on every sampled frame; removed adaptive ONNX skip, ROI cascade, and fast letterbox helpers (~12 s vs ~8 s on Oies-multi-1.mp4, still ~5× faster than pre-RGB JPEG path)

Tracking pack Phase 2 (cutforge-tracker, local dev)

  • RGB prefetch - background ffmpeg decode thread (`CUTFORGE_RGB_PREFETCH=0` to disable)
  • Skin mask - BiSeNet every N frames (`CUTFORGE_SKIN_MASK_EVERY`, default 2) with mask reuse
  • ORT EP features - optional `cuda` / `tensorrt` Cargo features + `CUTFORGE_ORT_EP`
  • Benchmarks - `npm run benchmark:tracker` on reference clips (face / object / click-box)

Tracking stability (P1)

  • Export cancel - no longer cancels unrelated UI face/object analyze (`request_export_cancel` decoupled from face-tracking cancel)
  • Progress poll - `get_face_tracking_progress` reports idle unless a UI tracking session is active
  • Mask engine - changing engine in Face filter clears persisted filter until re-analyze (draft vs export mismatch)
  • Job store - reject overlapping `runFaceTracking` while `faceTrackingJob` is set; progress updates ignore stale clip ids
  • Mask cache - deduplicate parallel prep by cache key; publish via `.mp4.part` + rename with per-key generation lock

Tracking stability (P0)

  • UI session mutex - reject concurrent `run_face_tracking` invokes; export tracker spawns use per-thread wait + export PID registration (parallel-safe)
  • ONNX inference errors - exit `MODEL_ERROR` after 3 consecutive SCRFD/YOLO failures instead of silent empty detections

[0.8.83] - 2026-07-02

Inspector & preview

  • Face filter - single Face tracking card (SMART DETECT, pick, analyze); smart reframe 9:16 checkbox only (no duplicate subject pick)
  • Montage - Object / animal tracking card + smart reframe 9:16 for non-face subjects (YOLO)
  • Preview - smart-reframe zoom applies immediately after tracking ends; detection % badge counter-scaled in 9:16 preview

[0.8.82] - 2026-07-01

Smart reframe & subject tracking

  • GPU object tracking (pack 1.4.0) - `--track-mode object` runs YOLOv8n on DirectML; Choose subject in Face filter tracks animals/objects without CPU template matching
  • Two-step subject pick - crosshair + dashed box in preview; reposition by clicking, then Start tracking (no auto-start on first click)
  • Reset subject - clears smart reframe keyframes, UI pick state, and restores project aspect to 16:9 when no other reframe is active
  • Face filter panel layout - SMART DETECT / pick face at top; Smart reframe 9:16 block (enable, pick subject, headroom, static building) below; blur/warm effect controls last
  • Progress overlay - Object tracking title/messages for subject runs vs Face tracking for face filter
  • Preview fix - clear stale smart-reframe zoom transform after reset so the subject pick box stays the correct size

Tracking pack 1.4.0

  • Embeds `yolov8n.onnx` (~12 MB) alongside SCRFD; index on private channel (`tracking-pack-index.json`)
  • Tracker modes: `face`, `object`, `click-box`, `static-subject`

Smart reframe (Phase B1 - carried from 0.8.80+)

  • Decoupled subject track from face blur - `smartReframe.keyframes` with legacy `faceFilter` fallback
  • Fix first-second crop offset - anchor keyframe at clip-local time, not forced `timeMs: 0`
  • Export cleanup - delete `sr_*.sendcmd` scratch after each segment
  • Preview export parity - sequence preview zooms to tracked 9:16 crop when reframe is active

[0.8.81] - 2026-07-01

Face filter / tracking

  • SMART DETECT - auto-pick the primary face (size + center) without a preview click; manual pick remains available in the Face filter panel
  • Tracking pack 1.3.3 - `cutforge-tracker` supports `--click auto`; embedded index points to the new pack on the private channel
  • Pack manifest repair - if only `cutforge-tracker.exe` or `whisper-cli.exe` was replaced locally, the app refreshes the worker SHA256 in `manifest.json` instead of re-downloading the full pack on every analyze/transcribe
  • Dev helpers - `npm run patch:tracking-tracker`, `install:tracking-pack:local`, `install:stt-pack:local` (both `com.cutforge.studio` and `com.cutforge.studio.private` app data folders)
  • Clearer outdated-pack error when SMART DETECT runs against an old tracker (no more misleading "Video file not found" for clap `--click auto`)

[0.8.80] - 2026-07-01

Smart Reframe

  • Smart Reframe 9:16 - face-centered vertical export (1080×1920): blue crop preview, single continuous MP4 with per-frame `sendcmd` crop (validated); requires face analysis + Montage toggle; export FPS follows resolved timeline rate

Tracker / face filter

  • Face tracking UI - progress overlay stays visible through post-analyze steps (parse, cache, apply); tracker stderr capped at 90% so 91-100% cover Rust finalize; `faceFilter` returned over IPC (no asset fetch on the UI thread); mask warm-up still skipped at analyze time
  • Fix multi-minute freeze after analyze - the tracker's ~10 progress events/s were flooding Tauri's global event system (`emit`/`listen`), queueing ahead of the command response so the `run_face_tracking` `invoke` only resolved minutes after the Rust work finished (observed ~15 s of work -> ~240 s until the UI regained control). Progress now streams over a per-invocation Tauri channel instead, and mid-analysis emits are throttled (~1 per 300 ms, deduped; boundary/finalize percents always sent), so the response returns promptly.

Inspector

  • Clip FPS - inspector shows probed source frame rate for the selected video clip (below Resolution)

[0.8.74] - 2026-06-30

Captions

  • Animated captions polish - ASS export parity for caption box fill, drop shadow, and word-pop scale (`\fscx`/`\fscy` on active syllable); inspector word-by-word editor (text + start/end ms); `updateTextClip` accepts `words` patch with auto-sync on text/duration edits; split/trim partition per-word timings; preview karaoke/word-pop syncs to decoded audio/video clock with `sourceClipId`; STT audio extract uses sample-accurate FFmpeg trim (`-ss` after `-i`) so Whisper word timings match preview playback.

STT

  • WhisperX sidecar (pack v2) - optional STT pack engine `whisperx`: embedded Python + torch + WhisperX with forced word alignment (wav2vec2) for karaoke-grade `words[]` timings; Rust dispatch in `transcribe_clip_sync`, manifest `engine`, build via `npm run build:stt-pack:whisperx`; dev override `CUTFORGE_WHISPERX_PYTHON`.
  • STT pack 2.0.1 - fixes portable Python runtime (`pyvenv.cfg` / embed layout); published on `releases-private` (`stt-2.0.1`, WhisperX, ~579 MiB); replaces broken 2.0.0.

Hygiene

  • Remove unused STT pack placeholder / `whisper_model_path`; `install_stt_pack_from_file` returns `()`; drop `normalizeClipWords` re-export; STT pack gate live test reads `packVersion` from embedded index (fixes 502 after latest-only purge).

[0.8.73] - 2026-06-29

Tracker / face filter

  • SCRFD - letterbox padding uses normalized `0.0` (neutral gray) instead of raw `127.5`
  • ONNX - register DirectML execution provider with CPU fallback (`onnx_session`)
  • Skin mask - decode source segment via single FFmpeg RGB pipe (no per-frame JPEG spawns)
  • Robustness - UltraLight output shape validation; `SparseKeyframe` struct; densify O(n) prepass
  • Dead code - remove unused tracker APIs (`has_landmark_outputs`, `from_bbox`, `MaskEngine::as_str`)

Export / backend

  • Export progress UI - parallel segment exports track completion by timeline index (not finish order); overlay shows completed count, active segment %, and global bar without duplicate phase %
  • Export hardware - AMF/QSV encoder support, NVIDIA multi-GPU index, `get_export_hardware_profile` IPC, hardware summary in export settings
  • Segment merge - collapse text-only boundaries on a single video track (one render job instead of per-subtitle segments)
  • Filter graph - long graphs use `-filter_complex //?/path` on Windows (FFmpeg 62+)
  • Face filter export - fix invalid FFmpeg graph when face blur chains into overlay fades (empty `[vlface]` pad)
  • Export profiler - `ExportProfile` on every `export_timeline` (raw/merged segments, boundary breakdown, phase timings, per-segment stats); optional JSON via `CUTFORGE_EXPORT_PROFILE`
  • Single-pass export (opt-in) - `CUTFORGE_EXPORT_SINGLE_PASS=1` renders eligible timelines in one full `filter_complex` job (`exportMode: singlePassComposite`); segmented pipeline stays default (faster on DJI workflow benchmark)
  • Face mask cache - key v7 includes `export_fps` and export dimensions; warm uses probed source size
  • Manifests - strip UTF-8 BOM before JSON parse (tracking + STT packs)
  • Downloads - reject non-HTTPS zip URLs; fix RFC1918 `172.16-31` check (no `172.2` over-block)
  • Capabilities - remove unused `default` / `desktop-capability` Tauri configs

Preview / frontend

  • Toolbar layout - customizable quick and timeline toolbars (minimal / standard / full presets, per-action checkboxes); default production layout is minimal (export + split + zoom); Edit -> Customize toolbar...; persisted in `localStorage`; E2E builds keep full toolbar via `VITE_E2E`; `EditorPage` falls back to menu when toolbar buttons are hidden
  • Inspector - drag-reorder section blocks (Montage, Pro, Text, ...); order persisted in localStorage
  • STT captions - `caption-clips` pipeline with word-level timings for karaoke / word-pop presets
  • Playback - `useSequencePlayback` uses memoized `TimelineIndex` (parity with RAF loop)
  • Playback engine - `computePlaybackTick` / handoff helpers use indexed timeline resolution (closes R3-1 residual)
  • IPC progress - scoped listeners ignore events after invoke completes

CI / hygiene

  • E2E workflow benchmark - `test:e2e:workflow-dji` (DJI + wife, FX max, phased JSON report); offline `build:benchmark-dji-60s` / `export:benchmark-dji-60s`
  • Remove accidental `$s/` stub directory from the repo
  • Contracts - `mask-geometry-contract` + repo `$` path guard in `test:export-contracts`

[0.8.72] - 2026-06-19

Editor (beta UX)

  • Inspector - subsection headers fully clickable (`InspectorSubsection` on Pro, Montage, Text, Sticker, Face filter, Audio, Image, main inspector)
  • Inspector cards - Pro and Montage panels use bordered `InspectorCard` groups (keyframes, effects, proxy, SRT, STT, silence; speed, transition, transform)
  • Timeline toolbar - compact grouped actions, icon-only undo/redo, abbreviated labels with shortcuts; zoom slider (5%-400%) centered in the toolbar row
  • Timeline tracks - + / on the last overlay, audio, and text track (remove only when empty; at least one track per kind kept)
  • Timeline layout - text tracks (T1, T2, ...) displayed above the video stack (subtitles on top, V3->V1 below)

Tests

  • Component tests for `InspectorSubsection`, `InspectorCard`, Pro/Montage card layout, compact timeline toolbar
  • `inspector-ux-visual` CSS contract + `inspector-visual-contract` test ids
  • E2E `inspector-ux.e2e.cjs` + static spec test

[0.8.71] - 2026-06-25

Editor (STT - Phase 1)

  • Subtitles - local Whisper pack (optional download): transcribe selected audio/video clip -> text clips on T1
  • Inspector (Pro) - "Generate subtitles" button with install/transcribe progress overlays
  • Privacy - speech never leaves the machine (whisper.cpp in `%APPDATA%/stt`)

Editor (styled subtitles - Phase 2)

  • Subtitle presets - viral styles (box, bold, neon, minimal, pop) with live preview and matching FFmpeg `drawtext` burn-in
  • Caption box - semi-opaque background (`box=1`) on export when preset uses `boxColor`
  • Inspector (Pro) - pick preset before STT generation; Apply to T1 restyles all subtitles on the text track

Editor (multi-export batch - Phase 3)

  • Export settings - "Export for all networks" produces 4 MP4s (YouTube, Shorts, TikTok, Instagram) in one folder
  • Progress - batch overlay shows platform index (e.g. 2/4) with combined progress bar
  • Resilience - partial batch failure continues remaining presets and reports summary

Editor (podcast assistant - Phase 4)

  • Wizard - File -> Podcast assistant: 6-step flow (project template -> import -> silence cut -> ducking -> local STT captions -> batch export)
  • Skippable steps - each stage can be skipped; summary before export
  • Orchestration - reuses podcast template, global silence cut, subtitle presets, and multi-export batch from Phases 1-3
  • Wizard STT - inline errors and unpublished-pack hint on the captions step

Editor (STT pack - private channel)

  • STT pack - `stt-1.0.1` on `releases-private` (Whisper 1.9.1 + ggml-small + whisper.cpp runtime DLLs)
  • Download proxy - `GET /api/download-stt-pack?pack=1.0.1` (private gate, same as tracking pack)
  • Pack download - append private gate `?k=` on cutforge.app STT/tracking proxy URLs (fixes HTTP 401)
  • Gate resolution - runtime `PRIVATE_UPDATER_GATE_TOKEN` fallback for dev builds; compile-time gated pack URLs in `build.rs`
  • Gate source - read private updater `?k=` from embedded Tauri config (CUTFORGE-TEST installs)
  • Gate bundle - ship `private-gate.embed` in CUTFORGE-TEST; wizard blocks subtitle generation on public CUTFORGE with a clear PRIVÉ message
  • Catalog - `downloadReady` flag on STT pack catalog
  • Errors - block ungated pack downloads with a clear CUTFORGE PRIVÉ message instead of opaque HTTP 401
  • Wizard - fix duplicate error toast on subtitle generation failure
  • Transcript - clamp whisper segment timestamps to clip duration
  • Smoke - `npm run smoke:stt` (wife-front.mp4 fixture)
  • Subtitle length - max on-screen duration presets (Short 3 s / Medium 5 s / Long 10 s / Auto) in Pro inspector and podcast wizard; reflow after Whisper
  • STT pack - manifest integrity fixes (no self-hash in `files[]`); regression tests for repack and manual manifest edits

Fixes

  • STT sync - subtitle cues follow speech timing: Whisper full JSON (`-ojf`) per-token timestamps; reflow splits on word timings instead of character-length ratio

[0.8.70] - 2026-06-19

_Thank you to ṪëṄäḲïṄṾḞẌ for the beta feedback._

Editor (beta UX)

  • Timeline - ruler and playhead no longer select timecode text while scrubbing (`user-select: none`)
  • Inspector - all numeric sliders (audio, image, text, sticker, montage, chroma, effects, face filter, silence cut) accept typed values beside the range control
  • Montage - clip rotation range extended to ±360° (preview + FFmpeg export)
  • Keyframes - translated property labels, seek on list/timeline click, enriched guidance hint

FFmpeg

  • First launch - setup dialog retries automatic FFmpeg download (BtbN GPL build into `%APPDATA%`) before manual gyan.dev steps; clears broken saved paths before install
  • Auto-install - bump pinned BtbN autobuild URL (upstream purged the previous pin -> HTTP 404 on fresh install)

[0.8.69] - 2026-06-19

Security (code audit W1-W5)

  • Tracking pack - download proxy requires private gate header; install IPC gated in release builds
  • Telemetry - desktop `app-event` posts require gate token (compile-time + site validation)
  • Stickers - export path validation rejects traversal outside allowed directories
  • Tauri - splash window capability split from main IPC surface
  • Ops - timing-safe bearer check for cron dashboard routes

Performance (code audit W6-W9)

  • Undo - history stores serialized project snapshots (lower RAM on large timelines)
  • Media library - no longer subscribes to live playhead ticks
  • Playback - timeline index cache for RAF hot-path clip lookups
  • Face filter - mask cache pre-warmed after tracking analyze completes

Editor (code audit W10-W15)

  • Preview audio - all dedicated audio tracks (A1, A2, ...) play together in preview
  • Waveforms - peaks extracted during media probe on import
  • Preview - export frame keeps correct 16/9 aspect ratio when resizing the preview panel
  • Menus - keyboard navigation in menu bar and dropdown menus
  • Timeline - focusable scroll area; arrow/Home/End scrub; clips selectable from keyboard
  • i18n - English `a11y.inspector` label (no French fallback)

[0.8.68] - 2026-06-19

Added

  • Media library - user-created bins (chutiers) to organize assets; imports go into the active bin
  • Edit menu - customizable keyboard shortcuts (saved per device)

Changed

  • Effects - stronger vignette and warm LUT at the same slider value (preview + export)

[0.8.67] - 2026-06-19

Added

  • Editor - classic menu bar (File, Edit, Timeline, View, Help) with keyboard hints; quick toolbar keeps Save / Import / Export
  • Media import - native Tauri drag-drop on the main window (`dragDropEnabled`) with Explorer file routing to timeline lanes or media library

Fixes

  • Playback - preview embedded video audio sync via decoded-time state (no ref read during render); RAF loop resync tolerance for V1 handoff

[0.8.66] - 2026-06-18

Added

  • Timeline - NLE track order (V1 bottom, overlays above); OS file drag-drop onto lanes; playhead seek by frame (`←/->`), 1s (`Shift`), 5s (`Ctrl`); timeline gutter wheel 1s (Shift 10s)

[0.8.65] - 2026-06-17

Fixes

  • Face analyze - tracking pack 1.3.2 fixes FFmpeg 7+ JPEG frame extraction (`yuvj420p`) for phone/webcam sources

[0.8.64] - 2026-06-17

Fixes

  • Inspector - Text and Stickers panels always visible in the right sidebar (restore default picker UX after lazy-mount regression)

[0.8.63] - 2026-06-17

Security

  • IPC paths - sticker cache limited to canonical app-data directory; media path traversal rejected; relink paths validated on blocking pool
  • Media scope - `register_media_paths` failures reported to Sentry and surfaced in UI (i18n toast)

Editor

  • Autosave recovery - startup dialog to restore or ignore recovered project (no silent auto-restore)
  • Undo history - lighter snapshots via `projectForHistory()` (exclude waveformPeaks, thumbnailPath, proxy)
  • Accessibility - toast dismiss `aria-label`; preview splitter keyboard resize

Fixes

  • Error boundary - unexpected crash message uses i18n `error.unexpected`

[0.8.62] - 2026-06-16

Editor

  • Global silence cut - remove internal silences across unlocked audio/video tracks with ripple; toolbar action and speech-segment helpers on waveform peaks
  • Face filter preview - overlay driven from playhead bus at 60 Hz during playback; backdrop blur skipped while playing for smoother motion
  • Preview text layers - position updates at playhead-bus rate instead of per-frame React state
  • Face filter score badge - throttled to 10 Hz during playback
  • Timeline ruler - adaptive tick density on long projects
  • Inspector - lazy-mount panels by selection type
  • Trim drag - clip geometry via DOM during drag; store commit on mouseup; text clips use CSS transform like media
  • Face mask export - per-clip progress in export overlay (EN/FR/RU)

Fixes

  • Face filter / tracking pack - embedded index points to `cutforge.app/api/download-tracking-pack` (proxies private GitHub release); fixes HTTP 404 when downloading models without GitHub auth
  • ClipProPanel - removed FREE tier gate (full editor on FREE; PRO = watermark removal only)
  • FREE watermark - preview alignment with FFmpeg overlay math
  • License API - fail-closed Paddle idempotency, upsert-before-email, subscription revoke; 503 on DB errors
  • IPC - sticker and media path handlers on `spawn_blocking`

Site

  • Tracking pack API - `GET /api/download-tracking-pack?pack=` streams `tracking-*` assets from `releases-private` via server token
  • Windows download - homepage card and `/api/download-windows` show Coming soon (same as macOS); public GitHub releases repo emptied and set private; default channel `releases-private`; public app releases only from v1.0.0+
  • Built-in updater - disabled in stock `tauri.conf.json` (private gate unchanged on site)

Architecture

  • Codegen - manifest-driven TS/Rust shared types; sync gate in `test:export-contracts`
  • Timeline - `timeline-clip-timing` contract JSON; shared `isTimeInsideClip`; Rust cross-ref in `timeline_resolve`
  • Contracts - `ProjectSnapshot` asserts `textClips` and `beatMarkers`; notify inject for tests
  • Playhead bus - playback drops 60 Hz `displayMs` React state; preview transforms subscribe to bus

Tests & CI

  • E2E face-filter export (analyze fixture, MP4 + corner luma guard); `test:e2e:long` in CI; macOS WDIO smoke job
  • P1 e2e verify script; updater E2E available path; webhook idempotency env tests

[0.8.61] - 2026-06-14

Sentry

  • Handled errors - `captureAppException` normalizes non-Error rejections; wired for export, import, project session, autosave, stickers, and missing media

Editor

  • Feature split - timeline, inspector, and export logic moved into dedicated `src/features/editor` modules

Site

  • Changelog build - repair corrupted user release notes; normalize em dashes, arrows, and narrow spaces in published HTML bodies

[0.8.60] - 2026-06-14

Face filter (Phase 5)

  • Temporal mask smoothing - EMA on skin-engine masks (alpha=0.4) for steadier blur during motion
  • Tracking pack 1.3.1 - rebuilt tracker; catalog zipSha256 aligned with GitHub release; minAppVersion 0.8.59

[0.8.59] - 2026-06-14

Face filter - dual engine (MVP)

  • Engine selector - `standard` (landmark polygon mask) / `skin` (BiSeNet face parsing) on clip `FaceFilter`
  • Skin export - `smartblur` when FFmpeg supports it; `gblur` fallback (~15% higher sigma)
  • Re-analyze gate - engine change invalidates cached masks/keyframes until re-analyze; localized UI prompt (EN/FR/RU)
  • Tracking pack 1.3.0 - adds `face_parsing_resnet18.onnx`; `minAppVersion` 0.8.59; index SHA updated locally (GitHub publish pending)

Tests

  • Dual-engine unit/contract coverage; skin export E2E via `npm run test:face-filter-export-e2e` (FFmpeg + fixtures)

[0.8.58] - 2026-06-13

Face filter (Phase 8)

  • Analyze progress - real `%` from `cutforge-tracker` stderr (`cutforge-progress:`) -> `face-tracking-progress` -> overlay
  • Cancel polish - cancel during tracking-pack download; localized cancel toast; overlay tests
  • Preview pick - `preview-media-pick.ts` maps clicks through clip scale/crop/position (`useFaceFilterPick`)
  • Detection model - default `fetch:tracking-model` = SCRFD 2.5G bn kps (bbox + keypoints)
  • Manual - SmartScreen / Authenticode note for `cutforge-tracker.exe` (EN/FR/RU)

Tests & CI

  • Vitest 80 % branches thresholds on `face-filter.ts` / store actions
  • Knip clean; `cargo fmt` / clippy on tracking modules
  • E2E tracking install - local zip IPC skips catalog SHA pin (fixture rebuild)

[0.8.57] - 2026-06-13

Security

  • Tracking pack local install - SHA-256 pin, path validation, IPC gated to debug/E2E
  • External URL allowlist - hardened against backslash/userinfo bypass
  • FFmpeg directory selection - native dialog only (no arbitrary IPC paths)
  • Production CSP - `base-uri`, `object-src`, `frame-ancestors`, `form-action`; removed `style-src unsafe-inline`
  • Telemetry IPC - event allowlist + field sanitization
  • Error messages - scrub absolute paths from export and `probe_media` errors

Export

  • Face mask encode - stream frames (lower memory), stderr drain, cancel/kill improvements
  • Export watchdog - before mask prep; parallel bounded mask generation
  • Render cache - serialized prune, atomic writes, skip cache on direct-output single pass
  • Cancel PID - race fixes

UI

  • Modal accessibility - focus trap, Escape, `aria-labelledby`
  • Editor store - narrower subscriptions (fewer re-renders)

License

  • Offline revocation grace - reduced to 3 days; clock rollback detection

[0.8.56] - 2026-06-10

Changed

  • Contact email - app, site, legal docs, and license fulfillment now use `info@cutforge.app` (Proton custom domain)

[0.8.55] - 2026-06-12

Fixed

  • Face filter export - installed builds no longer panic with `CARGO_MANIFEST_DIR: NotPresent`; face-blur curve JSON is baked in at compile time

[0.8.54] - 2026-06-12

Fixed

  • Face tracking / export - hide Windows console windows when spawning `cutforge-tracker` and FFmpeg mask encode (`CREATE_NO_WINDOW` via `hidden_command`)
  • Face tracking UI - localized progress messages (preparing / analyzing) in EN, FR, and RU

[0.8.53] - 2026-06-12

Added

  • Face blur curve contract - shared `face-blur-curve.json` for preview CSS and FFmpeg `gblur` sigma (wider 80-100 % range)
  • FREE watermark preview - overlay in sequence preview aligned with export layout
  • GitHub releases cleanup - publish scripts purge older `v*` / `tracking-*` tags (latest-only policy)

Changed

  • Face filter export - landmark polygon mask at encode (parity with preview); mask cache key v5
  • Face filter UI - intensity slider label + hint (EN/FR/RU); preview blur follows export curve
  • Face filter export E2E - fixture fallbacks (`wife-front.mp4`) and on-the-fly mask generation

Fixed

  • Face filter export - scale before `gblur` to avoid OOM on long clips; mask pipe drain / keyframe-only cache

[0.8.52] - 2026-06-12

Added

  • Face tracking module uninstall - Help -> Privacy -> remove the optional tracking pack from `%APPDATA%\com.cutforge.studio\tracking\`
  • Preview clip transform - face-filter pick, mask, and score follow clip scale/crop/position in the sequence preview
  • Confidence score on preview - detection score badge anchored at the nose landmark (red when below 50%)
  • E2E tracking install - local fixture zip (`tracking-pack-e2e.zip`) avoids GitHub download in CI

Changed

  • Tracking pack index - embeds `tracking-1.1.0` (landmarks + Kalman + landmark masks from 0.8.52)
  • User manual - face filter section updated (cancel, uninstall, preview ~ export)
  • Face filter hints - preview copy reflects landmark mask parity with export

[0.8.51] - 2026-06-12

Changed

  • FREE export watermark - updated branding asset (`Cutforge.app` logo PNG, bottom-right overlay)

[0.8.50] - 2026-06-12

Changed

  • Telemetry consent - one-time opt-in banner shown after the first successful export (not at launch); rating prompt unchanged
  • Telemetry decline - banner accept and decline both POST `telemetry_opt_in_changed` (`source: banner`) even when full telemetry is off (`consentOnly` allowlist)

Added

  • Ops dashboard - post-export telemetry KPIs: opt-in % (banner accept rate), banner decline %, prompted machine counts (`telemetryBannerPromptedMachines`, `telemetryBannerDeclinedMachines`, `telemetryBannerDeclineRate`)
  • Face filter unit tests - `src/lib/face-filter.test.ts` (normalize/merge helpers, `TrackingAnalyzeOutput` fixtures)

Docs

  • Analytics - document post-export consent flow and ops KPI definitions in internal analytics docs

[0.8.38] - 2026-06-11

Fixed

  • Face filter export - bind source video to FFmpeg input 0 (was using mask input -> black background + wandering ellipse)
  • Face filter export - fix empty FFmpeg filter segment before `[vpre]` label
  • Face filter analyze - pass app FFmpeg sidecars to tracker; remove unsupported `-hide_banner` in worker
  • Face filter preview - pick coordinates in letterboxed media contain box (resize / fullscreen)
  • Face filter preview - frosted overlay effect (reliable vs `backdrop-filter` on `

Added

  • Face filter panel - inline analyze error message; detection confidence % after tracking
  • Face filter export E2E - `npm run test:face-filter-export-e2e` (`ref-face-front.mp4`, luma corner check)

Changed

  • Export render cache - bump generation `render=v16-face-filter-source-input`

[0.8.37] - 2026-06-11

Fixed

  • Tracking pack download - correct GitHub URL (`/releases/releases/download/...`) for repo `CUTFORGE-VIDEO/releases` (was HTTP 404)
  • Face analyze - UI analyze no longer passes `--mask-out` (compatible with pack 1.0.0 during tracking; mask at export only)
  • Face filter panel - effect kind/strength editable before first analyze; show pack status hint when module missing

[0.8.36] - 2026-06-11

Added

  • Face filters (filtres visage) - inspector panel: pick face in preview, analyze, live bbox overlay, blur/warm sliders
  • Face filter export - precomputed mask video (`--mask-out`) + FFmpeg `alphamerge` with `gblur` / `eq` on export (simple + compositor paths)
  • Face tracking pack 1.0.1 - republished with mask generation support (`tracking-1.0.1` tag)

Changed

  • Tracking pack index - `packVersion` 1.0.1, `minAppVersion` 0.8.36, updated zip SHA256

[0.8.35] - 2026-06-11

Added

  • Face tracking pack 1.0.0 published on GitHub Releases (`tracking-1.0.0` tag) - `cutforge-tracking-1.0.0-win64.zip` (~17 MiB)
  • Build scripts `npm run build:tracking-pack` and `npm run publish:tracking-pack`

Changed

  • Tracking pack index - real download URL and SHA256; `minAppVersion` 0.8.34; manifest lists `DirectML.dll` (ONNX Runtime statically linked in worker)

[0.8.34] - 2026-06-11

Added

  • Face tracking pack - installer module (download, SHA256 verify, extract, manifest check) mirroring FFmpeg install; dev toolbar button + progress overlay
  • Tracking IPC - `check_tracking_pack`, `ensure_tracking_pack_installed`, `tracking-install-progress` events

Fixed

  • Face tracker - decode Ultra-Light RFB-320 bboxes as normalized 0-1 coords (M1 real-video validation)

[0.8.33] - 2026-06-11

Fixed

  • Stickers export - accept `sticker-cache` PNG asset paths at export validation (regression from FABLE v4 `validate_export_media_paths`); regenerate from bundled SVG when cache file is missing

[0.8.32] - 2026-06-11

Security

  • Clip effects & chroma key - validate chroma hex and effect parameters at the IPC boundary (FABLE v4 audit)

Added

  • Cross-lang contracts - clip effects and chroma key FFmpeg filter JSON fixtures verified in TypeScript and Rust

Fixed

  • Keyframes - aligned scale bounds across preview, IPC, and export
  • Install attribution - atomic write for consumed marker file
  • Editor - remove preview splitter listeners on `EditorShell` unmount; export cancel telemetry fallback when session missing

Tests

  • CI - clip-effects contract fixtures typecheck; validate test formatting

[0.8.31] - 2026-06-11

Added

  • Cross-lang contracts - timeline active clips and clip color / FFmpeg filter JSON fixtures verified in TypeScript and Rust (audit C10)
  • Ops dashboard - export timing heatmaps (`cacheHitRateBucket`, `maxSegmentRenderMsBucket`)
  • Project backup - `.cutforge.bak` written atomically before overwrite on save

Security

  • License IPC - 64 KiB cap on `activate_license` body before JSON parse
  • Telemetry - `post_app_telemetry` async (non-blocking reqwest)
  • Config I/O - atomic writes for `launch_guard` and `ffmpeg_config`
  • Stickers - 2 MiB cap before SVG rasterization; watermark temp file uses random name

Changed

  • Timeline - memoized `` per track (fewer re-renders during edit)
  • Export - thread-local `asset_fingerprint` cache before parallel segment render; `commitGesture` avoids double project stringify

Tests

  • CI - `test:timeline-contract` and `test:clip-color-contract` in `test:export-contracts`
  • OSV - Windows-target allowlist for GTK/Linux transitive advisories (`audit:osv`, informational)

[0.8.30] - 2026-06-11

Added

  • Export errors - typed `CUTFORGE_EXPORT:` from Rust with localized UI messages (en/fr/ru)
  • Keyframe contract - shared opacity interpolation JSON verified in TypeScript and Rust

Changed

  • Timeline drag - CSS preview during mousemove; store and undo history commit on mouseup only (no `updatedAt` churn mid-gesture)
  • FFmpeg - per-segment thread budget aligned with rayon parallelism (replaces `-threads 0`)
  • Export keyframes - subdivision interval 500 ms -> 2000 ms (fewer segments on long spans)
  • Waveform - extraction capped at asset duration (max 300 s)

Tests

  • CI - `test:export-contracts` and sticker export e2e in `test:ci`
  • Timeline - drag keeps store unchanged during mousemove; gesture `updatedAt` behavior

[0.8.29] - 2026-06-11

Added

  • Export telemetry - per-segment render duration and cache hit/miss in Rust logs; `app_export_timing` includes cache hit rate and segment render buckets (audit v3 §7.4)

Tests

  • Timeline - component test: drag clip then undo restores original position (audit v3 §7.2)

[0.8.28] - 2026-06-11

Security

  • Asset protocol - narrower `asset://` scope; per-file registration with path canonicalization (no whole-parent directory grant)
  • Export paths - validate media paths before render; guards on proxy and waveform IPC
  • Telemetry - pin `cutforge.app` origin in release builds (debug override only)
  • External links - host allowlist for `open_external_url`
  • FFmpeg download - pinned BtbN build with SHA-256 verification (no rolling `latest` tag)
  • IPC - bound `volume_gain`, `playback_rate`, `opacity`, and keyframe values at project validation

Fixed

  • Export - atomic finalize via `.part` rename; Windows staging uses `out.part.mp4` so FFmpeg accepts the muxer
  • Export - render watchdog during parallel segments; license revocation no longer blocks export start on HTTP
  • Export - reject concurrent `export_timeline` calls; stable cancellation error code
  • Stickers - accept bundled sticker paths at export validation
  • FFmpeg install - reject zip-slip paths when extracting the GPL archive
  • Keyboard - Q/W/S timeline shortcuts ignore Ctrl/Alt combos
  • Undo - `beginGesture` / `commitGesture` for drag and trim (replaces scattered `commitHistory` flag)
  • License tests - skip remote revocation checks when unit-test machine id is set

Changed

  • Export cache - segment cache key built from serialized render inputs (full fingerprint matrix)
  • Playback - consolidated ref bag into `PlaybackRuntime`; named A/V resync thresholds
  • Timeline - O(1) asset and per-track clip lookups during render
  • FFmpeg install - stream GPL zip to a temp file instead of buffering in RAM
  • Export UI - warn when motion interpolation (`minterpolate`) is enabled
  • CI - `cargo fmt --check` and `clippy -D warnings` in `test:ci`

[0.8.27] - 2026-06-10

Fixed

  • Preview stickers - stack stickers above PiP/image overlays (export compositor parity); raise preview z-index so WebView2 video no longer paints over sticker overlays

[0.8.26] - 2026-06-10

Fixed

  • Stickers - resolve bundled SVG paths from exe directory and manifest (export, preview, and rasterization no longer fail with `resources/stickers/*.svg` not found in debug/no-bundle runs)

Added

  • E2E - `export-sticker.e2e.cjs` (export + center luma verification); stage stickers beside E2E binary; `addStickerAt` on E2E bridge

[0.8.25] - 2026-06-10

Fixed

  • Export cache - segment cache key fingerprints text content/style, reversed, playback rate, keyframes, effects, chroma key, and strip-metadata so re-exports stay correct after edits
  • Project I/O - atomic writes for save project, autosave session, and license files (crash-safe)
  • Undo - drag/trim gestures snapshot state at pointer-down; Ctrl+Z restores the pre-gesture position
  • Keyboard - skip global undo/redo while typing in inputs; Ctrl+Shift+Z redo works with uppercase key
  • FFmpeg install - reject zip-slip paths when extracting the GPL archive
  • Export - reject concurrent `export_timeline` calls (shared cancel/PID state)
  • QA - gesture undo skips no-op drags; E2E text export fixtures and peak-luma assertion

[0.8.24] - 2026-06-10

Fixed

  • Export keyframes - subdivide long keyframe spans (500 ms steps) and sample transforms at segment midpoint for smoother motion at export
  • Export text E2E - verify title visibility window via frame luma sampling (not only file size)
  • License revocation - background check on startup; export uses cached status; offline grace reuses last successful result for 7 days
  • Release hardening - debug-only env overrides for license path, machine id, export timeout

Added

  • Tests - `ffmpeg-frame` E2E helper, keyframe subdivision/opacity sampling, `split_transform_montage` compositor unit test, offline grace cache test

Changed

  • Compositor - shared `fps_interpolation_part` / `split_transform_montage` helpers (sticker + overlay chains)

[0.8.23] - 2026-05-30

Fixed

  • Export keyframes - segment boundaries follow clip keyframes; transform sampling uses segment start (not mid-segment) so motion no longer freezes between keyframes
  • Autosave (large projects) - payloads above the 1.5 MB localStorage cap persist in `app_data_dir` via backend session commands

Added

  • E2E - long export with live progress and cancel; export with text offset from clip cuts
  • Tests - Rust coverage for keyframe segment boundaries, hostile `drawtext` escaping, and autosave backend round-trip

[0.8.22] - 2026-06-10

Fixed

  • Export text timing - titles use segment boundaries and `enable=between(t,...)` so preview matches export when text is not aligned on clip cuts
  • UI freeze - heavy Tauri commands (`export`, probe, proxy, waveform, license, project I/O) run on the async blocking pool
  • License signing - canonical JSON key order aligned with Node; golden vector cross-check in CI
  • FFmpeg process I/O - stdout drained concurrently; stderr decoded as UTF-8
  • Autosave - warn when project exceeds local size cap; no longer re-triggered on timeline scrub
  • Updater notes - download dialog shows full changelog entries between installed and target version

Security

  • Validate text clip styles on export/load; hardened `drawtext` escaping; non-recursive asset scope; embedded FREE watermark bytes

[0.8.21] - 2026-06-10

Fixed

  • Rating prompt - shown after first export even without full telemetry opt-in; rating events stored via `consentRating`
  • Ops opt-in KPI - counts `app_launch` and explicit toggles (rate capped at 100%)
  • Site deploy (Vercel Hobby) - ops CSV export merged into `GET /api/ops/dashboard?export=csv`; desktop telemetry routed via `/api/event?target=app` rewrite (12-function limit)

Added

  • Ops test coverage - KPI normalizers, mocked `fetchOpsDashboard`, CI Postgres e2e gate

[0.8.20] - 2026-05-30

Added

  • Analytics P0-P3 - ops KPIs (opt-in %, weekly active machines, activation J+7, feature adoption, launches by country, rating summary); email on `app_export_failed`; weekly ops report cron
  • Desktop telemetry - `app_feature_used` (SRT, silence trim, proxy, ducking), session summary on close, export abandon detection, 1-5 rating prompt after first export

[0.8.19] - 2026-05-30

Changed

  • Toolbar - Help and language menus grouped on the right next to FFmpeg status

[0.8.18] - 2026-05-30

Changed

  • Help menu - log mode (Normal / Debug), privacy, license, and check for updates moved from the toolbar into Aide

[0.8.17] - 2026-05-30

Changed

  • Help menu - single entry point for feedback and logs; removed duplicate beta feedback panel in the inspector and the toolbar Open logs button

[0.8.16] - 2026-05-30

Added

  • Help menu (toolbar) - manual (site), write to team (prefilled mailto + diagnostics), open logs; always available (including post-1.0); `app_feedback_opened` with `source: toolbar_help`

[0.8.15] - 2026-06-08

Added

  • Product analytics (opt-in) - desktop telemetry P0-P2: export lifecycle, project/feature usage, updater, FFmpeg, license, session heartbeats, export timing, beta feedback; enriched `/ops` dashboard (in-app funnel, D1/D7 retention, heatmaps, time-to-first-export)
  • Site - `hero_cta_click` on Windows download CTA

[0.8.14] - 2026-06-07

Fixed

  • License revocation - forced server check on status read; background poll every ~2 min while app is open (second OPS revoke no longer stuck on PRO)
  • OPS dashboard - `ops.js` crash (`escapeHtml` duplicate) caused black login page; token paste/hash login and restore (test) button

Added

  • `scripts/setup-ops-dashboard-token.mjs` - rotate `OPS_DASHBOARD_TOKEN` on Vercel (`--force`)

[0.8.13] - 2026-06-07

Added

  • Remote license revocation (desktop) - `GET cutforge.app/api/license?machine_id=...` on startup and before export; clears local PRO + toast when revoked (fail-open offline, 5 min cache)
  • Site (already deployed) - `license_entitlements` table, unified `/api/license` (check + OPS revoke), Paddle fulfillment records entitlements; license ops runbook (internal)

[0.8.12] - 2026-06-07

Fixed

  • Export audio - embedded video audio follows the top overlay (V2/V3), not V1 underneath (preview parity)
  • Dev launch - Rust export compile fix; `devCsp` for Vite HMR while production CSP stays strict
  • Updater toolbar - status colours in `tauri dev` (green / blue after silent check)
  • Empty timeline - 30 s ruler on first launch, zoom fits lane width

Security

  • Production CSP: removed `unsafe-eval` from `script-src`; Sentry ingest allowed in `connect-src`
  • `test:security` gate: npm + cargo audit (OSV optional)

Added

  • OPS dashboard: `updaterChannel` on `app_launch` (public vs PRIVÉ)
  • Sentry `captureAppException` on export, import, and project I/O failures
  • Tests: export audio stack V1/V2/V3, updater dev, timeline empty layout, CSP `devCsp`

Added (historical - pre-0.8.10 draft notes)

Added

  • Paddle Billing checkout via `GET /api/checkout` (`variant=monthly|yearly|choose`, `machine_id`)
  • Paddle setup - Vercel env vars, sandbox vs live, price IDs
  • App Passer en PRO opens `cutforge.app/api/checkout?variant=...&machine_id=...`
  • Site pricing buttons wired to the same checkout API
  • GitHub Releases publish script + `npm run release:github`

Changed

  • License dialog (PRO): primary Fermer button; Retirer / Importer secondary; machine ID hidden when tier is PRO
  • i18n: `common.close`; license hints reference Paddle checkout via cutforge.app
  • Legal docs: Paddle as Merchant of Record
  • `site/config.js`: `checkoutApi` replaces `checkoutBase`; `releasesUrl` -> `github.com/CUTFORGE/releases`

Notes

  • Vercel: `PADDLE_*`, webhook (`PADDLE_WEBHOOK_SECRET`), license keys, `RESEND_API_KEY` - see Paddle setup notes (internal)
  • Fallback: manual `scripts/sign-license.mjs` if webhook or email fails
  • Installed app builds predating this work still use old checkout URLs - rebuild required

[0.8.10] - 2026-05-30

Fixed

  • Desktop telemetry delivery - POST via Rust (`reqwest`) instead of WebView `fetch`; session launch flag only set after successful send

[0.8.9] - 2026-05-30

Fixed

  • Desktop telemetry - public Windows build CSP blocked `fetch` to `cutforge.app` (`connect-src`); opt-in events were silently dropped

[0.8.8] - 2026-05-30

Fixed

  • Privacy toolbar button (always visible) - telemetry opt-in was unreachable in 0.8.x because the License dialog is hidden before v1.0

[0.8.7] - 2026-05-30

Added

  • Telemetry toggle in License dialog - re-enable or disable anonymous usage stats after declining the first-run banner

[0.8.6] - 2026-05-30

Added

  • Auto-install FFmpeg on first launch (Windows): silent download of BtbN GPL build into `%APPDATA%\com.cutforge.studio\ffmpeg\bin\` with progress overlay; manual setup dialog only if auto-install fails
  • FFmpeg GPL compliance: `licenses/` notices, site `/third-party` (FR/EN/RU), in-app Open-source licenses link, written source offer
  • Timeline bar: Undo/Redo with ←/-> icons, zoom centered in toolbar
  • Global shortcuts: Space play/pause, ←/-> seek ±5 s, ↑/↓ track navigation
  • Ctrl + mouse wheel zoom on timeline scroll area
  • Sticky track label column when scrolling timeline horizontally
  • Site user manual (`/manual`, FR/EN/RU) linked from download section
  • v1.0.0 checklist - must-have vs nice-to-have for v1.0.0 (internal)

Changed

  • Zoom scale: 100 % = 60 s visible, 200 % = 30 s; minimum zoom 5 % (was 25 %); viewport-based `pixelsPerSecond`
  • Undo/Redo moved from main toolbar to timeline bar
  • Site header: brand icons and top-left label removed
  • Neutral brand icon (OG + Tauri app icons regenerated from master artwork)

Fixed

  • Legal page build template: header no longer re-adds brand icon on `build:legal`
  • Fresh Windows installs without admin rights no longer block on FFmpeg setup when network is available

[0.8.5] - 2026-06-04

Added

  • Hardware HEVC decode for export: CUDA -> D3D11VA (Windows) / VAAPI (Linux) -> CPU fallback; `hwdownload` formats fixed for 8-bit (`nv12`) and 10-bit (`p010le`)
  • Export setting Hardware decode (`exportHwDecode`: auto / off) in export dialog + i18n
  • `hasAudio` on import (probe) - video files without an audio track no longer break compositor export
  • Segment export progress (`ffmpeg_progress.rs`, overlay UI) and clearer FFmpeg stderr in logs on failure
  • E2E benchmark-classic-fx export spec (optional, replaces long-video)

Fixed

  • Session restore: register media paths before autosave restore so preview video loads (not black) after app restart
  • Preview seek on load when paused (`onVideoLoaded` applies playhead position)
  • Compositor export for video-only sources: skip embedded-audio duplicate input; optional `-map N:a?`
  • Removed dead compositor/util code; Rust warning cleanup

Changed

  • Export performance - hardware decode chain and troubleshooting (internal)
  • Vitest branch coverage threshold and additional unit tests

[0.8.3] - 2026-05-31

Added

  • Export watermark `CUTFORGE-WATERMARK.png` (FFmpeg overlay, 30 % opacity, bottom-right)
  • Buy PRO button in license dialog -> cutforge.app/#pricing
  • Site pricing section (FREE vs PRO, €1/mo · €10/yr, manual activation note)
  • Tests: `LicenseDialog` component, `license-urls`, E2E license dialog smoke, watermark FFmpeg E2E

Changed

  • Watermark asset: classic logo PNG instead of text `drawtext` / FREE icon
  • License / export i18n aligned with PNG filigrane wording

[0.8.2] - 2026-05-31

Added

  • Phase 1 licensing: Ed25519 signed `license.json`, machine-bound activation, FREE/PRO badge in toolbar
  • FREE export watermark (PNG overlay, bottom-right, enforced in Rust/FFmpeg)
  • License dialog (import `.json`, copy machine ID), `scripts/sign-license.mjs`, `scripts/generate-license-keys.mjs`
  • Splash screen fixed 3.33 s minimum while main window loads in background
  • Branding icons FREE/PRO (`public/branding/`)

Changed

  • Inspector clip tools panel label PRO -> Avancé (commercial PRO is separate `license` namespace)
  • App/window icons aligned on FREE badge; neutral icon archived under `public/branding/archive/`

[0.8.0] - 2026-05-29

Added

  • Landing site (`site/`) for cutforge.app (v0.8.0, i18n, Vercel config)
  • Single-pass project normalization (`normalize-project.ts`)
  • E2E Page Object (`e2e/pages/EditorPage.cjs`) and specs: export-cancel, relink-media, undo-redo (12 specs total)
  • Quality toolchain: `typecheck`, ESLint 9, Prettier, Vitest coverage thresholds in CI
  • `scripts/sync-version.mjs` propagates version to Tauri, splash, site, and E2E

Changed

  • Split `export/compositor.rs` into `compositor/` module (policy, render, filters, audio, inputs, util, tests)
  • Split `useSequencePlayback.ts` into orchestrator + `hooks/playback/` (RAF loop, media sync, preview style)
  • E2E bridge gated (`DEV` or `VITE_E2E`); dedicated `build:e2e` mode
  • Rust: `total_cmp` for f64 ordering (no `partial_cmp().unwrap()`)

Fixed

  • `duplicateTextClip` guard when source clip missing
  • Prettier/format consistency on playback hooks and new E2E specs

[0.6.7] - 2026-05-28

Added

  • Sticker test suite: store placement, timeline compositing, preview overlay layers, FFmpeg rgba export chain

Fixed

  • Sticker default position: first sticker on a track uses layout index 0 (was offset by one)

[0.6.6] - 2026-05-28

Version sync (no functional changes beyond v0.6.5).

[0.6.5] - 2026-05-28

Added

  • Second text track (T2) on the timeline - subtitles/captions on two layers
  • Double-click a text lane to add a title on T1 or T2
  • Drag text clips between T1 and T2 with lane-accurate positioning

Changed

  • New titles use the selected clip's text track, or T1 when none is selected
  • Overlap rules apply per text track (same time allowed on T1 and T2)
  • Older projects gain T2 automatically via `ensureDefaultTracks`

[0.6.4] - 2026-05-28

Changed

  • Inspector panel renamed PRO (was « Phase C - Pro »)
  • Dev launcher script renamed `CUTFORGE.bat` (was `lancer-cutforge.bat`)

Added

  • PRO polish: keyframe list + timeline ticks, chroma sliders, warm LUT effect, SRT file import/export, silence trim preview with thresholds, 720p proxy generation, beat snap (B) / Shift+click delete, GPU encoder in export settings dialog

Fixed

  • Phase C panel crash (invalid GPU i18n keys) - `0bf4fd3`
  • Timeline clips misaligned when dragging between video tracks (V3 -> V2 / V1)

[0.6.3] - 2026-05-28

Added - Phase C (CC parity foundation)

  • Keyframes - opacity, scale, position X/Y on clip timeline (preview + FFmpeg export)
  • Effect stack - blur, sharpen, vignette per clip
  • Chroma key - green-screen colorkey on export
  • Beat markers - timeline markers + snap helper
  • SRT import - subtitles to T1 text track
  • Silence trim - suggestion from waveform peaks
  • Proxy media - optional proxy path on assets (4K workflow)
  • Export GPU preference - auto / software (x264) / NVENC
  • Platform flags - cloud, mobile, marketplace (beta toggles)
  • AI tools - STT / background removal planned (SRT + chroma available now)
  • Inspector Phase C panel, Vitest + Rust tests, E2E `phase-c.e2e.cjs`

[0.6.0] - 2026-05-28

Fixed

  • Export presets - aspect ratio from the settings dialog (e.g. Instagram 1:1) is applied on export instead of a stale project snapshot
  • `normalizeProject` - preserves `exportPresetId`, ducking, and other optional meta fields sent to FFmpeg

Added

  • Tests for Instagram / all social export dimensions (Rust + Vitest)
  • `scripts/test-export-aspects.cjs` - optional ffmpeg/ffprobe smoke test for 16:9, 9:16, 1:1, 4:3

[0.5.0] - 2026-05-28

Added

  • Text track UX - drag, trim handles, snap, overlap avoidance on T1
  • Text clipboard - copy, cut, paste; split at playhead; duplicate
  • Text inspector - position X/Y, timing (ms), fonts, outline, shadow, style presets
  • Preview - drag selected text overlay to reposition
  • Export - FFmpeg drawtext with font file, border, shadow on Windows
  • E2E - WebDriver scenarios for text track (`e2e/specs/text-track.e2e.cjs`)

[0.3.0] - 2026-05-28

Added

  • Phase B: social export presets (YouTube, Shorts, TikTok, Instagram)
  • Project templates (vertical short, YouTube, podcast) on new project
  • Text track T1 - static titles, inspector, timeline blocks, preview overlay, FFmpeg `drawtext` on export
  • Sticker pack - SVG stickers on overlay track (V3)
  • PiP transform - position X/Y, uniform crop, clip opacity (preview + FFmpeg export)
  • Audio ducking - lower music on audio tracks when video dialogue is present
  • Q / W - trim clip start/end to playhead on selected clip
  • Preview crossfade - optional fade at clip end in sequence preview
  • Roadmap - Phase B/C CC parity plan (internal)

[0.2.1] - 2026-05-28

Added

  • Phase A montage: per-clip speed (0.25×-4×), reverse on export, transitions (fade / wipe / slide), scale & rotation
  • Inspector Montage panel, color presets in Image, timeline snap (grid, playhead, clip edges)
  • Playback shortcuts J / K / L (scrub back, play/pause, play)
  • Rust export: `clip_montage` (speed, transform, per-junction xfade kinds)
  • Tests: montage store/UI, snap, playback keyboard, `clip_montage` unit tests (Vitest + `cargo test --lib`)

Changed

  • Preview respects clip playback rate and transform; scaled media clipped inside the preview pane

Fixed

  • Preview overflow when clip scale > 100% (video no longer covers toolbar, timeline, or inspector)

[0.2.0] - 2026-05-28

Added

  • App icon asset `public/cutforge-icon.png` (window title bar, favicon, splash screen)
  • Tauri splash window at launch; closes when the editor shell is ready
  • FFmpeg setup dialog and persistent user paths (`%APPDATA%\com.cutforge.studio`)
  • Export segment disk cache and single-pass export for one merged segment
  • Release scripts: `npm run fetch:ffmpeg`, `npm run release:win`, `sign-windows-release.ps1`
  • Preview/export fidelity banners and localized export phases
  • E2E: FFmpeg staging beside app binary, precheck before WebDriver run

Changed

  • Version bump to 0.2.0 (package, Tauri, Cargo)
  • stricter FFmpeg readiness: requires libx264 + HEVC decode for "ready" status

Fixed

  • TypeScript build (i18n locales, `ToastKind`, unused imports)
  • Crossfade no longer forces per-segment `filter_complex` (faster export)
  • Export cache module compiles in release builds

[0.1.0] - 2025

Initial MVP: timeline editor, FFmpeg export, FR/EN/RU, Windows desktop (Tauri 2).