Skip to content

den.lib.diag

The diagramming library provides a composable pipeline for rendering aspect-resolution graphs: trace capture collects structured trace entries from resolved aspects, graph construction builds a format-agnostic IR, filters prune and reshape the IR, and renderers emit Mermaid, DOT, PlantUML, or JSON strings.

See Diagrams explanation for concepts and usage patterns.

High-level entry points that resolve an entity and return a graph IR in one call.

hostContext { host, classes?, direction? }

Section titled “hostContext { host, classes?, direction? }”

Build a host-scoped graph. When classes is omitted, auto-discovers from [ "nixos" "homeManager" "user" ] plus each user’s declared classes. Returns the graph IR plus rootAspect, pathSets, and classes.

userContext { host, user, classes?, direction? }

Section titled “userContext { host, user, classes?, direction? }”

Build a user-scoped graph. Defaults to [ "homeManager" "user" ] plus the user’s own classes.

homeContext { home, classes?, direction? }

Section titled “homeContext { home, classes?, direction? }”

Build a home-scoped graph. Defaults to [ "homeManager" ] plus the home’s own classes.

context { root, name, classes, direction? }

Section titled “context { root, name, classes, direction? }”

Generic entry point for any entity kind. root is a resolved stage (from den.lib.resolveStage), name is used as the graph root label, and classes lists the aspect classes to trace. direction defaults to "LR".

root = den.lib.resolveStage "user" { inherit host user; };
g = diag.context { inherit root; name = user.name; classes = [ "homeManager" ]; };

graph.build { entries, rootName, ctxTrace?, direction? }

Section titled “graph.build { entries, rootName, ctxTrace?, direction? }”

Core IR builder. Transforms a list of structured trace entries into a graph record containing nodes, edges, stages, stageEdges, rootId, rootName, and direction. This is the lowest-level constructor — convenience wrappers call it internally.

Thin wrapper around hostContext that strips auxiliary fields (rootAspect, pathSets, classes), returning a plain graph record.

graph.ofNamespace { name?, aspects?, direction?, filter? }

Section titled “graph.ofNamespace { name?, aspects?, direction?, filter? }”

Static namespace graph built from den.aspects declarations (no host resolution). Walks authored building blocks and their static inclusions. Useful for fleet-level views showing the full aspect catalogue.

All filters are available on the graph attrset (e.g., diag.graph.aspectsOnly). Each takes a graph IR and returns a new graph IR.

FilterSignatureDescription
userDeclaredOnlygraph -> graphNodes with hasClass = true — user-authored aspects only
pipelineOnlygraph -> graphWrapper/plumbing nodes only — reveals resolution machinery
crossClassOnlygraph -> graphNodes contributing to 2+ classes — bridge aspects
orphansAndLeavesgraph -> graphNodes with no incoming edges (orphans) or no outgoing edges (leaves)
FilterSignatureDescription
classSlicestring -> graph -> graphAncestor closure from nodes active in the given class
neighborhoodOf(node -> bool) -> graph -> graphNodes matching predicate plus their direct neighbors
adaptersOnlygraph -> graphNodes with resolution handlers plus neighbors
parametricOnlygraph -> graphParametric aspects (isParametric = true) plus neighbors
FilterSignatureDescription
contextOnlygraph -> graphContext pipeline stages as nodes, aspect content discarded
aspectsOnlygraph -> graphUser aspects with context wrappers folded out, provider edges dropped
providersOnlygraph -> graphProvider hierarchy as a multi-level tree
providersResolvedgraph -> graphProviders alongside their resolved output nodes
decisionsViewgraph -> graphStructural decisions — excluded nodes grouped by adapter owner
FilterSignatureDescription
foldWrappersgraph -> graphRemove wrapper/context nodes, rewire edges to their children
foldProvidersgraph -> graphCollapse provider chains into single edges
flattenStagesgraph -> graphRemove stage subgraph grouping
FilterSignatureDescription
filterMeaningfulgraph -> graphDrop anonymous and definition-stub nodes
filterUserAspectsgraph -> graphfoldWrappers composed with filterMeaningful
simplifiedgraph -> graphfoldProviders + flattenStages + aspectsOnly
FunctionSignatureDescription
fanMetricsgraph -> [{ id, label, fanIn, fanOut, total, ... }]Fan-in/fan-out counts per node, sorted by total
diff{ a, b } -> graphMerge two graphs with origin tags ("a", "b", "both") on each node and edge
FilterSignatureDescription
hasAspectPresent{ class } -> graph -> graphNodes answering hasAspect = true for the given class (ancestor closure)
hasAspectForAnyClass[string] -> graph -> graphUnion of hasAspectPresent across multiple classes

