Commit Graph
125 Commits
Author SHA1 Message Date
bflatasticandClaude Opus 5.5 05188d036a M4.13: motion blur of collapsed precomps and of animated shape / text content
- Collapsed precomps: the renderer records the precomp layers a nested comp is drawn through;
  motion-blur sub-samples re-evaluate their transforms (when their motion blur is on) and map
  times down through each one, so the precomp layer's own motion blurs its nested layers. The
  containing (outermost) comp's shutter applies to collapsed layers. The GPU compositor gets
  this through Renderer::placement.
- Shape and text layers whose content changes within the shutter (compared by its cache key)
  draw their source at Samples Per Frame times and average them; the cache key covers every
  sub-sample's content.
- Tests: tests_motion_blur_depth (collapsed vs flat, the containing shutter, shape content vs
  the same move by Position); each fails without the change.
- Docs: roadmap, parity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:35:30 +07:00
bflatasticandClaude Opus 5.5 73b2607c9a M5.16: Key Light: keyer eyedroppers pick from the effect input (effect.pickColor); "keylight" search
- effect.pickColor {effect, param|prop, x, y (layer px), average?}: the colour of the effect's
  input at a point, set on the parameter (one undo step). Keying effects' Effect Controls
  eyedroppers use it, since the shown frame is already keyed; Ctrl/Cmd+click averages 5x5.
- effects::aliases / name_matches: Effects & Presets and effect.list (MCP list_effects) find
  Key Light by After Effects' name ("Keylight (1.2)").
- End-to-end test: a green-screen plate with an uneven screen, spill and soft edges keyed via
  effect.apply "Keylight (1.2)", pick, Clip Black / White and a render; UI eyedropper test.
- Docs: parity, agents (green-screen recipe).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:04:10 +07:00
bflatasticandClaude Opus 5.5 9929b5f9ac M5.10: keyframes behave like After Effects: drags never destroy keys, stretched layers, Shift/Ctrl/Ctrl+Alt clicks, locked layers, Hold off
- A drag (keys.move steps sharing a merge key) applies its total offset to the keys as they
  were before it (`Session::key_move`, `prop::shift_keys`): dragging over another key of the
  property no longer deletes it; only the drop position replaces a key, as in After Effects.
- Keys of time-stretched layers move with the pointer: offsets are applied in comp time and
  snapped to comp frames (drags and Alt+Arrow nudges; they moved by the layer-time distance).
- Shift+click toggles a key in or out of the selection (`keys.select {toggle}`); Ctrl+click
  switches Linear ↔ Auto Bezier and Ctrl+Alt+click toggles Hold.
- Keys of locked layers can't be selected (clicks, marquee, Select All Keyframes), so nothing
  edits them.
- Toggle Hold off returns an eased key to Bezier (it always restored Linear).
- Shift-dragging a key snaps to everything the current time snaps to — other keys, layer in /
  out points, layer and comp markers, the work area — and a tooltip shows the key's time and how
  many frames it moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 07:40:42 +07:00
