new
Sequence diagram: Native rendering for the sequence family
Sequence diagram: the sequence family is now first-class. Lifelines and
actors auto-size to fit their head labels (including multi-line labels via per-line
tspan), foot bars render by default to close the diagram, lane pitch is
computed per-pair so self-message arcs grow to fit their label and clear the source
lifeline, self-message U-shapes render with rounded interior corners, the lifeline
header band is treated as a label-placer obstacle so first-message labels never dip
into the header zone, and async messages emit an open arrowhead. The new
sequence.note element anchors over a single lifeline or spans a range,
and containerType: "fragment" with extensions.operands
renders alt-fragment branch dividers with their guard text protected from label
collisions.
new
Examples library launches at /examples
The new /examples library showcases agent-native diagram workflows with
before/after revision diffs, CI/CD recipes, and curated agent artifacts across every
diagram family. The first sequence-diagram showcase walks through an HTTP
/checkout handler request lifecycle (eight lifelines, twelve messages,
an alt fragment around payment retry, and a fire-and-forget queue publish) and shows
the diff a reviewer sees when an agent maintains the diagram alongside the handler.
new
ER diagram: Entities auto-size to fit their declared columns
ER diagram: compartmented entities (er.entity and er.weakEntity
with extensions.columns) grow to fit the longest column row and full row
count whenever the author-declared layout.width or layout.height
is smaller than the intrinsic content size. Declared dimensions act as a floor, not a
cap, so a default 150x60 layout still renders correctly when columns carry long names.
Mirrors the canvas auto-extension semantics.
new
Diagnostics guide agents to declare diagramFamily and avoid origin-stacked layouts
Two new normalizer diagnostics help agents self-correct before the engine reaches
layout. MISSING_DIAGRAM_FAMILY emits when a scene omits the top-level
diagramFamily field and lists the seven valid values in
data.allowedValues. LAYOUT_ABSOLUTE_AT_ORIGIN emits when a
scene declares layoutStrategy: "absolute" but every node sits at
(0, 0), the signature of an agent that meant to omit coordinates and rely on
auto-layout.
new
State machine: Transition labels styled with EVENT [guard] / action typography
State-machine and BPMN transition labels of the form
EVENT [guard] / action now render with three distinct typographic runs
inside one text element: the event in the regular edge weight, the
guard at smaller size and muted colour, and the action italicised. The eye locks
onto the event name first while the guard and action stay legible without dominating
the canvas. Detection is content-based and family-agnostic; plain labels keep their
existing single-style rendering.
new
Architecture: External-system nodes get a distinct visual treatment
Architecture: nodes declared with nodeType: "externalSystem" now render
with a dashed outline and muted fill so third-party services read as clearly outside
the system boundary. Internal services keep their solid fill and crisp outline,
giving readers an immediate visual separation between owned and external components.
new
Diagnostic accepts nested document-root fields
The normalizer now accepts scenes where diagramFamily,
layoutStrategy, or other document-root fields appear nested inside
document or scene, hoists them to the correct location,
and emits an OUTER_FIELD_NESTED diagnostic so the agent learns the
canonical shape. A common authoring slip that previously broke layout selection
now produces a working diagram with a guidance code attached.
improved
Parallel edges with distinct labels fan out across the bundle face
When two or more edges connect the same source-target pair across one rank gap and
at least one carries a label, the layered planner now inflates the bundle endpoints
by the cumulative label-stack height so the existing funnel passes can redistribute
anchors across the inflated face. Labels naturally place at distinct midpoint
positions instead of clustering at one anchor, and the placer succeeds without
further intervention.
improved
Label placer picks minimum-overlap candidate when no clean position exists
The label placer previously fell through to the polyline midpoint whenever every
candidate position overlapped an obstacle, silently bypassing the spatial index and
dumping labels on top of nodes, dividers, and other labels. It now tracks the best
clean candidate and the minimum-overlap candidate in parallel, returning the clean
one when available and otherwise the position that grazes the smallest obstacle area.
Thin features (fragment dividers, header bands) are preferred over thick ones (node
bodies), matching how a human would resolve the conflict.
improved
ER diagram: Leads the playground examples
ER diagram: the playground opens on the ER tab so column-row anchored edges,
Crow's Foot auto-inference, PK fallback routing, and entity auto-sizing are visible
on first paint. Architecture moves to the second slot.
improved
State machine: Diagnostic dedup, fan-in label collapse, orthogonal back-edge U-hook
State-machine diagrams pick up three quality improvements in one pass: duplicate
diagnostic codes are deduped before they reach the agent, fan-in labels at a shared
target collapse onto a single anchor row instead of stacking, and back-edges that
cannot route cleanly drop into the canvas whitespace below all nodes as an
obstacle-aware orthogonal U-hook. The U-hook keeps loopbacks clear of unrelated
shapes instead of arcing through them, matching how mainstream BPMN and state
modellers draw retry edges.
improved
Canvas bottom-padding aligned to industry convention
The canvas now reserves 60 px below the bottom-most rendered element instead of
40 px. Sequence foot bars, ER row bottoms, and workflow terminator events sit
comfortably inside the canvas instead of crowding the lower edge. The constant is
shared between the centering pass and final canvas sizing so the two stay in sync.
improved
Multi-rank fan-out trunks align and shared-label fan-ins merge
When a single source spawns several edges that travel across more than one rank
before splitting, the router now aligns their initial trunk segments so the group
reads as one bus rather than a frayed broom. Conversely, edges that share a label
and converge on a single target merge into one trunk before terminating, giving
hub patterns and shared-event fan-ins the visual coherence they had on simple
source-target pairs.
improved
Canvas size adapts to layout aspect ratio
The canvas-tightening pass now respects the natural aspect ratio of the laid-out
content instead of producing fixed-shape backgrounds. Tall state machines no longer
waste horizontal space and wide workflows no longer truncate; the canvas snaps to
the shape the content wants. A single source of truth drives both the centering
pass and the final canvas dimensions so the two never diverge.
improved
Frame and lane titles use muted typography with knockout backgrounds
Generic frames and lane headers now render with smaller, muted title typography so
the frame reads as ambient context rather than competing with its contained nodes.
The title text knocks out the frame border behind it so the label is never bisected
by an outline stroke. Applied uniformly across themed and no-theme renders.
improved
Generic edges default to a target-end triangle arrowhead
Edges authored without an explicit style.arrowhead now render with a
filled target-end triangle by default. Agents that omit the field get the
direction-conveying arrowhead readers expect on flow diagrams, while agents that
set arrowhead: "none" or pick a different style keep full control.
improved
Node labels gain breathing room and parallel-bundle labels stagger along the path
Default node label padding moved from 12 px to 14 px so text sits with visible
margin inside the shape rather than crowding the outline. The label placer now
treats sibling edges as obstacles and staggers parallel-bundle labels along the
path so two-edge bundles that share a midpoint no longer drop both labels on the
same coordinate.
improved
UI flow: Card anchors skip the title-bar seam and contrast meets WCAG AA
UI flow: card screens narrow the funnel anchor span on east and west faces so
edges no longer exit through the title-bar seam, and the polish bundle lifts text
and outline contrast to WCAG AA across the family. Default arrowheads, shape-core
targeting, and title font alignment land in the same pass so authored UI flows
render with consistent typography and clearly-anchored connections.
fixed
Asymmetric layouts no longer pin against the bottom canvas edge
The canvas-centering pass can now shift content upward when the planner placed it
low. Previously a defensive clamp refused negative shifts, so asymmetric workflows
and state machines (where one branch fans further than the others) ended up with a
huge top margin and almost no bottom margin. With the clamp removed, an 18-state
workflow that rendered with an 824 px top margin and a 207 px bottom margin in a
1600 px canvas now renders centred at 515 px on each side.
fixed
Workflow: Decision diamonds render labels inside the shape
Workflow: decision diamonds authored as workflow.decision place their
label inside the shape, matching generic flowchart convention. Previously the label
floated below the diamond because the renderer grouped workflow.decision
with the BPMN-spec gateway types, which intentionally reserve label space outside
the shape for their marker glyphs. The four workflow.gateway* types
keep their external-label BPMN treatment, and agent guidance across MCP and the docs
nudges toward workflow.sequenceFlow for directional edges and
workflow.decision for plain decision diamonds.
fixed
Sub-pixel residual segments removed from routed edges
Edge paths now run through simplifyPath after the funnel and
channel-routing passes, so sub-pixel interior segments produced when source-funnel
and target-funnel shifts collide are collapsed before the renderer sees them.
Previously a hairline residual could survive to the SVG output, misorienting an
arrow marker or producing a barely-visible bent path.
fixed
Back-edges no longer clip the canvas top and stay anchored on shared faces
The canvas now includes routed edge polylines when computing its bounds, so
back-edges and U-hooks that arc above the top-most node no longer get sliced by
the canvas edge. The same pass keeps anchor bounds in step with shape bounds
during the centering shift, so when two or more edges share a target face the
terminal segments stay pinned to the shape perimeter instead of drifting tens of
pixels off the target. Visible on dense state-machine and architecture diagrams
where multiple edges converge on the same node.
fixed
Edges no longer graze the outlines of unrelated nodes
The router's obstacle-grazing detection now treats sibling node outlines as hard
boundaries, so a candidate path that touches a neighbouring shape's edge is
rejected before it reaches the renderer. Previously a path could clip a neighbour
by a fraction of a pixel and pass the cleanliness check, leaving the edge
appearing to enter and exit through an unrelated node.
breaking
Sequence diagram: sequence.note centres over the named lifeline
Sequence diagram: a sequence.note with a single
extensions.anchor value now centres OVER the named lifeline instead of
placing to the right of it. The previous 'right of' contract was idiosyncratic and
produced broken output for notes anchored to the right-most lifeline (they hung off
the canvas edge, forcing auto-extension). Multi-anchor span semantics
(extensions.anchor: ["a", "b"]) are unchanged. Authors who relied on
the old offset should switch to a multi-anchor span or move the anchor.
breaking
@zindex-ai/mcp is now a thin HTTP client
The @zindex-ai/mcp npm package now talks to api.zindex.ai
exclusively. Local mode is removed and ZINDEX_API_KEY is required for
every tool call. Bundle size drops from 802 KB to 38 KB, agents always get
persistence and revision history through dsp_create_scene, and the
hosted state platform is the single source of truth. Set
ZINDEX_API_KEY in your MCP host config; ZINDEX_API_URL
defaults to the production host.