Every renderer has two forms: toFoo uses the default theme and toFooWith { theme?, mermaidConfig? } accepts explicit options. All take graph -> string (or fleetData -> string for fleet renderers).

RendererFormatNotes
toMermaid / toMermaidWithMermaid flowchartPrimary renderer; supports ELK layout via mermaidConfig
toDot / toDotWithGraphviz DOTNo mermaidConfig option
toPlantUML / toPlantUMLWithPlantUMLNo mermaidConfig option
RendererFormatNotes
toSequenceMermaid / toSequenceMermaidWithMermaid sequenceStage sequence diagram
toSequenceMermaidExpanded / toSequenceMermaidExpandedWithMermaid sequenceExpanded with per-aspect detail
toPolicySequenceMermaid / toPolicySequenceMermaidWithMermaid sequencePolicy-level sequence
toStageEdgesMermaid / toStageEdgesMermaidWithMermaidStage topology edges
RendererFormatNotes
toC4Component / toC4ComponentWithPlantUML C4Component diagram
toC4Container / toC4ContainerWithPlantUML C4Container diagram
toC4Context / toC4ContextWithPlantUML C4Context diagram (fleet-level)
toC4ComponentMermaid / toC4ComponentMermaidWithMermaid C4Component diagram
toC4ContainerMermaid / toC4ContainerMermaidWithMermaid C4Container diagram
toC4ContextMermaid / toC4ContextMermaidWithMermaid C4Context diagram
RendererFormatNotes
toSankeyMermaid / toSankeyMermaidWithMermaid sankeyAspect flow
toFleetSankeyMermaid / toFleetSankeyMermaidWithMermaid sankeyFleet-wide flow
toFanMetricsSankey / toFanMetricsSankeyWithMermaid sankeyFan-in/fan-out metrics
RendererFormatNotes
toTreemapMermaid / toTreemapMermaidWithMermaidAspect treemap
toFleetTreemapMermaid / toFleetTreemapMermaidWithMermaidFleet-wide treemap
toFleetProviderMatrix / toFleetProviderMatrixWithMermaidProvider matrix across hosts
RendererFormatNotes
toMindmapMermaid / toMindmapMermaidWithMermaid mindmapAspect mindmap
toStateMermaid / toStateMermaidWithMermaid stateState diagram
toJSONJSONGraph IR serialized to JSON (no theme)

Factory that returns an attrset of all pre-configured renderers. Each key is a toFoo function with the given theme/config baked in. Includes toJSON.

Hard-coded github-light palette. No pkgs required — the library is usable without running any build-time tools.

Build a theme from a base16 palette. Converts the YAML scheme to JSON via yj at build time.

theme = diag.themeFromBase16 { inherit pkgs; scheme = "catppuccin-mocha"; };

Build a theme from a raw palette attrset ({ base00, base01, ..., base0F }).

Low-level helper: returns the raw { base00, ..., base0F } palette without wrapping it in a theme record.

A theme record contains: palette, background, foreground, mutedForeground, nodeBg, nodeBorder, nodeText, clusterBg, clusterBorder, edgeColor, edgeText, labelBg, rootFill, rootStroke, rootText, excludedFill, excludedStroke, excludedText, replacedFill, replacedStroke, replacedText, and accentPool (list of 8 accent colors used by per-node color hashing).

