Let the agent copy nodes, also into another graph (#434)
The agent built every part again that already stood in a graph, node by node, while the editor has Ctrl+C and Ctrl+V for it. The new command `copy_nodes` in the area graphs copies nodes into the same graph or another one, in one undo step with the rest of the call. - The links between the copied nodes come along, and so do groups and comments that are only about copied nodes. A node belongs to a group by its middle, as when it is dragged. `boxesAbout` in annotationFollow.ts decides this. - `made` names each copy by the id of its original, so later steps link to it with `$copy.<id>`. `$copy` alone is the first one. - Without x and y the copies are arranged at the end of the call like new nodes. With them they keep their layout, top left corner there. - Nodes the target graph does not take are refused by name, not left out as Ctrl+V does. The rule is the graph tab's: `fitsGraph` and `fittingPart` moved from clipboard.ts to paletteEntries.ts. - A copied Variables node takes the variables of its behavior along into the target behavior (`CarryVariablesCommand`), with default, value, Keep and Private. A variable of that name of another kind there is refused. - The relay's instructions name `copy_nodes`. Found on the way: - Groups made by the agent can take in a node of another group once the nodes are arranged. lint_graph does not count that. - Undo after a paste leaves an empty `groups: []`, as AddAnnotationCommand does. It is the same as no list. Tests: - agent-copy (new, 3 tests) with the agent, relay, clipboard and palette tests: 118/118. - Counter-probes: 6 bendings, all compile, all red. - e2e 71 (atx): ALL PASSED, 26 checks. - Gate (atx): CHECK EXIT 0, 327 files, 5024 tests. - Live in the MCP Test Project: 5 nodes of Arrow keys walk into a new behavior, 6 links, group, comment and speed (300) along, lint_graph 0 everywhere, taken back with undo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e4b0419a53
commit
fb981b5b0f
7 files changed
+386
-45
No files matched your search
@@ -65,6 +65,48 @@ export class AddVariableCommand implements Command {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares variables of one behavior in another as they are declared there (#434): default, Keep
|
||||
* and Private included, for copied nodes that name them. A key the target has already is left alone.
|
||||
*/
|
||||
export class CarryVariablesCommand implements Command {
|
||||
readonly label = 'Carry variables';
|
||||
private added: string[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly assetId: string,
|
||||
private readonly fromId: string,
|
||||
private readonly keys: readonly string[],
|
||||
) {}
|
||||
|
||||
execute(project: Project): void {
|
||||
const from = requireBehavior(project, this.fromId);
|
||||
const to = requireBehavior(project, this.assetId);
|
||||
this.added = [];
|
||||
for (const key of this.keys) {
|
||||
const def = from.variables.find((v) => v.key === key);
|
||||
if (!def) throw new CommandError(`${from.name} has no variable "${key}"`);
|
||||
if (to.variables.some((v) => v.key === key)) continue;
|
||||
to.variables.push(structuredClone(def));
|
||||
to.props[key] = structuredClone(from.props[key] ?? def.default);
|
||||
if (isKeptVariable(from, key)) setKeptVariable(to, key, true);
|
||||
if (isPrivateVariable(from, key)) setPrivateVariable(to, key, true);
|
||||
this.added.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
undo(project: Project): void {
|
||||
const to = requireBehavior(project, this.assetId);
|
||||
const added = new Set(this.added);
|
||||
to.variables = to.variables.filter((v) => !added.has(v.key));
|
||||
for (const key of added) {
|
||||
delete to.props[key];
|
||||
setKeptVariable(to, key, false);
|
||||
setPrivateVariable(to, key, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** One placed object's own value for a variable, remembered so that undo can put it back. */
|
||||
interface TakenOverride {
|
||||
holderId: string;
|
||||
|
||||
Reference in new issue
Block a user