Layout and Tidy up
Tidy a workflow's layout with one click, one node at a time, from the console, or through an agent — and set the spacing it keeps.
A workflow that grew by hand ends up with cards on top of each other, wires that double back, and wires that run straight through a port they have nothing to do with. Tidy up puts that right without you moving a card: it picks a layout that reads left to right, keeps your cards apart, straightens what it can, and leaves the workflow alone when it cannot do better.
Tidy up
| Where | Entry | Shortcut | What it tidies |
|---|---|---|---|
| Canvas controls | The broom button | Shift + Alt + T | The whole workflow |
| Canvas (pane) menu | Tidy up | Shift + Alt + T | The whole workflow |
| Node menu | Tidy node (Tidy 3 nodes with a multi-selection) | Shift + S | The selected node, or each selected node in turn |
The buttons are absent when the canvas is read-only or locked. The shortcuts work
with the canvas focused (or nothing focused, after a click on the empty canvas);
Shift + S needs at least one selected node.
- One undo step. Tidying several nodes is one step too.
- The cards slide to their new places (about a quarter of a second; not at all under reduced motion).
- A toast says what happened, for example Tidied up: 2 overlaps fixed · 3 wires straightened · 1 crossing removed, with an Undo button. When something had to get worse to fix something more important, the toast says so (but 1 more crossing).
- Nothing to gain, nothing moves. You get Layout is already tidy (Node is already tidy), and no undo step is recorded.
- Big workflows are refused. Tidy up works on up to 120 nodes. Above that, the
toast reads Too many nodes to tidy at once; the error is
graph too large to tidy. Tidy single nodes instead, which has no limit. - Notes and captions never move. They are fixed obstacles: cards keep clear of them and no layout step moves or reorders them.
Tidy up keeps the top-left corner of your workflow where it was and keeps every card on the 20 px layout grid, so a tidied workflow does not drift across the canvas.
What "tidy" means
A layout is judged by a fixed list, in priority order. A better result on an earlier item always wins over any gain on a later one:
- No overlaps and enough spacing. Cards never overlap, and keep the gap from each other: the horizontal gap between cards side by side, the vertical gap between stacked cards. Diagonal neighbours need no gap.
- No wire through a port it does not belong to. A wire passing straight through an unconnected port looks as if it started or ended there.
- Straight wires. A wire is straight when it is level and runs left to right. Loopbacks do not count.
- Wires run forward. Left to right, not back across the cards.
- Fewer crossings.
- Fewer near misses. A wire passing 10 to 20 px from a port that is not its own.
- Least movement. Of two equal layouts, the one that moves cards less.
Only the first two can bend a wire that was straight. The rest never trade away a straight wire.
Tidy up keeps your layout unless the result is better on items 1 to 6. A layout that would end up equal or worse is thrown away, so running it twice is harmless.
Four moves do the work, tried one node at a time and each kept only if it improves the score of the whole workflow:
| Move | What it changes |
|---|---|
column | The card's x: into its column, one step right of what feeds it, then up or down to find room. |
ports | The order of the card's connected ports, so wires stop crossing. Only connected data ports move, within the slots they hold. The branch outputs of a gateway are never reordered; the cards they lead to move instead. |
align | The card's y, so one of its wires runs level. |
clear | The card's y, only to leave an overlap, a too-tight spacing, or a wire passing through a port. |
align and clear move cards vertically only; only column changes x.
Tidy up on the whole workflow puts every card in its column first, then clears
conflicts, then runs ports and align until a pass changes nothing.
From the console and the AI Assistant
The command console (and the AI Assistant, which runs the same
commands) has three layout commands besides layout auto.
layout node inspect <nodeId> [--gap-x <px>] [--gap-y <px>]
layout node beautify <nodeId> [column|ports|align|clear|all] [--dry-run] [--gap-x <px>] [--gap-y <px>]
layout beautify [--dry-run] [--gap-x <px>] [--gap-y <px>]layout node inspect
Reports how one node sits on the canvas and changes nothing. Run it before you beautify to see what is wrong.
> layout node inspect compose
compose y=160 inputs: contact, label outputs: reply
in contact ← lookup.contact off by 40 crosses classify.label → compose.label
out reply → loop.items straight
overlaps none · spacing okFor each wire the report says straight, off by <px>, backward or loopback, and
names the wires it crosses. The last line lists the card's conflicts: overlap with,
spacing with a neighbour, or lane with a return lane. For a note or caption it
says fixed obstacle.
layout node beautify
Tidies one node. The strategy is one of the moves above, or all (the default),
which runs column, ports, align and clear in that order. Only that node moves.
> layout node beautify compose --dry-run
> layout node beautify compose align
> layout node beautify compose all --gap-x 160It prints what changed and the score before and after (straight 0 → 1 · crossings 3 → 2 · overlaps 1 → 0 · spacing ok), or no change with the reason. --dry-run
only previews: the output says would move instead of moved. One undo step.
layout beautify
The whole-workflow tidy: the same thing as Tidy up. It prints a line per step
and the score before and after, or says the layout is already as good as it gets.
--sweep is still accepted and changes nothing. Above 120 nodes it fails with
TOO_LARGE, and points at layout node beautify.
Gaps
--gap-x and --gap-y override the layout gap settings for one
call. A gap must be a non-negative multiple of the 20 px layout grid; anything else
fails with INVALID_ARGUMENT:
--gap-x 30 is not valid: a gap must be a non-negative multiple of the 20 px layout grid (0, 20, 40, ...)The flags can come in any order after the node id and strategy.
Spacing and lanes
In Settings → Editor:
| Setting | Default | What it does |
|---|---|---|
Layout gap between columns (layoutGapX) | 120 | Space kept between cards side by side, in px. |
Layout gap between stacked cards (layoutGapY) | 40 | Space kept between cards one above the other, in px. |
Gaps are at least 0 and are rounded to the grid. Tidy up, layout beautify,
layout node beautify and layout node inspect all read them; the console flags and
the agent tools' gapX / gapY override them for a single call.
updateSettings({ editor: { layoutGapX: 160, layoutGapY: 60 } });Return lanes. A loop's loop_back wire is always drawn as a lane: out of the
source, down under the loop body, back along a lane 40 px below its lowest card, and up
into the port. Nested loops get nested lanes, and several loopbacks stack 20 px apart.
Layout keeps the lanes free of cards, so the loop body keeps the room below it. There is
no setting for it. Until every card of a loop body has been measured on the canvas, its
loopback is drawn as a curve.
Everything the layout places lands on the 20 px layout grid, whatever the editor's Grid size is.
See also
- Editor tools for browser agents —
inspect_node_layout,beautify_nodeandbeautify_layoutas agent tools. - The AI Assistant — the AI Assistant Layout Changes opt-out.