Skip to content

v1.0.0

2026-06-30 · GitHub release · Diff

Major milestone release and first release under the seqeralabs GitHub organisation. 300+ commits since 0.7.2. The .mmd input format is backward compatible - existing files render without edits (many will look better thanks to the routing work below).

nf-metro now supports all four Mermaid graph directions: LR, RL, TB, and BT. Previously only LR and TB were supported; RL and BT are their respective mirrors, with full routing vocabulary for fold sections, bypass-V, convergence sinks, and perpendicular entries.

The majority of the code change in this release is engine work, and most of it is structural rather than a list of isolated fixes. Three large programs ran across the cycle, then a focused fold-routing sprint closed it out.

Centreline-builder unification. Edge routing was consolidated onto a single centreline builder that owns corner anchoring and tapering for every route family - entry-wrap, perpendicular-exit up-and-over, U-shaped bypass, TOP-entry staircase, fan L-shapes, and inter-section bundles. What used to be scattered per-case path construction now flows through one declarative inter-section dispatch table and one builder, so curves are correct by construction rather than patched after the fact (#791-#814, plus the #845 symbolic gap-slot model).

Direction-agnostic layout (AxisFrame). Layout heuristics that were written against hardcoded "TB" string checks were migrated to an AxisFrame abstraction with lane accessors and a single offset-regime applier, and the core handlers adopted a Direction enum. This is what made the new RL and BT directions tractable: every routing handler now operates on one canonical orientation, and the per-direction special cases were retired. The LR/TB rotation model was extended so RL and BT are derived by mirroring at the seam-classifier layer (#918-#922, #1029-#1049).

Robustness hardening. A gate-arm triage pass gave every un-exercised branch in the layout and routing modules a verdict - reachable (with a new fixture), defensive, or a filed bug - and the inter-phase state shared between layout stages was formalised into an explicit protocol. A guard registry with a cost audit and golden baseline now reds CI the moment a layout regresses (#687, #673, #921).

Fold-threshold routing. Folded sections (where a line wraps across a column boundary) got the most targeted-fix work, late in the cycle. The keystone: fold-back routes that cannot be drawn cleanly now raise a FoldThresholdError and are treated as an authoring constraint rather than emitting broken geometry (#1088). On top of that gate:

  • Perpendicular-entry fans slot onto parallel approach channels by feeder order instead of overlapping (#1144).
  • Folded LEFT-exit staircase bundle ordering and concentric nesting (#1143, #1161).
  • Folded bbox bottom aligns to the target section’s settled content bottom, not its live bounding box, preventing balance drift on tall fold targets (#1162).
  • Tight 1-row folds no longer leave a visible run-out stub on the bypass-V (#1177).
  • Same-side cul-de-sac entry re-anchors the interior-consumer port instead of routing around it, removing a whole class of U-route generation (#1182).
  • Opposing-line fold-backs under fold compression raise FoldThresholdError rather than tangling (#1187).
  • Convergence-sink ports no longer face the wrong section after fold relocation (#1167).
  • Disconnected components renormalise grid rows after stacking, preventing section overlap (#1164).
  • Corridor-fed single-line sections re-centre instead of drifting off-trunk (#1173); same-column RIGHT-entry corridor descent no longer jogs before dropping (#1178).
  • TB-section bypass-V seats on the line’s lane-side grid column, not a fixed offset (#1163); the post-bypass settling pass runs in both validate modes (#1171); convergence-split placement is deterministic across runs (#1168).

Spacing and symmetry.

  • Symmetric 2-way diamonds compact to half pitch through the grid-snap, halving wasted horizontal space (#1076).
  • Upright (TB/BT) label and icon spacing derives from the AxisFrame rather than hardcoded "TB" checks (#1043).
  • Light theme line width corrected to match OFFSET_STEP (4 px -> 3 px) (#1073).

Ball animations switch from SMIL <animateMotion> to CSS offset-path. SMIL is disabled in some host environments and causes SVG-in-HTML embedding issues; offset-path works reliably across all modern browsers.

Brand (nfcore, seqera) and display mode (light, dark) are now independent. A single rendered SVG carries both palettes via CSS light-dark() and adapts to the viewer’s color-scheme automatically. Logo assets also adapt per color-scheme with no extra directives required.

A stable Python API:

from nf_metro.api import render_string, RenderConfig
svg = render_string(
graph_text,
theme="nfcore",
mode="dark",
config=RenderConfig(embed_font=True, responsive=True),
)

render_string is the one-call entry point. RenderConfig is a typed dataclass bundling the render-side output options (font embedding, responsive viewBox, class prefixes, color-scheme handling) for callers who prefer a config object over keyword arguments. The render-many CLI command batch-renders a JSON manifest of jobs in a single process, amortising interpreter and import startup across the whole corpus.

Every render now carries a machine-readable JSON manifest - station visual centres, pill dimensions, and line metadata - factored into a dependency-free nf_metro.manifest package and documented as a standard. This is what lets nf-metro serve accept a previously rendered SVG as input, and it gives host systems a stable way to map screen coordinates back to graph elements (#623).

Renders can embed the Inter font or convert text to vector paths, so maps display identically whether or not the host has the font installed - important for SVGs that travel into PDFs, slides, and other documents (#839).

Live workflow visualisation (nf-metro serve)

Section titled “Live workflow visualisation (nf-metro serve)”

nf-metro serve connects to a running Nextflow workflow and renders a live metro map in the browser, updating as processes progress. New in this release:

  • SVG input - accepts a previously rendered SVG (with embedded manifest) instead of a .mmd source.
  • auto_process mapping - %%metro auto_process: true and process_scope: collapse a Nextflow DAG into a lean process-level map automatically.

A browser-based editor powered by Pyodide runs the full Python engine client-side - edit .mmd source, see the map update live. Features: example dropdown, Nextflow DAG import, graphical topology editing, zoom controls, brand/mode toggles, gzip-compressed share URLs, and a service-worker cache so the Pyodide runtime loads instantly after the first visit.

Rebuilt in Astro / Starlight with a Seqera-branded theme, replacing MkDocs-Material. Metro maps render live at build time; the <Metro> component presents source, CLI command, and rendered map as a three-panel toggle. Versioned docs with an in-page version switcher, Pagefind full-text search, ZoomableSVG lightbox, color-chip swatches in code blocks, and link validation in CI.

  • 3-way parallel test split with pytest-split to cut CI wall-clock time.
  • Python 3.10 dropped (EOL); minimum is now Python 3.11.
  • All GitHub Actions refs pinned to full commit SHAs (seqeralabs org policy).
  • Incremental render-diff: PR previews only re-render changed fixtures.