bflatasticandClaude Opus 5.5 2d4a0902ea M12.8: the app no longer freezes every 10 s on Windows: the system memory is read in the background
Every 10 seconds the UI thread re-read the system's memory for the cache budgets, and on
Windows that starts PowerShell (`Get-CimInstance Win32_OperatingSystem`) and waits for it:
about a second, sometimes two, during which the whole app froze. The reading now runs on a
background thread (`sysinfo::MemoryWatch`); `Session::memory_tick` takes the last reading and
starts the next one, never waiting. Console programs started for it no longer open a console
window (`CREATE_NO_WINDOW`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 07:05:17 +07:00
bflatasticandClaude Opus 5.5 a12d4ae1fa M3.9: a browser session restored with unsaved changes stays modified
The web app reopens the last visit's project and, when it had unsaved changes, marked it
modified with `bump()`. Since M3.9 the modified mark follows the saved snapshot, and a bump on
the very project just opened counts as "back at the saved state", so restored changes looked
saved (no `*`, no unsaved-changes prompt). `Session::mark_unsaved` forgets the saved snapshot
instead: the project stays modified until saved, whatever is undone. Regression test included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 06:33:40 +07:00
Brandon Thomas c6488d0cd4 Merge pull request #30 from storytold/pr/never-crash-engine
Never crash: engine without expect() (job polling, commands, menus)
2026-10-04 15:31:40 -04:00
Brandon Thomas a69f417d63 Merge pull request #28 from storytold/pr/never-crash-guard
Never crash: last-resort guard around command execution, and a logging panic hook
2026-10-04 15:28:05 -04:00
Brandon ThomasandClaude Opus 5.5 3d5432c318 Never crash: engine without expect() (job polling, commands, menus)
Removes the engine's production expect() calls: background-job polling (camera, mask, roto,
point and warp tracking, render queue) uses let-else / if-let instead of take().expect("job"),
command helpers bind what they checked instead of re-reading it with expect, the menu bar falls
back to an empty tree (logged) instead of expect()ing that a constant parses, and
autotrace/text animator group lookups no longer expect a just-inserted group. perf.rs, the
benchmark harness behind `effectcraft-cli bench --ops`, opts out with a module-level allow.
Test-only unreachable!() calls become panic!() (clippy.toml allows panics in tests). Denies the
panic lints in the crate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:40:46 -04:00
Brandon ThomasandClaude Opus 5.5 6144ca0804 Never crash: last-resort guard around command execution, and a logging panic hook
Session::execute runs every command (UI, CLI, control channel, MCP, scripts; file import,
export and save are commands too) through guard::guarded, which catch_unwinds a panic that
escapes the command and returns EngineError::Other("command `x` failed with an internal error
(...); it was stopped and your project is still open"). Edits work on a copy of the project, so
a command that panics mid-edit leaves the project untouched. The desktop app also installs a
panic hook that logs every panic through the app logger (then runs the default hook).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:27:33 -04:00
bflatasticandClaude Opus 5.5 e0ed28f55d M3.9: closing a modified project asks to save it first; the modified mark follows undo
- Quit and the window's close button, File ▸ New Project, Open Project, Open Recent, Close
  Project, the demo project and a Home template show Save / Don't Save / Cancel when the
  project has unsaved changes (Save asks for a path when untitled; cancelling that keeps the
  project open). File ▸ Revert asks to discard. Before, all of them dropped unsaved work
  without asking.
- The window title shows the project's path and `*` while it is modified.
- The modified mark follows undo: the session keeps the snapshot it last opened or saved
  (`Session::saved_project`), so undoing, jumping in the History panel or rolling back a batch
  to the saved state clears it.
- An edit that changes nothing (a value set to what it already is) records no undo step and
  doesn't mark the project modified (`Project::same_content`, comparing untouched comps by
  pointer).
- Agents' `engine.execute` / MCP calls are never asked; `ui.menu.invoke` shows the prompt like a
  click (automation ids `dialog.unsaved.save` / `dontSave` / `revert` / `cancel`), and the
  control channel's `app.quit {force: true}` skips it.
- Docs: architecture, agents, control protocol, parity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:02:14 +07:00
Brandon ThomasandClaude Opus 5.5 f3715aac32 M13.30: web depth and polish
- GPU in browser job workers: each job worker opens its own WebGPU device
  (deferred readbacks); the Render Queue export and the analyses' frame loops
  are futures (render::passes, offload::run_request_async) whose frames
  render in passes, awaiting the device between them. GPU particles and
  Advanced 3D read back under keys too. workers.jobs reports passes and
  readbacks; the smoke test measures them.
- Layer buffers in the browser's OPFS disk cache: frame workers back their
  layer caches with a PrefetchStore; the page plans what to fetch before a
  request from recent misses (LayerPrefetch over the shared DiskIndex).
- Templates embed footage (default on, size-capped with a warning) and
  creating from a template extracts it next to the new project / into
  browser storage.
- ICC LUT profiles (lut8/lut16/lutAtoB/lutBtoA, from the public ICC spec) in
  Simulate Output > My Custom RGB, baked into a 3D LUT for the viewer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 02:57:17 -04:00
