Skip to content

Add a bulk property-replace tool (like Pencil's replace_all_matching_properties) #127

Description

@vicmaster

Summary

Add a bulk property-replace tool to the FrameSmith MCP so a single call can update a property across many nodes at once — analogous to Pencil's replace_all_matching_properties.

Motivation

Today batch_design only edits nodes by explicit id (U("nodeId", {...})). When you need the same change across many nodes there's no shortcut — you hand-write one U(...) per node.

Concrete example from real use: making a ~17-row data table fill its container meant setting width: "100%" on every cell of 4 columns — 68 individual U() ops in one batch, after manually gathering all 68 node ids. A single "set width→100% on all nodes currently width:110" call would have been one line.

canvas_autofix covers the mechanical spacing/scale subset, but there's no general "find nodes matching property X, set property Y" primitive.

Proposed API

A new tool, e.g. replace_matching_properties:

replace_matching_properties({
  canvasId,
  match:   { width: 110 },        // property/value predicate (AND across keys)
  set:     { width: "100%" },     // properties to write
  scope?:  "nodeId",              // optional subtree to limit to (default: whole doc)
  type?:   "text" | "frame" | ... // optional node-type filter
  dryRun?: true                    // return the matched node ids + count without writing
})

Returns the list of affected node ids and a count (mirrors batch_design's result shape).

Notes / niceties

  • dryRun is valuable for safety — preview the match set before committing, since a value like width: 150 can match more nodes than intended.
  • A type and/or scope filter avoids collateral hits (e.g. only table cells, not the whole canvas).
  • Matching on token references (e.g. fill: "$secondary-container") as well as literals would be handy.
  • Pencil's MCP already ships replace_all_matching_properties / search_all_unique_properties — worth looking at for prior art (the search companion that enumerates the distinct values in use pairs naturally with this).

Workaround today

Enumerate the node ids and emit one U(...) per node in a batch_design call. Works, but is O(n) to author and error-prone for large tables.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions