Handle ids are the ports serialized as node_id.port edge endpoints,
matching the success/outcome/error routing executed in src/graph/engine.rs
and declared in src/plugins/ports.rs. input/output/error are the
supernode boundary pseudo-nodes (src/graph/expand.rs) alongside
listener/client; they are not catalog types, so their handle counts fall
back to the hard-coded shapes in ../nodeKinds rather than reading
data.ports.
Renders one plugin node on the canvas.
Handle layout encodes the port model (see
../nodeKindsfor the shared entry/terminal classification and output resolution):in(left, target) — omitted on entry-like nodes (listener,input).client,output,error, none of which get asuccessoutput either); a singlesuccesshandle on entry-like nodes (listenerreads its own catalog spec, which happens to be exactly onesuccessport; the non-cataloginputpseudo-node uses a hard-coded fallback of the same shape); otherwise one handle per port declared indata.ports.outputs(falling back to the default success+error pair when the type has no catalog entry), colored by PortDecl.kind. Whendata.showPortNamesis notfalse(the default), each port renders as a labeled row inside the node body, with its handle centered on the row; otherwise handles fall back to the previous evenly-spaced absolute placement with only a hover tooltip.Clicking the node invokes
data.onSelect(id); selection is shown with an accent border and ring.