Brandon Thomas 05b614990b Merge branch 'main' into worktree-agent-a9fea98fe9839069d 2026-10-04 00:25:43 -04:00
Brandon ThomasandClaude Opus 5.5 955422819c M13.26: Premiere Pro interop commands (file.importTimeline, file.exportTimeline with ProRes 4444 pre-renders), File menu entries, export dialog, docs and pixel round-trip tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 00:25:43 -04:00
Brandon Thomas 7d9f369a5e Merge branch 'main' into worktree-agent-acd022ffe72ec3783
# Conflicts:
#	docs/parity.md
2026-10-03 18:35:29 -04:00
Brandon ThomasandClaude Opus 5.5 1b726349ab M13.24: web app depth (WEB-1) — GPU effects in frame workers, OPFS disk cache, storage manager
- GPU in the browser: each frame worker opens its own WebGPU device (Gpu::request_deferred) and
  renders the GPU compositor and GPU effects with deferred readbacks (effectcraft-gpu deferred):
  readbacks keyed by content start with map_async and miss, the pass returns placeholders, the
  layer cache's gate drops inserts, and FrameServer::resume renders again once the device
  delivered. Backend Auto times whole frames per comp in the workers. Frames with effects go to
  GPU workers instead of the page. CPU fallback without WebGPU in workers (?nogpuworkers).
