MCP: copy_nodes, and room for groups made round new nodes (#434)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-18 20:54:21 +02:00
1 parent c098520c86
commit 286e3daa8d
1 file changed
+15 -2
+15 -2
@@ -106,9 +106,18 @@ it. One Ctrl+Z takes the whole call back.
Nodes that belong together go into a group (`add_group`), with a comment on what they do
(`add_comment`). Both take the nodes they are about rather than a box: a group is drawn around
them, a comment just above — below them where another node or a group's title bar stands above —
and when the call arranges its nodes they follow them there, still in the same undo step. The
and when the call arranges its nodes they follow them there, still in the same undo step. A
group made round new nodes alone gets room as they are arranged: a node or another such group
that would stand in it goes below it, so it holds its own nodes only. The
group is the one *Group* in the graph's menu draws around a selection. `lint_graph` also counts
comments a node lies on (`coveredNotes`), which `fit_group` puts back by their nodes.
- **Copying nodes.** `copy_nodes` copies nodes into the same graph or another, as Ctrl+C and
Ctrl+V do: with the links between them and the groups and comments about them alone. Each copy
is named by the id of its original (`"$copy.<id>"`), so later steps can link it. Without `x`
and `y` the copies are arranged like new nodes, with them the copy keeps its layout. Nodes the
other graph cannot hold are refused by name, by the same rule the graph tab pastes with. The
variables a copied Variables node reads from its behavior come along into the other behavior,
with their default, *Keep* and *Private*. One declared there in another kind is refused.
- **Silent music.** A pattern plays nothing without an instrument, and an instrument sounds only
the notes its Notes nodes take in (C4 to B4 in a new one). Nothing else says so. `get_asset` lists
under `silent` what of a pattern, a song or a composition is not heard: all of it for want of an
@@ -152,7 +161,7 @@ for an area or for command names asked for.
| assets | `create_asset`, `add_file_asset`, `rename_asset`, `duplicate_asset`, `delete_asset`, `set_asset_property`, `reset_asset_property`, `set_start_scene`, `set_machine_scope`, `set_machine_start`, `set_variables_scope`, `set_variables_persistent`, `make_project_asset` |
| variables | `add_variable`, `remove_variable`, `rename_variable`, `move_variable`, `set_variable_kept`, `set_variable_private`, `add_struct_field`, `remove_struct_field`, `rename_struct_field`, `move_struct_field`, `set_struct_type`, `make_struct_type`, `set_list_item_type`, `make_list_item_type` |
| objects | `place_asset`, `remove_objects`, `move_object`, `reorder_object`, `set_editor_offset`, `rename_object`, `set_override`, `clear_override`, `apply_override_to_asset`, `apply_override_to_container`, `revert_override_to_container`, `apply_position_to_container`, `revert_position_to_container`, `set_parent`, `group_objects`, `set_object_group`, `rename_object_group`, `ungroup_objects`, `create_container`, `unpack_container`, `add_collider`, `add_rigidbody`, `add_joint`, `fit_collider` |
| graphs | `add_node`, `arrange_graph`, `remove_node`, `move_node`, `set_node_param`, `collapse_nodes`, `resize_node`, `connect`, `disconnect`, `fold_edge`, `name_transition`, `add_group`, `add_comment`, `fit_group`, `edit_annotation`, `remove_annotation`, `add_port`, `repoint_port`, `remove_port`, `rename_port`, `move_port`, `set_port_write`, `set_port_machine`, `set_port_default`, `set_node_struct_type`, `split_output`, `set_list_node_type` |
| graphs | `add_node`, `copy_nodes`, `arrange_graph`, `remove_node`, `move_node`, `set_node_param`, `collapse_nodes`, `resize_node`, `connect`, `disconnect`, `fold_edge`, `name_transition`, `add_group`, `add_comment`, `fit_group`, `edit_annotation`, `remove_annotation`, `add_port`, `repoint_port`, `remove_port`, `rename_port`, `move_port`, `set_port_write`, `set_port_machine`, `set_port_default`, `set_node_struct_type`, `split_output`, `set_list_node_type` |
| animation | `set_animation_root`, `add_animation_track`, `remove_animation_tracks`, `retarget_animation_track`, `set_track_relative`, `set_animation_key`, `set_key_easing`, `remove_animation_keys`, `move_animation_keys`, `shift_animation_frames`, `key_straight_run`, `set_curve_points` |
| textures | `add_frame`, `set_frame_rect`, `rename_frame`, `remove_frame`, `slice_frames`, `set_nine_slice`, `set_sort_line`, `set_frame_collision` |
| tiles | `add_tile_picture`, `remove_tile_picture`, `move_tile_picture`, `paint_tiles`, `add_tilemap_layer`, `duplicate_tilemap_layer`, `remove_tilemap_layer`, `move_tilemap_layer`, `set_tilemap_layer`, `resize_placed_tilemap` |
@@ -267,6 +276,10 @@ What is behind it on the server, and the routes it uses: [API](API), [Developmen
undo step, `arrange_graph`, what the editor shows after a call (and
the scene switch inside the undo step, and nothing with *Follow agent* off), the reading tools
and the catalog (every area in full under the size an answer is cut at).
- `tests/editor/agent-copy.test.ts`: nodes copied into another behavior with their links, a group
and a comment, a variable carried along and later steps linking the copies, all taken back by one
undo; a copy placed by hand keeping its layout; nodes a shader cannot hold and a variable of
another kind refused.
- `tests/editor/agent-catalog.test.ts`: a Variables node reading a variable once `add_port` names
it (and refusing a name it does not know), a group and a comment fitted to the nodes after the
call arranged them, a field of a Struct asset reaching the variables of that type, a container's