Selecting a mask group now clears the previous key selection, so Copy/Cut act
on the mask. Pasting masks clears the source mask's vertex selection, so Clear
removes the pasted mask rather than points of the source.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Two queue items that resolve to one output (the same comp added twice, a duplicated item) replaced
each other's file inside one job. Nothing is on disk when the job starts, so no check said anything.
- A default output name (renderQueue.add, render.preRender, comp.saveFrameAs {queue},
file.createProxy) that another item of the queue writes, in any output module or segment, is
numbered like a footage collision: Main.mp4, Main_1.mp4, Main_2.mp4. Sequences are compared by
the frames they write, so two stills of one comp at different times keep their names. Names a
caller gave and names already stored in items are never changed.
- Outputs of one job that still name the same file (explicit names, renderQueue.duplicate, output
modules, segments) refuse the whole render before anything is written, naming both items.
Sequences clash only on frames both write; a later item with Skip Existing Files leaves the
earlier item's frames alone; items refused for footage take no part.
Refusing the whole render, not just the later item: which of two items should keep the file is the
user's to say, and failing only the later one would leave a half-rendered queue found after they
left. renderQueue.duplicate stays a verbatim copy so the clash is reported, not hidden.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
#1339 was written before ui-egui's integration tests became modules of one binary
(`tests/it/main.rs`), so its six test files landed at the top of `tests/`, each its own crate
and link. They move into `tests/it/` as modules; the a11y module's doc names the new path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
edit.copy {"layer": id} copied the selected mask instead of the layer:
the mask branch only checked for `layers`, but `layer` is an explicit
target too.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Edit > Copy with masks selected copied the layer, so Paste duplicated it
instead of adding the mask. Masks now go to their own clipboard and Paste
appends them, with unique names, to the selected unlocked layers.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Since #2204, ci.yml runs `cargo xtask ci` through craft-common-actions' shared gate on every
pull request and push to main; gaps.md still listed "No CI gate on pull requests" as gap 4 and
in the Stability row.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
File ▸ Export ▸ Adobe Premiere Pro Project… pre-rendered every layer Premiere can't show to
ProRes 4444 with the window waiting: minutes on a large comp, which Windows reports as not
responding. The export now runs as a job (Window ▸ Progress, cancellable, with per-layer
progress) when started from its dialog (`background: true`); without it, the command still
waits and returns the same result.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UPDATE_APP gains our accent (#e0368f, our colour in ArtCraft Launcher). The prompt draws it
on the UPDATE chip, the buttons and the What's new underline, and says "by ArtCraft"
(craft-update's default developer); #2646 gave it our icon.
craft-update is pinned to storytold/craft-libs main at 1065653e7 (#434).