- Fix: a WGSL constant (3.40282347e38) that Chrome rejects invalidated every GPU kernel in Chrome
  (the page's compositor too); a test checks every float literal fits f32.
- Disk cache in the Origin Private File System: workers write sealed frame entries with sync
  access handles (temp file + move), the page keeps the DiskIndex (LRU under the settings' limit,
  at most half the quota) and reads hits instead of rendering; survives reloads; blue cache bar.
- Storage manager: Settings ▸ Disk ▸ Browser Storage (usage/quota, persistent storage, Clear
  buttons, automation ids) and storage.info / storage.persist / storage.clear (StorageHost).
- Docs: web.md (GPU workers, deferred passes, disk cache, storage manager, threading design:
  one engine instance per worker), architecture, preferences, parity (WEB-1), roadmap.
- Tests: deferred passes vs CPU on a real device, placeholder gating, frame server passes and
  Auto, GPU worker routing + disk cache across a reload, storage commands and widgets, store
  usage by kind; smoke test: GPU effect frames in workers with pixel parity, disk hits after a
  reload, storage manager.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 18:35:03 -04:00
Brandon ThomasandClaude Opus 5.5 b760f1d23a M13.25: project templates engine — eight original built-in templates with Essential Graphics controls and rendered thumbnails; user .ectemplate templates in the config Templates folder; templates.list/thumbnail/create/saveAs/delete
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:37:18 -04:00
Brandon Thomas 91bd8ca7c8 Merge main into M13.14
# Conflicts:
#	crates/engine/src/lib.rs
#	docs/agents.md
2026-10-03 13:13:50 -04:00
Brandon ThomasandClaude Opus 5.5 77ab92fb7d M13.15: qa essential graphics template via CLI script
Fill's ADBE Fill-0002 is Color (documented numbering); essential.* controls by name with
a listing error; an explicit comp param satisfies a command's active-comp enablement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:30:11 -04:00
Brandon ThomasandClaude Opus 5.5 fecf054e5f M13.15: qa scenarios 1-4 (kinetic type, shape logo, compositing, tracking) and fixes
engine.batch + MCP batch tool; layer.newText/newShape name; prop.get evaluated
expression value; keys.select by path with errors; @uid paths; plain-JSON gradients;
addShapeItem/effect.apply return paths; unknown layers error; conform rescales
footage duration; render log name for [###]; render_frame transparent; clearer
mask errors; truncated groups in flat get_layer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 12:09:41 -04:00
Brandon Thomas 9904525591 Merge main into M13.14 2026-10-03 11:50:14 -04:00
Brandon ThomasandClaude Opus 5.5 8a4a2bfc52 M13.14: lazy project open, non-blocking UI with large projects, bench --ops
- footage.check: background footage check after File > Open (Progress panel), not an undo step
- timeline: track-matte / parent menus built only while open (was O(n^2) per frame);
  expression-row lookup per layer; panels hold Arc<Comp> snapshots instead of deep clones
- Project panel: virtualised vertical scrolling, selection reveal, thumbnails rendered off
  the UI thread
- effectcraft-cli bench --ops (engine::perf + ui-egui::bench)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 11:49:55 -04:00
Brandon ThomasandClaude Opus 5.5 41f672eef5 M13.14: large-project generator, background compact auto-save
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:59:23 -04:00
Brandon ThomasandClaude Opus 5.5 454df5d143 Merge main into M13.4 (codec completion)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:24:05 -04:00
Brandon ThomasandClaude Opus 5.5 5c54ccd8d0 Merge main into M13.10
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:59:35 -04:00
Brandon ThomasandClaude Opus 5.5 5bb6768766 M13.10: web frame workers fed by project diffs, offloaded Roto Brush propagation, non-blocking wait jobs, browser Media Browser
Viewer frames render in long-lived Web Workers holding a project replica
(engine::remote: structural JSON diff/patch, Mirror, FrameServer); the
frame cache hands jobs to a RemoteFrames renderer (UI-thread fallback).
Roto Brush propagation runs in a job worker and streams segmentations
back (FrameSeg binary form), relayed to frame workers. Control-channel
wait:true commands whose job is offloaded reply when it ends. The Media
Browser browses a pluggable Browser: the file system on the desktop;
browser storage and File System Access folders on the web.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:36:00 -04:00
Brandon Thomas 417ddd1d89 Merge branch 'worktree-agent-ac0d75bd55dd48956'
# Conflicts:
#	docs/parity.md
2026-10-03 08:09:29 -04:00
Brandon ThomasandClaude Opus 5.5 0698b23cd7 M13.7: Save Frame As Photoshop Layers / ProEXR, Watch Folder, Vanishing Point (disabled), Create Nulls From Paths, VR Comp Editor, Help tutorials
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 07:55:04 -04:00
Brandon ThomasandClaude Opus 5.5 553a51316c M13.8: Preview panel shortcuts and Align panel commands
Preview panel: five shortcuts (Spacebar, Shift+Spacebar, Numpad 0, Shift+Numpad 0,
Alt+Numpad 0) each with saved options (include video/audio/overlays/layer controls, loop,
cache before playback, range incl. play around current time, play from, frame rate, skip,
resolution, full screen, play cached frames, move time to preview time), persisted in
prefs; playback.settings.get/set; the playback loop follows the preview plan.

Align panel: layer.align {edge, to} and layer.distribute {mode} engine commands (bounds
through transform and parents, one undo step); Align Layers to dropdown and Distribute row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 07:38:46 -04:00
Brandon ThomasandClaude Opus 5.5 a30cf38180 Merge main into M13.4 (codec completion): HEVC/AV1 on the export pipeline (Cx), one key-frame interval for all movie codecs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 07:29:32 -04:00
Brandon Thomas 1772250fc4 Merge main into M13.7 2026-10-03 07:23:25 -04:00
Brandon ThomasandClaude Opus 5.5 558de71720 M13.7: Essential Graphics scripting hooks, Font and uniform Scale controls, Open in Essential Graphics
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 07:23:22 -04:00
Brandon ThomasandClaude Opus 5.5 9d23944c2b Merge main into M13.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:37:39 -04:00
Brandon ThomasandClaude Opus 5.5 1b823eb852 M13.5: Home ▸ Learn tab with interactive tutorials (learn.list/start/step/stop/state, coach card, target highlight)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:25:45 -04:00
Brandon Thomas 978e8d7f94 Merge branch 'worktree-agent-a12b9f39d35fe5457'
# Conflicts:
#	docs/parity.md
2026-10-03 05:25:26 -04:00
Brandon ThomasandClaude Opus 5.5 ad0f821fa8 Merge main into M10.2 (render queue + VP9 inter)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:09:51 -04:00
Brandon Thomas 6102d1523e Merge branch 'worktree-agent-a5320bec04bab3dac'
# Conflicts:
#	docs/parity.md
2026-10-03 05:09:10 -04:00
Brandon Thomas 310a9fce94 Merge branch 'worktree-agent-a5b25d366383f4675'
# Conflicts:
#	docs/parity.md
2026-10-03 05:09:01 -04:00
Brandon ThomasandClaude Opus 5.5 280f7d509c M13.4: HEVC / AV1 output modules (MP4 hvc1/av01, WebM AV1), codec + Opus options in engine, UI, CLI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 05:01:43 -04:00
Brandon ThomasandClaude Opus 5.5 1242a775fe M10.2: Render Queue completeness (render settings, output module, templates, logs, overflow, notify)
Render Settings: field render with 3:2 pulldown phases, effects/solo/guide
layer/color depth/frame blending/motion blur overrides, custom time sampling
(duration), storage overflow through a quota hook. Output Module: crop
(edges or region of interest), resize (presets, lock aspect, quality),
straight/premultiplied/alpha-only channels, post-render actions, include
project link, audio channels and PCM formats, WebM bitrate and key frame
interval. Render Settings / Output Module templates with built-ins and
defaults per slot (Edit > Templates dialogs), render logs next to the
output, Notify on completion. All through renderQueue.* commands and
persisted in the project.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:55:31 -04:00
Brandon ThomasandClaude Opus 5.5 a1a195fd51 Merge main into M13.1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:51:32 -04:00
Brandon ThomasandClaude Opus 5.5 104c154194 Merge main into M13.3 (tracking completion)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:36:19 -04:00
Brandon ThomasandClaude Opus 5.5 d209fa001f M13.3: face tracking methods, Face Track Points / Measurements, camera lens distortion, docs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:36:12 -04:00
Brandon ThomasandClaude Opus 5.5 47d2da04de Merge main into M13.1 (scripts in File ▸ Scripts / Window via @dynamic menu nodes)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:27:09 -04:00
Brandon Thomas 7ac5317ce9 Merge main into M13.2 2026-10-03 04:19:01 -04:00
Brandon ThomasandClaude Opus 5.5 89c9b1b6ee M13.1: branching history, puppet pin recording, WebAssembly plug-in API, ScriptUI model and hosts, File ▸ Scripts, deterministic render test
- engine: History keeps undone lines as branches; edit.history.list/goto; History panel tree; MCP history tool
- puppet.recordPin / puppet.recordOptions; viewer Cmd-drag records; Record Options form
- effects::plugin (EffectPlugin trait, register_plugin, API v1); effectcraft-plugin (wasmi, sandboxed, fuel-limited); effect.plugins.load/list
- ScriptUI: engine scriptui model + layout + scriptui.* commands; script crate scriptui.js and script-host threads (dialogs block show())
- File ▸ Scripts: install script / ScriptUI panel, sample scripts, window.scriptPanel
- host test: bit-identical renders across runs and thread counts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 04:07:20 -04:00
Brandon ThomasandClaude Opus 5.5 30a92ba82f M13.2: OpenType features (stylistic sets, figures, fractions, ordinals, dlig, true small caps / superscripts with faux fallback), Character panel OpenType popup, text.fontFeatures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:53:05 -04:00
Brandon ThomasandClaude Opus 5.5 0ed7bf69af Merge main into M13.6 panels and content tools (Footage window label on the real panel; no stubs left)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:43:46 -04:00
Brandon ThomasandClaude Opus 5.5 fa27d000ea Merge main into M14.5 (settings and menus)
Display Color Space setting joins the live list; View3D::Default maps to view.3d.default for
the Assign Shortcut submenu; stub tests use the stubs that remain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:29:39 -04:00
Brandon ThomasandClaude Opus 5.5 a5be68499e Merge main into M13.6 panels and content tools
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:23:13 -04:00
Brandon ThomasandClaude Opus 5.5 b29d833b2d M13.6: Lumetri Scopes, Footage, Media Browser, Metadata, Progress and Content-Aware Fill panels; Content-Aware Fill, Scene Edit Detection, Auto-trace, Align Video to Data
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 03:12:36 -04:00