This file provides guidance to AI code assistants when working with code in this repository.
mmdflux is a Rust CLI tool and library that parses Mermaid diagrams and renders them as text (Unicode/ASCII), SVG, or MMDS JSON. Supported diagram types: flowchart, class, sequence. It converts Mermaid syntax into terminal-friendly visualizations using Unicode box-drawing characters, with support for multiple layout directions (TD, BT, LR, RL), node shapes, edge styles, subgraphs with direction overrides, and structured JSON output (MMDS format).
This project uses Conventional Commits, enforced by cocogitto via a commit-msg git hook.
Format: <type>(<optional scope>): <subject>
Types: feat, fix, perf, revert, docs, test, build, ci, refactor, chore, style
Scopes: wasm, xtask, web, mmds-core, mmds-excalidraw, mmds-tldraw (match monorepo packages). Omit scope for changes to the root mmdflux crate.
Rules:
- Header must be 100 characters or fewer
- Subject must start with a lowercase letter
- Subject must not end with a period
- Use imperative mood ("add feature" not "added feature")
For non-trivial changes, include a body after a blank line explaining what changed and why. A one-liner is fine for truly simple changes (typo fixes, version bumps), but multi-file changes, bug fixes, and new features should have a body.
Use cog check to validate commit history and cog changelog to preview changelog output. Use git commit (not cog commit) for creating commits — the commit-msg hook handles validation automatically.
This project uses Conventional Branch, enforced by a pre-push git hook.
Format: <type>/<description>
Types: feat/, fix/, hotfix/, release/, chore/
Rules:
- Use lowercase letters, numbers, and hyphens only (no underscores or spaces)
- Include issue numbers when applicable (e.g.,
feat/issue-42-add-svg-export) - Keep descriptions concise (e.g.,
fix/lr-routing-regression)
When fixing a GitHub issue:
- Read the issue and comments:
gh issue view <N> --comments - Create a conventional branch:
fix/descriptionorfeat/description - Keep PRs as a single commit — squash before merging, use
git push --force-with-leasewhen iterating - Reference the issue in the commit body:
Closes #N - Post findings back to the issue with
gh issue comment <N>when investigation reveals useful context
Use just (see Justfile) for day-to-day work. Tests use cargo-nextest for parallel execution.
just test # Run all tests (nextest, parallel)
just test-file integration # Run a specific test file
just test -E 'test(test_name)' # Run a specific test (nextest filter)
just lint # clippy + fmt check
just check # lint + test + architecture
just build # Debug build
just release # Release build
just architecture-host # Host a semantic architecture lint server
just architecture-check # Run the architecture linter
just run diagram.mmd # Run the CLI
just fmt # Format code
# Run CLI directly
cargo run -- diagram.mmd
cargo run -- --debug diagram.mmd
cargo run -- --ascii diagram.mmd
echo 'graph LR\nA-->B' | cargo runSee docs/architecture/dependency-rules.md for the authoritative module ownership rules and public contract tiers. The repo-owned architecture gate is cargo xtask architecture check or just architecture-check. Semantic module boundaries are enforced from boundaries.toml (override with SEMANTIC_BOUNDARIES_CONFIG); run cargo xtask architecture check or just architecture-check for the semantic dependency check.
When editing imports, top-level wiring, or ownership boundaries, run
cargo xtask architecture check before finishing. During larger boundary
refactors, keep just architecture-host running in a separate terminal.
Inspection commands:
just architecture-graph— print dependency graph as Mermaidjust architecture-explain --edge <source> <target>— inspect a specific edgejust architecture-explain --boundary <name>— inspect a boundary
Pipeline: Frontend → Diagrams → Engine → Render
Input Text → frontends.rs (detect frontend: Mermaid or MMDS)
→ mermaid/ (parse to AST) → diagrams/ (compile to IR, build payload)
→ runtime/ (orchestrate: registry → engine → render dispatch)
→ engines/ (solve graph layout → GraphGeometry)
→ render/ (emit Text/SVG/MMDS output)
- Runtime facade:
render_diagram,detect_diagram,validate_diagram+RenderConfig,OutputFormat,RenderErrorre-exported fromlib.rs - Low-level API:
builtins,registry,payload,graph,timeline,mmdsfor adapter-oriented workflows - Internal implementation:
diagrams,engines,render,mermaid— documented for contributors but not part of the supported contract
Test fixtures are organized by diagram type:
tests/fixtures/flowchart/*.mmd— flowchart fixturestests/fixtures/class/*.mmd— class diagram fixturestests/fixtures/sequence/*.mmd— sequence diagram fixtures
Snapshots follow the same structure: tests/snapshots/flowchart/*.txt, tests/svg-snapshots/flowchart/*.svg.
Key test files:
tests/integration_full.rs— full-pipeline rendering teststests/compliance_class.rs— class diagram compliancetests/compliance_sequence.rs— sequence diagram compliancetests/mmds_json.rs— MMDS JSON contract teststests/svg_render.rs— SVG rendering teststests/cli.rs— CLI integration testscargo xtask architecture— repo-owned architecture policy enforcementsrc/internal_tests/— crate-local cross-pipeline tests (engine + routing + render)
The xtask architecture command enforces the semantic boundary rules in
docs/architecture/dependency-rules.md. boundaries owns semantic top-level
dependency policy across production and test code.
Text and SVG snapshots are checked into the repo. Each diagram type has its own env var and test target. Regenerate only the type you changed:
# Flowchart
GENERATE_TEXT_SNAPSHOTS=1 cargo nextest run -E 'test(generate_baseline_snapshots)'
GENERATE_SVG_SNAPSHOTS=1 cargo nextest run -E 'test(svg_snapshot_all_fixtures)'
# Class
GENERATE_CLASS_TEXT_SNAPSHOTS=1 cargo nextest run --test compliance_class -E 'test(class_text_snapshots)'
GENERATE_CLASS_SVG_SNAPSHOTS=1 cargo nextest run --test compliance_class -E 'test(class_svg_snapshots)'
# Sequence
GENERATE_SEQUENCE_TEXT_SNAPSHOTS=1 cargo nextest run --test compliance_sequence -E 'test(sequence_text_snapshots)'The project includes tooling to compare mmdflux layout against dagre.js v0.8.5.
./scripts/setup-debug-deps.sh # Clone dagre and mermaid to deps/cargo nextest run -E 'test(dagre_parity)' # Compare layout against dagre.js fixtures./scripts/refresh-parity-fixtures.sh # Regenerate from dagre.jsLibrary code emits tracing events but does not install subscribers. The CLI
and xtask own subscriber setup.
--log <FILTER>- Enable CLI tracing with atracing_subscriber::EnvFilterdirectiveMMDFLUX_LOG=<FILTER>- Enable CLI tracing when--logis absentRUST_LOG=<FILTER>- Fallback tracing filter for CLI andxtask--log-format <compact|pretty|json>- Select tracing format (compactby default)--log-file <path>- Write tracing output to a file instead of stderrMMDFLUX_XTASK_LOG=<FILTER>- Enablextasktracing when its--logis absent
Common target filters:
MMDFLUX_LOG=mmdflux::runtime=debug- Render facade timing and outcomeMMDFLUX_LOG=mmdflux::engines::graph::algorithms::layered::kernel=trace- All layered-kernel diagnosticsMMDFLUX_LOG=mmdflux::engines::graph::algorithms::layered::kernel::order=trace- Order diagnosticsMMDFLUX_LOG=mmdflux::engines::graph::algorithms::layered::kernel::bk=trace- Brandes-Köpf diagnosticsMMDFLUX_LOG=mmdflux::engines::graph::algorithms::layered::kernel::border=trace- Border/subgraph diagnosticsMMDFLUX_LOG=mmdflux::engines::graph::algorithms::layered::kernel::parent_dummy_chains=trace- Dummy-parent diagnosticsMMDFLUX_LOG=mmdflux::graph::grid::routing=trace- Route-segment diagnostics
These env vars produce deterministic files or parity text and are intentionally not replaced by subscriber formatting:
MMDFLUX_DEBUG_LAYOUT=1|<file>- Write one compact layout JSON documentMMDFLUX_DEBUG_PIPELINE=1|<file>- Write pipeline stages as JSONL; file mode appendsMMDFLUX_DEBUG_BORDER_NODES=1- Print border-node parity trace to stderrMMDFLUX_DEBUG_SVG_THEME_AUTO=<file>- Write/truncate the SVG auto-theme probe transcript
Behavior-changing debug switches are separate from tracing. Do not add new behavior modifiers as tracing controls.
scripts/dump-dagre-layout.js- Run dagre.js layoutscripts/dump-dagre-pipeline.js- Trace dagre pipeline stagesscripts/dump-dagre-borders.js- Extract dagre border nodesscripts/dump-dagre-order.js- Dump node order per rank
See docs/development/mermaid-parity.md for comprehensive parity and debug documentation.