A document opened or created between edit.undoGroup.begin and
edit.undoGroup.end opens an undo group of its own with the begun
group's name, so an atomic command_batch that starts with file.new or
document.open is one undo step in the new document. The group opens
after the command that opens the document: when that command also
edits it (a command.batch), those edits stay the command's own undo
step, and a canceled group keeps them, so the journal still replays.
Both commands also run with no document open, and a command.batch that
fails rolls back a begun group. Switching to a document that was
already open does not open a group in it.
With View > Guides > Lock Guides on, Session::select drops the paths
made into guides from the selection (#1534), but commands that set the
selection another way skipped that filter and left a locked guide
selected, so the next move moved it. object.exitIsolation selected an
isolated guide path. Undo, Redo, a canceled undo group, a canceled
drag or dialog preview and a failed command.batch brought back locked
guide paths and ruler guides in the selection. Unlock All, Show All
and Paste selected the guide paths they unlocked, showed or pasted.
Locking the guides deselected them in the active document only.
The filter is now deselect_guides, which also clears the selected
ruler guides. Session::select and Session::edit run it while Lock
Guides is on, and so do object.exitIsolation, Undo, Redo,
Session::cancel_interaction, a canceled undo group and a failed batch.
Locking the guides deselects them in every open document. With Lock
Guides off, the selection is set as before.
Docs: docs/mcp.md.
Object › Artboards › Fit to Artwork Bounds and Fit to Selected Art ran
artboard.fitToArt and artboard.fitToSelection without an index, so
they resized artboard 1 whichever artboard was active. The Artboards
panel menu's Fit to Artwork Bounds already passed the active artboard.
The app now passes its active artboard as the index of the two
commands when a call names none, as it passes the artboard to Align to
Artboard, All on Active Artboard and Paste in Place, in Front and in
Back. That covers the menu items, keyboard shortcuts, the command
palette and MCP's run_command in remote mode. A batch passes its
artboard as the index to their steps that name none, and a recorded
action leaves the index out, so an action resizes the artboard that is
active when it plays. The params texts of the two commands and of
command.batch describe where the index comes from.
Docs: docs/mcp.md, docs/target-app-parity.md.
The rollback undid the batch's interaction, which holds the art, the selection
and panel state only: a Save As step's new file, format and saved state stayed,
and an Undo step (which ends the interaction) left the art and the history
undone. The batch now keeps the documents as they were and puts them back,
and settles a drag or typing in progress first, as Undo does, instead of
running inside it and keeping its baseline as the batch's step. Files the
steps wrote stay written.
Align to Artboard aligned the selection to the artboard under its
center, or to the first artboard when no artboard was under the
center. A press with a selection tool inside an artboard makes that
artboard the active one (#693). With the Selection tool, a
Shift-click on an empty spot inside an artboard also makes it active
and keeps the selection. Align to Artboard did not use the active
artboard.
object.align takes artboard, a 0-based artboard index, and uses it
when its to param is "artboard". The app passes its active artboard,
the one the Artboards panel highlights, to each object.align it runs
that names none, as it does for Paste in Place, Paste in Front, Paste
in Back (#693) and Select › All on Active Artboard (#1006). MCP calls
in remote mode also get it. Without artboard (headless MCP and the
CLI), or with an index the document doesn't have, object.align aligns
to the artboard under the center of the selection, or to the first
artboard when no artboard is under the center.
command.batch takes artboard too, and the app passes it the active
artboard. The batch passes it on to each step of these five commands
that names none, when the step runs. When the document a step runs in
has no artboard at that index (for example, after an earlier step
deleted the active artboard when it was the last one), the step gets
that document's last artboard. A step in a document that an earlier
step opened, created or switched to gets the same index, not that
document's own active artboard.
With Align to Selection, one selected object aligned from the Align
panel, the Control bar or the Properties panel is aligned to the
active artboard too, unless it is the key object.
Recorded actions leave out the artboard that the app passes to these
commands and to the batch. The Actions panel plays an action as a
batch. Its Align to Artboard, All on Active Artboard and in-place
paste steps that name no artboard use the artboard that is active
when it plays, and the default Center on Artboard action now centers
on the active artboard. In-place paste steps recorded since #693 and
before this change still paste onto the artboard that was active when
they were recorded.
Tests cover object.align with and without artboard on three artboards;
a Shift-click that makes an artboard active, after which Align to
Artboard aligns to that artboard but keeps an artboard the call names;
a batch that passes its artboard to each step when the step runs,
after a step deletes the last artboard and in a new document; recorded
actions that leave the artboard out; and recorded Align to Artboard
and Paste in Place steps and the default Center on Artboard action,
which play on the artboard that is active when they play.
Docs: docs/mcp.md (Align to Artboard), docs/target-app-parity.md.
command.batch kept its steps in one interaction of the document active
when it began and journaled itself by committing that interaction. A
step that opened, closed or reverted a document broke both: the switch
cancelled the interaction (throwing away the steps so far), and the
commit then ran in the new document, which had none, so the batch was
never journaled and a replay was missing the new document. An error
after the switch rolled back only the active document.
- Each step runs inside an interaction of the document active when it
starts; a switch leaves it open while a batch runs, so every document
the batch edits gets one undo step when it succeeds.
- The batch journals itself, whichever document it ends in.
- On error everything rolls back: documents the batch opened close, the
ones it closed or reverted come back (Session::batch_stash), each
one's interaction is undone, and the active document and the
Untitled-N count go back too.
- DocState::keep_interaction / undo_interaction share the undo-step and
rollback code with commit_interaction / cancel_interaction.
- Tests: a batch that opens a new document is journaled, replays to the
same documents and keeps one undo step in each; a failed batch closes
the document it opened and restores the one it closed; a failed batch
brings back a document it reverted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Session::note_journal only kept values noted by the top-level command, so
a command run as a step of command.batch lost them: a save in a batch
stamped File Info's modified date from the clock without recording it,
and object.scale's strokes/corners came from the preferences again on
replay. Replaying such a journal a second later (or with other
preferences) gave a different document.
- Session::execute_step runs a batch step with its own journal notes
(note_depth) and returns its params with what it noted; command.batch
writes those params into its step of the batch's journal entry (steps
that note nothing stay as given).
- journal_for_action strips the replay-only dates from a batch's steps
too, so an action recorded with one still dates the document when it
plays.
- Tests: a save in a batch records its date and a replay with the
recorded date moved lands on it, while an action leaves it out; a scale
in a batch records Scale Strokes & Effects and replays alike with the
preference off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>