comfyui-plugin/skills/comfy-workflow-layout/SKILL.md
Auto-layout a ComfyUI workflow JSON with a layered DAG algorithm. Use when a workflow's nodes overlap, are messy or cramped, or were imported and need tidying before use.
npx skillsauth add laurigates/claude-plugins comfy-workflow-layoutInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
scripts/layout_workflow.py runs a layered (Sugiyama-style) DAG layout
over the nodes in a workflow JSON: median layering (each node sits at
the midpoint between its earliest and latest possible depth, so source
and sink nodes spread across columns instead of piling up at the edges),
a barycenter sweep within each layer to reduce edge crossings, and a
group-cohesion post-pass that clusters members of the same authored
group contiguously within each column. Group bounding boxes are re-fit
around their final members. Pure stdlib, no deps. Visual goal is "the
editor is readable again with comparable density to a hand-tuned
layout" — link routing is left to ComfyUI.
In practice on Wan 2.2 workflows in this install, output bounding-box area ranges from −13% to +23% of a hand-arranged layout (typically within ±10%), with 0 node overlaps. Without median layering it would be 2× larger.
| Use this skill when... | Use instead when... |
|---|---|
| A workflow's nodes overlap, are messy/cramped, or were imported and need tidying | Editing the graph's wiring/links -> comfy-workflow-json |
--no-groups).--strict-groups switches to a two-level mode where each group becomes
its own bounded super-node region with a separate outer DAG between
groups. Looser packing (typically +30-50% area) but stronger visual
separation between groups; reach for it when the user prefers visible
group containers over compactness.
Skip this for ~5–8 node workflows — hand-arrange is faster and the result will be tidier than what a layered algorithm produces on a tiny graph.
From the install root, run the script via the venv on the target file:
.venv/bin/python scripts/layout_workflow.py user/default/workflows/2026-05/<file>.json
This writes <file>-laidout.json next to the original. Open both in
ComfyUI side-by-side (or load one, eyeball, then load the other) and
confirm the laid-out version is actually better before committing to
overwrite. ComfyUI picks up the new file on page reload — no service
restart needed.
The script prints a one-line summary on completion
(42 nodes (cohesion, 3 absorbed), 13 layers, 7 groups recomputed -> ...).
Pass --quiet to suppress it. In --strict-groups mode the summary
shape is different (42 nodes in 8 supers (7 group + 1 singleton (3 absorbed)), 5 outer layers, ...).
Defaults are --col-gap 40 (pixels between layers) and --row-gap 20
(pixels between nodes within a layer). If the output looks cramped,
raise the gaps. If sparse, lower them.
.venv/bin/python scripts/layout_workflow.py --col-gap 60 --row-gap 30 \
user/default/workflows/2026-05/<file>.json
Useful starting points: 30/15 for tight, 40/20 default, 60/30 for roomy,
80/40 for very large workflows where the user wants whitespace. In
--strict-groups mode the inner gap uses these values; the outer
between-groups gap is fixed at 60×80 (source constants SUPER_COL_GAP
/ SUPER_ROW_GAP).
.venv/bin/python scripts/layout_workflow.py --strict-groups <file>.json
Two-level group-aware layout: each group renders as its own bounded region in a separate outer DAG. Looser packing, stronger group separation. Use when the user wants visible group containers more than compactness.
.venv/bin/python scripts/layout_workflow.py --no-cohesion <file>.json
Skip the group-cohesion pass — group members may scatter across the layer based purely on barycenter. Useful when a workflow has groups that fight DAG topology (e.g. one logical "group" spans many depths).
.venv/bin/python scripts/layout_workflow.py --no-absorb <file>.json
Don't absorb ungrouped leaf nodes into adjacent groups. Useful when the user has deliberately placed nodes outside a group and wants the layout to honor that.
.venv/bin/python scripts/layout_workflow.py --no-groups <file>.json
Skip the group bounding-box recompute. Positions still shift, so the old bounding boxes will end up wrong — only useful for debugging.
After confirming the laid-out version looks good, two paths:
mv user/default/workflows/2026-05/<file>-laidout.json \
user/default/workflows/2026-05/<file>.json
Or re-run with --in-place to overwrite directly (no A/B copy
produced):
.venv/bin/python scripts/layout_workflow.py --in-place \
user/default/workflows/2026-05/<file>.json
--in-place and -o / --output are mutually exclusive.
Per project CLAUDE.md, do not commit workflow JSONs unless asked —
workflows under user/default/workflows/ are user data, intentionally
untracked.
Once the user confirms one workflow lays out cleanly, the rest in the
same bucket usually follow. Batch with --in-place:
for f in user/default/workflows/nsfw/2026-05/*.json; do
case "$f" in *-laidout.json) continue ;; esac
.venv/bin/python scripts/layout_workflow.py --in-place --verify "$f"
done
The case skips already-laid-out outputs left over from earlier A/B
runs. --verify aborts on overlap, which is cheap and reasonable for
batch jobs. Always run on one workflow first, eyeball it, then
batch — unwinding 30 simultaneously-broken layouts is painful.
| Preserved | Rewritten |
|---|---|
| id, revision, last_node_id, last_link_id | nodes[*].pos |
| links, config, extra, version | groups[*].bounding |
| nodes[*].size, .order, .widgets_values | |
| nodes[*].inputs, .outputs | |
| nodes[*].title, .properties, .flags | |
| nodes[*].mode, .color, .bgcolor | |
| groups[*].title, .color | |
Only positions move. Wiring, widget values, sizes, group identities, and colors all carry through unchanged. Group membership is detected from the original bounding boxes; the new bounding box is rewritten to wrap the same members in their final positions.
Pass --verify to assert no node overlaps in the output before
writing. Cheap; reach for it when batching or when iterating on gap
values.
--strict-groups mode, groups feeding each other through
different members) are silently broken with a DFS feedback-arc-set
pass; the dropped edges only affect outer-layer assignment, not the
final node positions or wiring.--strict-groups mode is typically +30-50% larger because each
group claims its own outer cell.Note nodes as section labels with hand-placed
positioning. They survive but the placement won't match the user's
intent.Surface the output path so the user can navigate to it directly. After
overwriting in place, remind the user to reload the page in ComfyUI
to pick up the new positions — no service restart needed (and don't
restart, per project CLAUDE.md that would kill any running
generation). After producing <stem>-laidout.json, offer to mv it
over the original once the user confirms the new layout looks good.
development
Debug HTTP APIs: trace requests, inspect headers. Use when a request fails: check status first.
documentation
Render architecture diagrams from text sources. Use when documenting system topology.
tools
Inspect JSON payloads and extract nested fields. Use when parsing API responses.
tools
--- name: no-description allowed-tools: Read --- # No Description This skill has no description and must be dropped with a warning.