Straighten Layer was offered wherever a ruler line existed, so its button was
live for every target and the command turned whatever it was pointed at: it
rotated and cropped the canvas on the Background, turned several selected
layers or a group, failed on a locked layer with `layer "..." is locked`, and
rotated pixels nobody could see on a hidden layer. The reference application
(#12033) keeps the button off for the Background, a multi-layer selection, a
group, Lock All and Lock Position, and answers a hidden target layer with its
alert and no change at all. The command's own `enabled` check now says the
first set, so the options bar, the CLI, the control channel and an action step
all agree about what is offered; the hidden layer stays enabled and is refused
by the command, before it reads anything for the edit, so a refused click
leaves the document, its History and the ruler line exactly as they were. The
states the ticket marks *not measured* keep today's behaviour.
The journal made `layer` portable for layer.layerMask.moveTo but kept `to` as
the document's layer id. Replayed on another document, that id names some
other layer or none: the mask silently went to an unrelated layer or the step
failed. Before the fix, recorded_mask_drop_replays_on_another_document
recorded `"to": 8` and replay moved the mask onto "Extra" instead of "Shadow".
Recording now keeps `to` as the layer's name (from the document before the
step, since a drop on the Background renames it "Layer 0"), plus
`toOccurrence` when several layers share the name. move_mask resolves a name
(requiring `toOccurrence` when it is ambiguous), and explicit calls still take
a numeric id. This matches how layer.moveTo records its drop target
(`target` + `targetOccurrence`).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Batch and Create Droplet dialogs get a Set dropdown (each set once, each
action name once) and send the selected action's set, so a loaded library
with one name in two sets runs the chosen set's action; createDroplet now
honours `set` with a named action (dialogs.rs:512 finding).
- Droplet capture rewrites an ordinary call to the action's name only while
that name is unique in the exported list; otherwise it keeps the exported
index, so a call to the second of two same-named actions still reaches it
(outside-diff finding on actions_cmds.rs:337).
- Save and Close refuses a source whose bytes Batch would write in another
format (a Cineon source is encoded as PSD), instead of writing PSD bytes
under the source's .cin name (batch_run.rs:918 finding).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A direct Batch in a script or a CLI command list stops it when it is cancelled,
cannot write its error log, or ran out of script steps; per-file errors alone
still continue (CodeRabbit, outside-diff findings on automate_cmds.rs and
photocraft-cli document.rs).
- Recorded Save steps count against the script's step budget, and a Batch whose
files failed with the budget spent carries scriptLimitError, so Browse reports
the failure instead of ok: true (yoriswind).
- actions.rename rewrites a named Batch, nested Play or Conditional call only if
it resolved to the renamed action before the rename; a Batch with explicit
steps is left alone (yoriswind: two same-named actions in different sets).
- Shape Blur's run admission counts each worker's f64 prefix sums and, for a
custom shape, the kernel mask kept for the run plus its worst-case coverage
runs (yoriswind).
- Every sampler that takes the primary release (Color Picker, Curves/Levels and
Properties eyedroppers, Curves Cmd-click, Color Range) ends a transform handle
drag and a Move drag begun before it, not only the Color Picker (#11210 review).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Engine: droplet dependency capture skips disabled steps; a nested Batch
that was cancelled or could not write its error log fails the caller;
runDroplet forwards overrideOpen; actions.rename follows named Batch
steps; Batch steps inside a script count against MAX_SCRIPT_STEPS;
output claims compare destination identity; Save and Close never
replaces a read-only source. ATN: Md must be a BlnM enumeration,
adjustment-layer names must round-trip, Calculations exports a missing
blending as Multiply, Apply Image refuses unnamed-layer transparency.
Filters: Shape Blur records its resolved geometry, reserves its kernel
memory first, and reports a preparation failure as an error, not a
cancel; Crop keeps an artboard preset when the size is unchanged and
fits the board on a turned crop.
Codecs/cms/algo: zero-axis FITS image HDUs are empty; a GIF walk that
breaks off before the trailer fails closed; two-value .3dl shaper rows
are applied; fragmented custom kernels are refused and their work polls
cancellation.
UI: Conditional branches play through panel playback; paused actions
refuse to resume after being replaced; Playback Options OK validates
its fields; transform double-click ignores a hidden pivot; path boxes
snap to a stationary selection; modal blocking uses the effective tool;
a picker-consumed release clears snap lines and ends a Move drag; the
Crop preset control shows Selection and checks only it; Crop box undo
restores frame_from_selection; Bosnian fill labels.
Tests: timing asserts moved to an ignored test, plus the review's
coverage nitpicks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Accelerated / Step by Step / Pause For (whole seconds 1..60) and Create a
single history state are saved in prefs.actions and set together through
actions.setPlayback, validated before any value is stored. Headless
actions.play keeps running the whole action at once.
Co-Authored-By: Zer0C00L01 <12090083+Zer0C00L01@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#10788 adds a preserve_alpha argument to tga_image and makes
flat_transparency_and_channels fallible. The renderer export path the
batch already holds still called the old signatures; it now passes
opts.preserve_alpha and propagates the error like the CPU path.
Both PRs carried the same three tests (scoped source slots, droplet
Batch namespaces, droplet scoped variant limit); git kept both copies.
Keep one of each.
Co-Authored-By: yoriswind <yoriswind@yahoo.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A kept clone of a paused action's continuation could reopen a scope that had
already resumed and finished; every clone now shares one resumed mark. A dialog
paused on a document target (Quick Mask or an alpha channel) and switched to a
layer target now checks the layer that was active at the pause.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep command-local history, purge and rollback intact, then consolidate affected documents at action completion or dialog suspension. Preserve semantic no-op identity and redo, visibility semantics and row identifiers. Bind dialog continuation to its exact document/history, inherit the setting in scratch sessions and carry droplet action names. Add the review counterexamples and focused continuation, Batch/droplet and history-option controls. Source is formatted; compilation and runtime qualification remain pending.
Add the default-on Actions history setting and a grouping scope shared by ordinary engine and shell playback entry points. Define public regressions for whole-play Undo/Redo, the off setting, failure prefixes, nesting, no-op and repeated-play boundaries, and persistence. This is an unvalidated draft increment: dialog continuation, direct compound edits, Batch/droplet boundaries and the complete edge-case qualification remain unfinished.
- CLI batch: recursive inputs keep the engine's tree order for {serial};
--format picks the encoder whatever extension --naming writes; the
summary prints before --error-log is written.
- Batch: a jobs.cancel during a write keeps that file in `files`;
Opened Files refuses a default-named result that replaces another open
document's file; a recorded Save leaves a document changed when Batch
writes nothing for it.
- Recording: folded Move-tool nudges add whole-pixel steps; a null
Check Spelling `action` is recorded as Check Spelling.
- Linked files: a document without links lists none missing; a look
whose links changed while it ran is dropped.
- Save for Web: a null or empty destination opens the picker; a rename
while the picker is open writes the picked file.
- Actions: a Check Spelling step fails instead of replacing a dialog
opened by hand.
- Docs: desktop Batch cancel flow, Check Spelling step shape, filter row
history count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- FTcs reference points used a 3x3 grid (Qcs0..Qcs8). The reference application has
Qcsa centre, Qcs0..Qcs3 corners clockwise from top-left and Qcs4..Qcs7 the sides
top/right/bottom/left (measured: 50 % scale, Qcs6 keeps the bottom centre, Qcs1 the
top-right corner). Qcs8 and Qcsi stay kept steps; nothing writes Qcs8.
- file.close {"save": false} (used by ui-egui tests) became an error; it discards again
and saves as Svng N.
- Batch never performs the action's Save As, so the scratch document stayed dirty and the
recorded Close (no Svng -> "save":"ask") failed every file of "...; Save As; Close".
A Save / Save As save point now marks the document saved.
- Adjustment-layer opacity is quantised to 8 bits on load; a recorded 70 % saved back as
70.196 %. The whole percent that quantises to the same level is saved again.
- Cmd-clicking a group's thumbnail errored; it loads the whole canvas again as before.
A recorded Cmd-click on another layer's thumbnail kept the numeric id and failed strict
Save Actions; it records the layer by name (or as the Background).
Co-authored-by: yoriswind <164435053+yoriswind@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Ported mappings and smart Save into current modules, preserving bounded authorized playback; migrated legacy PAT by committing validated per-pattern assets before atomic authoritative index; preserved same-ID replacements and builtin edits; added temporary-store interruption, corruption, duplicate ID/name and restart regression coverage. Current all-target compilation passed before final ownership guard refinement; focused tests pending.
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Port responsive three-column Layer Style with owned right-side actions, preserve saved defaults/Blend If and current Curves/modal routing, and keep all original layout/Cancel tests registered.
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Register starter actions and bounded background-blur command in current modules; preserve persistent migration marker and portable JSON defaults compatibility.
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Resolve recorded visibility targets before both engine and shell authorization, preserving bounded playback, paused dialogs and existing journal coalescing; retain ActionState take generation.
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Keep action-definition undo separate from document history and preserve upstream panel routing and layout.
Port behavior and regression coverage into current modules; preserve current upstream behavior.
Register bounded Actions JSON module in current command tree; preserve all ambient path restrictions and inline-data allowances with regressions.