Transform objects (selector)
transform_objectsApply one typed operation to every object matching a selector, enabling bulk edits like recoloring, repositioning, or deleting objects based on their attributes.
Instructions
Apply ONE typed op to EVERY object a selector matches — one atomic, reversible operation.
When to use: bulk editing keyed by a predicate rather than by hand-listing ids — "recolour every
blue rect", "nudge every text down 4px", "delete every object whose id starts with tmp-". It is
find_objects (the SELECTOR) wired to ONE typed op fanned across the matches, run through the
SAME atomic batch kernel as apply_edits. For a known id list call the dedicated tool
(set_fill, move_object, …) or apply_edits directly; this adds NO authority — only the
select-then-apply fan-out (ADR-002/003: no free text, no raw Action, no loops/expressions).
Key params: selector is the SAME predicate find_objects takes (tag / fill / stroke /
text / id_prefix / bbox, full CSS-cascade paint match); operation is exactly ONE op
tagged by an op field — the accepted set is set_fill / set_stroke / set_opacity /
set_font / move_object / scale_object / rotate_object / delete_object (high), each
with the SAME params as its dedicated tool MINUS the target ids (those from the selector), e.g.
{"op": "set_fill", "color": "#3366cc"}, {"op": "move_object", "dx": 0, "dy": 4}. Document-
wide ops (replace_color, apply_palette, resize_canvas, normalize_viewbox), element
CREATION ops, and identity-conflicting per-id ops (rename_object, replace_text,
duplicate_object) are NOT accepted — they are not meaningful applied identically per match.
dry_run=True (DEFAULT) resolves + validates and returns the matched ids + the projected plan,
writing NOTHING; dry_run=False performs it. max_matches (default 64) REJECTS an over-broad
selector before any mutation. A delete_object op makes the operation HIGH and requires a
non-empty approval_token.
Render and look before you trust it: a transform changes many objects at once — call
render_preview (or live_render_view in live mode) afterwards and inspect the result, and
restore_snapshot(doc_id, snapshot_id) reverts the WHOLE transform in one step.
Return shape: TransformObjectsResult — matched_ids + match_count, the effective
risk_class, the dry_run flag, the projected plan (per-edit op + target id(s)); on a real
run also applied / changed / summary and the single operation_id / snapshot_id (the
revert target).
Example: transform_objects(doc_id, {"tag": "rect", "fill": "#3366cc"}, {"op": "set_fill", "color": "#ff0000"}, dry_run=False)
Risk class: medium (the effective risk is the op's class; a delete_object op escalates the
operation to high and requires approval_token). Reversible via the pre-transform snapshot.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes | ||
| dry_run | No | ||
| selector | Yes | The target selector — the SAME predicate fields `find_objects` takes (no new logic). Every supplied filter is ANDed; an unset filter is ignored. With no filters at all the selector matches every addressable object (then bounded by `max_matches`). `tag` is an exact local element name; `fill` / `stroke` match the EFFECTIVE cascade-resolved paint (casing- / shorthand- insensitive); `text` is a case-insensitive substring; `id_prefix` an id prefix; `bbox` an intersection box. `accurate_bbox` opts into geometry-accurate boxes (one read-only Inkscape `--query-all`) so transformed / path / text objects can match a `bbox`. | |
| operation | Yes | ||
| max_matches | No | ||
| approval_token | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| plan | Yes | ||
| doc_id | Yes | ||
| applied | No | ||
| changed | No | ||
| dry_run | Yes | ||
| summary | No | ||
| risk_class | Yes | ||
| match_count | Yes | ||
| matched_ids | Yes | ||
| snapshot_id | No | ||
| operation_id | No |