From 9873ee6190c3642f13ad16a20ae6e82603510663 Mon Sep 17 00:00:00 2001 From: MelekTaus Date: Sun, 18 Oct 2026 12:10:25 +0200 Subject: [PATCH] MCP and Behaviors: Arrange, lint_graph and the badge count (#429) The agent gives no coordinates any more, the editor lays its nodes out. The pages say how, and what an agent can check. - Behaviors: the Arrange button next to the magnet, what it does with a selection and with groups, one undo step. - MCP: the tool lint_graph, the command arrange_graph (24 commands now), nodes placed at the end of a call while placed ones stay, and the rule for far values. - MCP: which agents the badge counts. Spare sessions that never call a tool do not. - MCP: the tests for arrange and the new checks in e2e 71. Co-Authored-By: Claude Opus 5.5 --- Behaviors.md | 7 +++++++ MCP.md | 33 ++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Behaviors.md b/Behaviors.md index 5ef21d2..2040ef5 100644 --- a/Behaviors.md +++ b/Behaviors.md @@ -627,6 +627,13 @@ the inspector). switching it on never shuffles a graph that is already laid out, and a node nobody drags never moves. Every node of a selection snaps **for itself**, so dragging a group is how you line one up; the offset is a decision about rectangles and lives with the others in `editor/framing.ts`. +- **Arrange** (next to the magnet, in every graph tab; #429) lays the graph out: the flow runs left + to right in columns, a node that only feeds others (a Get, the Owner) stands just left of the + first one it feeds, each column is put in the order that crosses the fewest links, and the nodes + are moved up or down towards the ports they link to without ever overlapping. With several nodes + selected it arranges those and leaves the rest; they keep their place if they fit there, else they + go right of everything. A group around them stays where it is. One undo step, *Arrange nodes*. + It measures every node as drawn; the rule is the pure `editor/graph/arrange.ts`. - **One tab per behavior**: each behavior opens as a document of its own (double-click in the asset panel), several at once, each keeping its zoom and scroll for the session. A selection never changes what a tab shows; selecting a node of another graph brings that graph's tab up. diff --git a/MCP.md b/MCP.md index af6a465..c3680d3 100644 --- a/MCP.md +++ b/MCP.md @@ -19,7 +19,9 @@ clicks run. Laying out the graphs it builds comes next (see the issue). The server keeps only a hash of the token; close the dialog without copying it and it is gone, make a new one. 2. **Switch the agent on** in the tab you want it to work in: account menu → *Agent*. A badge - appears beside the account menu and shows how many agents are connected. A click on the badge + appears beside the account menu and shows how many agents are connected: an agent counts while + it keeps its event stream open or has called a tool in the last two minutes. Claude Code opens + spare sessions when it connects, they never call a tool and do not count. A click on the badge switches the agent off again. 3. Ask Claude Code about the editor. Without a tab switched on, every tool answers that no editor is connected and how to fix that. @@ -57,6 +59,7 @@ the badge says *Agent offline* meanwhile. | `list_assets` | The assets with ids, names and types, by type or a part of the name | | `get_asset` | One asset as stored, with the rows of its properties and the named objects of a scene or container. A graph is only counted, pixels and map cells too | | `get_graph` | A graph: every node with its settings and its ports as they are now, the edges, the groups and notes | +| `lint_graph` | How a graph reads, counted as you see it: nodes on top of each other, links that cross, links running over a node that is not theirs, links running right to left, the longest links, with a few ids of each | | `catalog` | What there is to make: the commands with their arguments, the nodes a graph can hold (all of them, or the best matches of a search in full), the asset types and their properties, the variable kinds | | `run_commands` | Changes the project, see below | | `open` | Brings up an asset's tab, or the scene or game tab | @@ -83,19 +86,26 @@ it. One Ctrl+Z takes the whole call back. (and `"$walk.closing"` for the second node a Find adds). Each step is built after the one before has run, so one call can make a behavior and fill its graph. - **Nodes come from the palette.** `add_node` takes the id of an entry of the catalog for that - graph: `OnKeyHeld`, `Move`, `RunBehavior:` for another behavior. Without `x` and `y` a node - goes right of everything the graph holds; the real layout comes with the next stage. + graph: `OnKeyHeld`, `Move`, `RunBehavior:` for another behavior. +- **The editor places the nodes.** Nodes added without `x` and `y` are arranged when the call has + run, the way the [Arrange](Behaviors) button does it, and the move is part of the same undo + step. Nodes that were there before stay where they are, so what you laid out by hand is never + shuffled; the new ones keep the place right of them. `arrange_graph` arranges nodes the agent + names, or the whole graph, which the agent is told to do only when you ask. +- **Readable graphs.** The agent is told to fetch a value needed far away with a second Get or + Owner node next to where it is used rather than one long link, and to check with `lint_graph`. - **Deleting asks you.** A call that deletes an asset that was there before opens a dialog *The agent asks: Delete "..."?* with the same text as your own Delete. The call waits for your answer, up to 110 seconds; Cancel, Escape or no answer leave everything as it was. - **While the game runs** a change goes into the running copy, as yours would, and the answer says it is gone when the game stops. -The 23 commands so far: assets (`create_asset`, `rename_asset`, `duplicate_asset`, +The 24 commands so far: assets (`create_asset`, `rename_asset`, `duplicate_asset`, `delete_asset`, `set_asset_property`, `reset_asset_property`, `set_start_scene`), variables (`add_variable`, `remove_variable`, `rename_variable`), placed objects (`place_asset`, `remove_objects`, `move_object`, `rename_object`, `set_override`, `clear_override`, `set_parent`) -and graphs (`add_node`, `remove_node`, `move_node`, `set_node_param`, `connect`, `disconnect`). +and graphs (`add_node`, `arrange_graph`, `remove_node`, `move_node`, `set_node_param`, `connect`, +`disconnect`). Textures, fonts, sounds and videos need a file and cannot be made by an agent. A behavior acts on the object it is placed under. The smallest walking object is therefore a @@ -138,9 +148,14 @@ What is behind it on the server, and the routes it uses: [API](API), [Developmen routes as everybody, with and without the relay's key. - `tests/editor/agent-view.test.ts`: what `get_view` answers, its one line, the tools' arguments. - `tests/editor/agent-edit.test.ts`: a walking object built in one call and taken back whole by one - undo, a failing step that leaves nothing, argument checks, deletes that ask, the reading tools - and the catalog. + undo, a failing step that leaves nothing, argument checks, deletes that ask, nodes arranged at the + end of a call while placed ones stay, `arrange_graph`, the reading tools and the catalog. +- `tests/editor/graph-arrange.test.ts`: the layout on the graph an agent really built for "walk with + the arrow keys" (no overlaps, no link over a node, none backwards, at most 8 crossings with one + Owner for four moves and 4 with one each), chains running straight, nodes that stay, groups kept + clear, loops, and what `lint_graph` counts. - e2e step 71 (`tools/e2e/71-mcp.mjs`): a token made in the dialog, the agent switched on in the account menu, an MCP client reading the view, hearing a tab switch and taking a screenshot; the - agent building a walking object that moves when played, one Ctrl+Z taking it back, a delete - waiting for the user's Cancel; and the badge switching it off. + agent building a walking object whose nodes come out arranged, Arrange in the header untangling + it as one undo step, the object moving when played, one Ctrl+Z taking it back, a delete waiting + for the user's Cancel; and the badge switching it off.