app-dev/figjam-diagrams/SKILL.md

name: figjam-diagrams description: >- Layout craft for readable FigJam architecture/flow diagrams. Use whenever creating or editing a diagram in FigJam — after generate_diagram (whose auto-layout is reliably bad) or when building/rearranging nodes via use_figma. Load alongside the plugin figma-use / figma-generate-diagram skills; this one adds the layout rules and FigJam node-manipulation gotchas they don't cover.

figjam-diagrams

generate_diagram gets topology and edge labels right but layout wrong: sprawling sections, diagonal queue chains, labels buried under shapes. Plan for a generate → compact → verify loop, not a one-shot call. Expect 2–3 render-look-fix iterations; budget them, don't fight them.

Content before layout

  • Diagram quality is bounded by context. Grep the actual repo (terraform, handlers, queue definitions) and use real file/class/method names as node and edge labels — billingWebhookProcess.processEvent, not "processor".
  • Mark proposed/not-yet-built components (new) inline in the label.
  • Don't invent edges to round out the picture; a gap beats a hallucination.

Layout rules (the ones that actually fix readability)

  1. One column per pipeline stage, strictly left-to-right in data-flow order (ingress → router → queues → consumers → downstream). Parallel paths become horizontal lanes sharing the same column grid — never scattered rows.
  2. Size each shape to its text. Long identifiers need 350–480+ width; forcing uniform small shapes causes ugly wraps and overflow. Resize per node, not globally.
  3. Column gaps must exceed the longest connector label living in them. FigJam renders labels at the path midpoint and you cannot move the label itself — if the gap is narrower than the label, it lands on a shape. Estimate ~9px per character at default font and leave slack.
  4. Reserve empty corridors for long skip-stage edges (e.g. router → datastore): route them above or below the whole grid, never threaded between columns. Give the corridor its own headroom so the label sits in pure whitespace.
  5. Continuation chains go to a new lane at the bottom-right, continuing the left-to-right flow, so their inbound drop edges fall through open space instead of crossing other columns.
  6. Keep edges orthogonal; avoid diagonals. Pin magnets when auto-routing picks a bad side (see below).

FigJam node-manipulation gotchas (use_figma)

  • Placement: new generated sections land far to the right of all existing content — after generating, read coords with get_figjam and move the section next to the rest of the board. Deleting a section leaves its old gap; reposition survivors.
  • Flatten before rearranging: the architecture layout (FIGMA_DIAGRAM_2026) nests lane sub-sections inside the diagram section. Reparent children to the outer section (outer.appendChild(child)) before inner.remove() — removing a section deletes its children.
  • Match nodes by ID, never by name substring. Names collide hard here (webhook-forward matches both the lambda and the queue). Pull IDs from get_figjam output and hardcode them in the script.
  • Shapes are SHAPE_WITH_TEXT; resize with node.resize(w, h). Generated widths are inconsistent (one shape came out 666px wide) — normalize per content, checking node.width first.
  • Connectors follow moved/reparented shapes automatically — moving shapes is always safe. To force a side: c.connectorStart = { ...c.connectorStart, magnet: 'BOTTOM' } (reassign the whole object; in-place mutation doesn't stick). Values: AUTO, TOP, BOTTOM, LEFT, RIGHT, CENTER.
  • Shrink the wrapper with section.resizeWithoutConstraints(w, h) — children keep their coordinates.
  • Labels can only be fixed by moving shapes or pinning magnets so the path midpoint lands in whitespace.

Verify loop

get_screenshot on the section node → curl the returned URL to the scratchpad → Read the PNG. Check specifically for: labels clipped by shapes, edges routing through boxes, dead whitespace bloating the section. Fix and re-screenshot until clean, then screenshot the whole page once to confirm placement relative to existing content.

Tool prerequisites

  • generate_diagram needs planKey (whoami lists plans — pick the org with a Full seat) and the plugin figma-generate-diagram skill loaded first; pass fileKey to add to an existing board instead of a new draft.
  • use_figma requires the plugin figma-use skill loaded first; FigJam files reject design-only APIs (figma.createPage, most design node types).