Table of Contents

Mermaid Diagram Export

FlowOrchestrator.Core ships with a one-line exporter that converts a flow's manifest into a Mermaid flowchart definition. The output is plain text that renders directly in any Markdown surface that understands Mermaid — GitHub READMEs and PRs, Notion, Obsidian, Confluence, GitLab, dev.to — without spinning up the dashboard or any other process.

Quick start

using FlowOrchestrator.Core.Diagnostics;

var flow = new OrderFulfillmentFlow();
Console.WriteLine(flow.ToMermaid());

The same extension is available on FlowManifest directly when you hold the manifest without a flow definition wrapper.

Options

MermaidExportOptions exposes four knobs:

Option Default Description
Direction TD Mermaid direction header. TD, LR, BT, RL.
IncludeTriggers true Emits one node per trigger and connects each to the entry steps.
ShowStepTypes true Renders the handler Type as italic text below each step key.
ApplyStyling true Adds classDef blocks so triggers, entry, polling, and loop steps differ.

Worked examples

1. Linear flow

new FlowManifest
{
    Triggers = { ["manual"] = new() { Type = TriggerType.Manual } },
    Steps =
    {
        ["a"] = new() { Type = "TypeA" },
        ["b"] = new() { Type = "TypeB", RunAfter = { ["a"] = [StepStatus.Succeeded] } },
        ["c"] = new() { Type = "TypeC", RunAfter = { ["b"] = [StepStatus.Succeeded] } }
    }
}
.ToMermaid();
flowchart TD
    classDef trigger fill:#e1f5ff,stroke:#0288d1
    classDef entry fill:#c8e6c9,stroke:#388e3c
    classDef polling fill:#fff9c4,stroke:#f57f17
    classDef loop fill:#f3e5f5,stroke:#7b1fa2

    T_manual["⚡ manual<br/>Manual"]:::trigger
    a["a<br/><i>TypeA</i>"]:::entry
    b["b<br/><i>TypeB</i>"]
    c["c<br/><i>TypeC</i>"]

    T_manual --> a
    a -- Succeeded --> b
    b -- Succeeded --> c

2. Fan-out / fan-in

A single root branches into three workers that join at a single leaf.

flowchart TD
    root["root"]:::entry
    a["a"]
    b["b"]
    c["c"]
    join["join"]

    root -- Succeeded --> a
    root -- Succeeded --> b
    root -- Succeeded --> c
    a -- Succeeded --> join
    b -- Succeeded --> join
    c -- Succeeded --> join

3. Polling step

When a step's Inputs carries pollEnabled = true, the exporter applies the polling class so it stands out from regular steps.

flowchart TD
    fetch["fetch_orders"]:::entry
    submit["submit_to_wms<br/><i>CallExternalApi</i>"]:::polling

    fetch -- Succeeded --> submit

4. ForEach loop

LoopStepMetadata becomes a Mermaid subgraph containing the child steps.

flowchart TD
    fetch["fetch_orders"]:::entry
    process_each["process_each_orders"]:::loop
    fetch -- Succeeded --> process_each

    subgraph subgraph_process_each["🔁 process_each_orders (ForEach)"]
        validate["validate"]
    end

    process_each --> subgraph_process_each

Using it from the dashboard

Open any flow's detail page, switch to the Mermaid tab, and click Copy Mermaid. The same content is also available via the REST endpoint:

GET /flows/api/flows/{id}/mermaid
Accept: text/plain

Using it from CI

The sample app accepts a --export-mermaid <flowId|flowName> flag that prints the diagram and exits without starting the web host. Wire this into a CI job that comments the new diagram on a pull request whenever a manifest changes:

dotnet run --project samples/FlowOrchestrator.SampleApp -- \
    --export-mermaid OrderFulfillmentFlow > order-fulfillment.mmd