Skip to content

v0.43.0

Choose a tag to compare

@github-actions github-actions released this 28 Jul 16:29
· 79 commits to master since this release
38e5031

[0.43.0] - 2026-07-28

Chore

  • Bump version to 0.43.0 (release)

Other

  • Fix text overflow in plain UML state-machine simple states

UmlState fell through UmlContentSizeProvider's else-branch to the fixed
160x80 default, and renderUmlState always drew the name on one line —
long names like "Antragsvorschlag Eingereicht auf Agora-Platform" ran
past the rounded box border. Simple states now wrap the name at word
boundaries and center the resulting block; box height grows to fit when
needed. Composite states are unaffected (ELK sizes those from their
substates).- Expose the SVG watermark option through the kuml-web render API

WebRenderPipeline already threaded widthPx/standaloneTex/notation but had
no way to opt into the "Powered by kUML" watermark that the CLI's
--watermark flag already supports. Added the same watermark parameter to
render() and every SVG-producing branch (UML, C4, all SysML 2 diagram
types, BPMN, ERM), mirroring kuml-cli/RenderPipeline.kt's existing support
matrix. Blueprint is intentionally excluded, matching the CLI. Exposed as
RenderRequest.watermark (default false) on POST /api/render.

This unblocks obsidian-kuml exposing a "Show kUML watermark" setting that
works identically whether it renders via the CLI or the kuml-web server.- Fix watermark rendering outside the frame on UML state diagrams

Plain UML state diagrams draw their outer "frame" through a different
path than every other diagram type: renderUmlStateDiagram treats the
UmlStateMachine as a layout group and sizes its frame to the group's own
content bounds, never going through SvgDocument.render's generic
renderDiagramFrame (frameName/frameTypeLabel aren't passed for
DiagramType.STATE). That generic frame is the only place that already
accounts for the watermark band added to canvasH, so the state-machine
frame stopped short of it — leaving "Powered by kUML" positioned near
the true canvas bottom, visibly below/outside the frame's border.

Fixed by stretching the state-machine frame's bottom edge down to
canvasH - DIAGRAM_FRAME_INSET_PX when the watermark is on (same edge
clearance the generic frame already uses), recomputing canvasH locally
from the same inputs SvgDocument.render itself uses since it isn't
threaded into this populate callback. WATERMARK_BAND_PX and the frame's
2px inset are now internal constants shared between the two files
instead of each being a private/local literal, so both frame mechanisms
stay in sync if either value changes.

Verified: watermark now renders inside the frame for a reconstructed
multi-branch state diagram; the same diagram rendered without
--watermark is byte-for-byte identical to before this change.- Fix activity diagram guard labels overflowing the frame

Plain UML ACTIVITY diagrams had no protection against a long decision-
edge guard label running past the outer frame's border — unlike state
machines, which already got this fix via umlStmWidenForLabelOverhang,
nothing widened the canvas for activity edges' [guard] text.

Added umlActivityWidenForGuardOverhang, wired into effectiveLayoutResult
for DiagramType.ACTIVITY. Unlike the state-machine version, activity
diagrams draw their frame the generic way (SvgDocument.render's
renderDiagramFrame spans the canvas directly), so there's no separate
frame rect to resize — growing the canvas width and shifting content
right by the overflow found on the left is enough; the wider frame
follows automatically from the new canvas width.

Verified against a reconstructed diagram with a long guard
("has BackupDelegateFunction AND OrdinaryDelegateFunction for this
BackupDelegateFunction") — it now renders entirely inside the widened
frame. A normal-length-guard activity diagram renders byte-for-byte
identical to before this change (confirmed via git stash A/B render).- Fix overlapping back-edge lines and labels in UML state diagrams

A state with several back-edges converging on it from below (e.g. three
different "E-Mail sent successful" transitions into the same waiting
state) rendered with the near-parallel return lines only a few px
apart, and their trigger-text labels overlapping into illegible glyph
soup — reported against a real "Becoming Contact WABEO" state machine.

Two contributing causes, both fixed:

  1. ELK's edge-to-edge spacing for STATE diagrams (RenderPipeline.kt) was
    36f — not enough room for many parallel back-edges converging on one
    state. Bumped to 56f.

  2. The real bug: back-edge labels got no collision detection at all.
    umlStmTransitionLabelAnchor anchors every back-edge label at a fixed
    8%-of-arc-length point near its source (existing fix, keeps labels
    off intermediate states) — but it applied that override after
    umlStmComputeLabelStackAssignments had already clustered labels using
    each edge's natural longest-segment midpoint, which for back-edges
    can sit far from where the label actually renders. Back-edges whose
    real anchors land within a few px of each other therefore never got
    detected as overlapping, so none of them received the stacking offset
    that normally separates colliding labels.

    Fixed by computing each STM edge's effective anchor (the back-edge
    override where applicable, natural anchor otherwise) once, in a new
    umlStmEffectiveAnchor, and feeding that into clustering instead of the
    raw route. Sysml2EdgeRenderer gained
    computeLabelStackAssignmentsFromAnchors, an anchor-input overload of
    the existing route-input computeLabelStackAssignments (which now just
    delegates to it) — REQ/ACT/PAR/UC callers are unaffected, byte-for-
    byte identical to before.

Verified against a reconstruction of the reported diagram: every
back-edge label now renders on its own clear line. A simple state
diagram with no back-edges (order-lifecycle) renders correctly with no
visual regressions (spacing widened intentionally, no other change).