Build fleet-wide data from the host registry. hosts defaults to den.hosts; flakeName defaults to "den flake".

Returns:

FieldTypeDescription
flakeNamestringDisplay name for the fleet
hosts[{ name, description }]Host records (description is the system string)
users[{ name }]Deduplicated user records across all hosts
relations[{ from, to, label }]User-to-host edges labeled with class names
providerSubAspects[{ provider, subAspect, hostName }]Lazily evaluated provider sub-aspects per host

renderContext { pkgs, theme?, mermaidConfig?, mermaidCli?, renderFonts?, fontFamily? }

Section titled “renderContext { pkgs, theme?, mermaidConfig?, mermaidCli?, renderFonts?, fontFamily? }”

Factory that builds a record carrying everything needed to render views. Wires up SVG infrastructure and pre-configured renderer sets.

Returns:

FieldDescription
renderRenderer set with default theme (no mermaidConfig)
renderDenseRenderer set with mermaidConfig applied
themeThe resolved theme record
viewsPre-built view definition sets (.core, .host, .user, .home, .fleet, .classViews)
mmdSourceToSvgbase -> source -> derivation — Mermaid source to SVG
pumlSourceToSvgbase -> source -> derivation — PlantUML source to SVG
rc = diag.renderContext { inherit pkgs; mermaidConfig = { layout = "elk"; }; };
rendered = rc.render.toMermaid myGraph;

Utilities for turning view definitions into derivations, packages, and write scripts. Available under diag.export.

entityEntries { pkgs, rc, diag } { entity, name, dir, viewDefs, galleryDrv? }

Section titled “entityEntries { pkgs, rc, diag } { entity, name, dir, viewDefs, galleryDrv? }”

Generate all derivation entries (markdown + SVG) for a single entity. entity must be a pre-computed graph.

fleetEntries { pkgs } { fleetData, viewDefs, galleryDrv? }

Section titled “fleetEntries { pkgs } { fleetData, viewDefs, galleryDrv? }”

Generate all derivation entries for fleet-level views.

entries -> attrset — Convert entry list to a { name = derivation; } attrset suitable for packages.

entries -> [{ path_, drv }] — Convert entries to file records.

mkGallery pkgs { name, dir, title, entries }

Section titled “mkGallery pkgs { name, dir, title, entries }”

Build a gallery markdown file embedding all SVG views for a directory.

mkWriteScript pkgs { entries, galleries?, readmeDrv?, destExpr?, scriptName? }

Section titled “mkWriteScript pkgs { entries, galleries?, readmeDrv?, destExpr?, scriptName? }”

Assemble a shell script that copies all entries and galleries to a target directory. Used by diagram templates to produce a write-diagrams package.

View definitions describe what to compute from a graph IR and how to present it. Each is a list of records with fields: view (identifier), title, altText, mdLang, svgInfix, svgFn, and compute (graph -> string).

Essential views shared by all entity kinds: aspect hierarchy, stage sequence, expanded stage sequence, policy sequence, provider tree, and IR JSON.

Optional extra views: context hierarchy, simplified, stage topology, providers resolved, adapter impact, structural decisions, and user-declared aspects.

views.host rc / views.user rc / views.home rc

Section titled “views.host rc / views.user rc / views.home rc”

Entity-specific view sets. Currently all return views.core rc.

Fleet-wide views: aspect namespace, fleet C4 context (PlantUML), and fleet provider matrix.

Dynamic per-class views. Generates a class-slice view for each class name in the list.

Low-level capture functions used internally by the convenience wrappers. Available at the top level of den.lib.diag.

Capture structured trace entries for a single class. Returns a list of entries.

Capture entries for multiple classes, concatenated.

Returns { entries, pathsByClass, ctxTrace } — entries plus per-class path sets needed by presence filters.

captureWithPathsWith { classes, root, extraHandlers? }

Section titled “captureWithPathsWith { classes, root, extraHandlers? }”

Extended form accepting additional trace handlers.

Contribute Community Sponsor