| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
All green: cargo test --workspace (~300 tests, 0 failures).
- timeline (45): placement, resize/ripple, split, snap, retime,
audio separation, scene helpers
- animation (73): bezier solver, channel sampling, keyframe ops,
split/clamp/clone, param definitions
- commands (9): Command trait, BatchCommand, history, 19 concrete
commands, freeze-frame port 1:1
- audio (22): audible collection, range mixing, mastering limiter,
rms/peak buckets
- text (19): cosmic-text layout/measure/raster, backgrounds,
decorations
- graphics (52): full CSS gradient parser, tiny-skia raster,
4 shape definitions
- effect-defs (16): blur definition, registry, pass resolution
- mask-defs (19): all 9 mask renderers via tiny-skia
- renderer (6): node model + scene builder port
- desktop: GPUI projects screen wired to ProjectStore
- scene: factory (web defaults: v32, Main Track, 1920x1080, 30fps)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- scene crate: full project/scene/element model, serde round-trip
proven against the web SerializedProject shape
- transfer crate: .ocp zip container, cross-compat with web fflate
archives proven in both directions
- storage crate: filesystem project store replacing IndexedDB,
.ocp import/export
- media crate: ffmpeg-next 8 decoder (frames, audio, thumbnails,
waveform summaries)
- playback crate: wall-clock anchored, frame-rounded playback clock
- gpu crate: native texture readback; compositor renders headless
offscreen on Vulkan (spike test)
- flake devshell: rust toolchain, GPUI native deps, ffmpeg dev,
bindgen clang args; GPUI hello-world builds
- port plan in notes/gpui-port.md
|
| |
|
|
|
|
|
|
| |
Yesterday's verified web session (gates green: 316 tests, tsc, build):
- ripple-extend pushes right-hand chain on static-element resize
- per-position video filmstrip thumbnails with zoom-adaptive density
- fps-aware export bitrate, 2s keyframes, even-dim export canvas
- freeze frame uses fixed 3s duration, prompt removed
|
| |
|
|
|
|
| |
AGENTS.md gains the versions/voiceover/transfer domains and the features
flag module; roadmap marks slices 1-6 done and notes deletion of
flagged-off code as the next strip step.
|
| |
|
|
|
|
|
|
|
| |
Shared wiring for the six roadmap slices in one commit: action ids and
handlers for create-checkpoint, toggle-versions-panel,
export-project-archive, and voice-over; the freeze-frame handler awaits
the duration prompt before capture; editor header gains the versions
popover and export menu item (and loses the feedback popover and
Discord item, part of the branding strip).
|
| |
|
|
|
|
|
|
|
| |
MediaRecorder mic capture (defensive mimeType picking, permission/no-mic
toasts) with elapsed display in the timeline toolbar. Stop produces an
audio asset and inserts it at the playhead on an audio track as ONE
BatchCommand undo step, freeze-frame precedent. voice-over action
registered, no default keybinding. 20 tests; smoke-tested in Chromium
with a fake mic end to end.
|
| |
|
|
|
|
|
|
|
|
|
| |
fflate zip container: project.json (serialized project incl. schema
version) + media files with a manifest. Export gathers all project
media (missing blobs warn, never abort) after save-flush; import
validates everything before any write, migrates older archives through
the storage migration registry, remaps media ids, and creates a new
project with rollback on failure. Entry points: projects page
import/export, editor header menu, export-project-archive action.
29 tests incl. full round-trip.
|
| |
|
|
|
|
|
|
|
|
|
| |
Linear per-project history per notes/project-versioning.md: named
checkpoints (thumbnail via renderer.captureFrame) plus auto-checkpoints
on save (60s throttle, ring of 20, named never rotate). Restore writes a
safety checkpoint first, then swaps the document outside undo/redo.
Media assets referenced by any version are pinned against deletion.
Migration v31-v32 stamps the schema; the version store lives in its own
IDB database with an in-memory fallback for tests. Versions popover in
the editor header for jump/rename/delete. 12 new tests.
|
| |
|
|
|
|
| |
/ redirects to /projects; marketing landing components, the feedback
popover + API route, and all Discord links removed (editor header,
footer, onboarding copy).
|
| |
|
|
|
|
|
| |
Freeze frame now asks for the duration (decimal seconds, 0 < d <= 600)
before capture, via a promise-based zustand store mounted as an
editor-global dialog. Last-used duration persists and prefills. Cancel
aborts before capture with no commands.
|
| |
|
|
|
|
|
| |
FEATURES in src/features.ts (all false) hides the assets-panel tabs and
views, the clip effects properties tab, and the timeline effects badge.
Existing project data still renders and stays editable (standalone effect
tab, sticker config, renderer nodes untouched).
|
| |
|
|
|
|
| |
Linear history with named checkpoints plus rotating auto-checkpoints,
content-addressed media dedup, jump-only v1. Owner decisions recorded;
branches and diff view explicitly out of scope.
|
| | |
|
| |
|
|
|
|
|
|
| |
The test step was a no-op stub. CI now installs at the repo root (where
bun.lock and bunfig.toml live), builds via the root script, typechecks,
and runs bun test. Adds 'just verify' as the same local gate (tests +
typecheck + build). Full lint stays out of the gate until the planned
feature stripping lands.
|
| |
|
|
|
|
|
|
|
| |
Mask insertion test expected zero handles; the de Casteljau split
correctly produces colinear shape-preserving ones. Box scale snap now
reports both symmetric snap lines. Fractional ticks and unbranded
MediaTime expectations fixed. Text-measurement test skipped (no canvas
2d in bun). CI-hostile it.only reference removed. Suite: 221 pass, 1
skip, 0 fail.
|
| |
|
|
|
|
| |
IndexedDBAdapter and DefinitionRegistry.register switched to object
params; these call sites still used positional args and were silent
no-ops at runtime (sticker providers never actually registered).
|
| |
|
|
|
|
|
|
| |
persistence.ts imported isActionWithOptionalArgs and isShortcutKey,
neither of which existed at runtime — loading persisted custom
keybindings would crash. Adds actions/guards.ts (excluding required-args
actions per TActionArgsMap) and isShortcutKey in keybinding.ts; the nine
previously dead persistence tests now pass.
|
| |
|
|
|
|
|
| |
Captures the freeze-duration-prompt task, GPU/CPU rendering state,
prioritized roadmap (strip landing/branding, disable unfinished domains,
self-contained project files, voice-over, versioning, desktop binary),
and known pre-existing breakage.
|
| |
|
|
|
|
| |
Recipes wrap the documented bun/turbo/cargo/docker commands; 'just test
<path>' passes through to bun test, 'just dev' ensures .env.local exists.
just is added to the nix devshell so it is available after nix develop.
|
| | |
|
| |
|
|
|
|
|
| |
The image branch rendered <Image src={item.url ?? ""}>, crashing the
assets panel for any image asset lacking url. It now falls back to
thumbnailUrl and then to the existing MediaTypePlaceholder, mirroring the
video branch's fallback.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
The handler fired four separate commands (asset add, split, move, insert),
producing four undo steps. It now builds one BatchCommand and executes it
once. The new ShiftSplitRemainderCommand resolves the split's right-side
elements lazily at execute() so it can be composed after the split in the
batch, and rebuilds the inner move on redo since a re-executed split
generates fresh element ids.
|
| |
|
|
|
|
|
|
| |
The published opencut-wasm package is wasm-pack bundler-target glue whose
.wasm ESM import bun's test runner does not instantiate, so any test
importing @/wasm failed at module evaluation. Register a faithful pure-TS
stand-in (mirrors rust/crates/time semantics) via a bunfig [test] preload
before any test module evaluates.
|
| |
|
|
|
|
|
|
|
|
|
| |
Enable the timeline toolbar freeze-frame button: capture the composited
canvas as PNG, add it as an image media asset, split the video element
at the playhead, shift the right part by the freeze duration, and insert
a 3-second image element in the gap. Adds RendererManager.captureFrame(),
reused by createSnapshot().
Also adds the Nix devshell (flake.nix/flake.lock: bun + nodejs) and
AGENTS.md repository guidelines.
|
| | |
|
| | |
|
| | |
|
| | |
|
| |\ |
|
| | | |
|
| | | |
|
| | | |
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The freeform mask was assembled on every getMaskDefinition("freeform") call,
re-spreading params and injecting a wrong SquareIcon placeholder, with a type
cast to suppress the structural mismatch. Root cause: MasksRegistry was keyed
on BuiltinMaskType, so freeform had no entry.
- Re-key MasksRegistry from BuiltinMaskType to MaskType
- Register freeform alongside builtins in registerDefaultMasks, with
PenToolAddIcon as its menu icon
- getMaskDefinition and getMaskDefinitionsForMenu become plain registry
lookups with no branching, no manual spreading, no cast
- Rename RegisteredBuiltinMaskDefinition to RegisteredMaskDefinition and
tighten computeParamUpdate return type to Partial<BaseMaskParams>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The { kind: "tangent" } MaskHandleId variant was never constructed — neither
getFreeformDisplayHandles nor any other code ever produced a tangent handle
object. The in/out control-arm branches in computeFreeformParamUpdate, the
tangent case in maskHandleIdKey, and the CUSTOM_MASK_TANGENT_SIZE rendering
path in mask-handles.tsx were all unreachable. Removed all four dead paths
and removed "tangent" from MaskHandleKind.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- Remove dead ternary in getPreferredEdges (always returned undefined; the
all-false object was never reached by Object.values().some(Boolean))
- Document why drawWithFeather descriptors zero the feather field in the
compositor (analytical renderer handles softness itself; zeroing prevents
a second JFA feather pass)
- Remove legacyType from V30→V31 migration (not consumed anywhere; a
down-migration can map type:"freeform" back to "custom" directly)
- Add V30→V31 test coverage: skip-guard branches, freeform passthrough,
elements without a masks array
- Add snap tests for vertical-edge (bottom) and uniform-scale handle paths
Co-authored-by: Cursor <cursoragent@cursor.com>
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| | |
| |
| |
| | |
Made-with: Cursor
|
| |\| |
|