agentic-mermaid 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +149 -4
- package/LICENSES/Apache-2.0.txt +202 -0
- package/README.md +25 -32
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/assets/fonts/FONT-LICENSES.md +9 -5
- package/assets/fonts/Inter-Bold.ttf +0 -0
- package/assets/fonts/Inter-Medium.ttf +0 -0
- package/assets/fonts/Inter-Regular.ttf +0 -0
- package/assets/fonts/Inter-SemiBold.ttf +0 -0
- package/dist/agent-core.d.ts +463 -0
- package/dist/agent-core.js +397 -0
- package/dist/agent.d.ts +81 -1822
- package/dist/agent.js +336 -36839
- package/dist/agentic-mermaid-mcp.js +7 -37908
- package/dist/am.js +33638 -36261
- package/dist/chunk-4QECACIA.js +4702 -0
- package/dist/chunk-CDPKJ2BQ.js +37 -0
- package/dist/chunk-QKDLMOJJ.js +3487 -0
- package/dist/chunk-WI35L7IR.js +615 -0
- package/dist/chunk-WN3YDOBG.js +149 -0
- package/dist/chunk-ZYMMKQ3I.js +62637 -0
- package/dist/index-D54dqSdC.d.ts +6777 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +310 -32836
- package/dist/mcp-cli-SBQSTJFC.js +17 -0
- package/docs/README.md +14 -6
- package/docs/schemas/style-spec.schema.json +1221 -30
- package/examples/styles/catalog.json +54 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
- package/examples/styles/cupertino-prototype.mmd +10 -0
- package/examples/styles/cupertino-prototype.style.json +63 -0
- package/examples/styles/mid-century-report.style.json +2 -2
- package/examples/styles/star-chart-atlas.style.json +2 -1
- package/examples/styles/transit-route-map.style.json +2 -2
- package/examples/styles/vercel-inspired-prototype.mmd +6 -0
- package/examples/styles/vercel-inspired-prototype.style.json +87 -0
- package/package.json +70 -43
- package/server.json +41 -0
- package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
- package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
- package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
- package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
- package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
- package/AGENT_NATIVE.md +0 -602
- package/Instructions_for_agents.md +0 -83
- package/TODO.md +0 -662
- package/assets/hero.png +0 -0
- package/dist/index-x2Cj1dVv.d.ts +0 -1089
- package/docs/agent-api-cookbook.md +0 -308
- package/docs/agent-mutation-policy.md +0 -104
- package/docs/agent-workflow-examples.md +0 -46
- package/docs/api.md +0 -203
- package/docs/ascii.md +0 -103
- package/docs/assets/improvements/box-start-connector.png +0 -0
- package/docs/assets/improvements/comment-dropped-lint.png +0 -0
- package/docs/assets/improvements/er-content-loss.png +0 -0
- package/docs/assets/improvements/fan-in-trunks.png +0 -0
- package/docs/assets/improvements/gantt-family.png +0 -0
- package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
- package/docs/assets/improvements/gantt-verify-seam.png +0 -0
- package/docs/assets/improvements/subgraph-container-edges.png +0 -0
- package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
- package/docs/assets/improvements/wrapper-init-directive.png +0 -0
- package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
- package/docs/assets/style-cookbook/mid-century-report.png +0 -0
- package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
- package/docs/assets/style-cookbook/transit-route-map.png +0 -0
- package/docs/comparison.md +0 -94
- package/docs/config.md +0 -105
- package/docs/contributing/adding-diagram-types.md +0 -144
- package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
- package/docs/contributing/diagram-family-citizenship.md +0 -82
- package/docs/contributing/harvesting-upstream-tests.md +0 -126
- package/docs/contributing/lessons-learned.md +0 -276
- package/docs/contributing/releasing.md +0 -71
- package/docs/contributing/visual-review-evidence.md +0 -53
- package/docs/custom-style-cookbook.md +0 -154
- package/docs/design/families/README.md +0 -26
- package/docs/design/families/architecture-beta.md +0 -48
- package/docs/design/families/flowchart-parser-conformance.md +0 -22
- package/docs/design/families/gantt-research.md +0 -137
- package/docs/design/families/gantt.md +0 -329
- package/docs/design/families/journey-agentic-cards-before.png +0 -0
- package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
- package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
- package/docs/design/families/journey-migration-parity.md +0 -433
- package/docs/design/families/journey-usage-research.md +0 -423
- package/docs/design/families/journey.md +0 -125
- package/docs/design/families/xychart.md +0 -85
- package/docs/design/system/README.md +0 -45
- package/docs/design/system/abstraction-audit.md +0 -224
- package/docs/design/system/abstraction-recommendations.md +0 -655
- package/docs/design/system/architecture.mmd +0 -29
- package/docs/design/system/architecture.svg +0 -137
- package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
- package/docs/design/system/layout-rubric.md +0 -138
- package/docs/design/system/route-contracts.md +0 -848
- package/docs/design/system/source-preservation-ladder.md +0 -52
- package/docs/design/system/styles-rollout.md +0 -216
- package/docs/design/system/ugly-layouts.md +0 -119
- package/docs/diagram-families.md +0 -193
- package/docs/features.md +0 -147
- package/docs/fork-differences.md +0 -130
- package/docs/getting-started.md +0 -175
- package/docs/issue-derived-test-cases.md +0 -156
- package/docs/layout-characterization/README.md +0 -245
- package/docs/layout-characterization/contact-sheet-families.md +0 -496
- package/docs/layout-characterization/contact-sheet.md +0 -638
- package/docs/layout-characterization/properties.md +0 -281
- package/docs/layout-characterization/visual-quality.md +0 -160
- package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
- package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
- package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
- package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
- package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/journey.svg +0 -118
- package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
- package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
- package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
- package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
- package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
- package/docs/mcp-code-mode-rationale.md +0 -101
- package/docs/mcp-http-transport.md +0 -223
- package/docs/mermaid-layout-complaints.md +0 -837
- package/docs/mutation-testing.md +0 -206
- package/docs/project/divergences.md +0 -98
- package/docs/project/dogfooding-docs-strategy.md +0 -66
- package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
- package/docs/project/lessons-learned.md +0 -1019
- package/docs/project/remove-role-styling-plan.md +0 -176
- package/docs/quality.md +0 -212
- package/docs/react.md +0 -97
- package/docs/style-authoring.md +0 -133
- package/docs/testing-strategy.md +0 -335
- package/docs/theming.md +0 -162
- package/examples/agent-improve-auth-flow.ts +0 -206
- package/examples/agent-loop.ts +0 -53
- package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
- package/llms.txt +0 -104
- package/skill-evals/README.md +0 -77
- package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
- package/skill-evals/fixtures/class-payment/input.mmd +0 -4
- package/skill-evals/fixtures/er-orders/input.mmd +0 -10
- package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
- package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
- package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
- package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
- package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
- package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
- package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
- package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
- package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
- package/skill-evals/shared-benchmark.json +0 -510
- package/src/agent/analyze.ts +0 -157
- package/src/agent/apply.ts +0 -146
- package/src/agent/architecture-body.ts +0 -458
- package/src/agent/certificates.ts +0 -110
- package/src/agent/class-body.ts +0 -319
- package/src/agent/core.ts +0 -207
- package/src/agent/create.ts +0 -106
- package/src/agent/describe.ts +0 -364
- package/src/agent/er-body.ts +0 -224
- package/src/agent/facts.ts +0 -337
- package/src/agent/families-builtin.ts +0 -934
- package/src/agent/families.ts +0 -232
- package/src/agent/family-layouts.ts +0 -826
- package/src/agent/flowchart-body.ts +0 -372
- package/src/agent/flowchart-unsupported.ts +0 -243
- package/src/agent/gantt-body.ts +0 -495
- package/src/agent/index.ts +0 -10
- package/src/agent/journey-body.ts +0 -414
- package/src/agent/label-metrics.ts +0 -28
- package/src/agent/layout-to-rendered.ts +0 -63
- package/src/agent/mutate.ts +0 -97
- package/src/agent/mutation-ops.ts +0 -51
- package/src/agent/op-schema.ts +0 -439
- package/src/agent/parse.ts +0 -223
- package/src/agent/pie-body.ts +0 -270
- package/src/agent/png.ts +0 -117
- package/src/agent/quadrant-body.ts +0 -336
- package/src/agent/quality.ts +0 -363
- package/src/agent/readability-audit.ts +0 -92
- package/src/agent/rendered-route-audit.ts +0 -61
- package/src/agent/sequence-body.ts +0 -345
- package/src/agent/serialize.ts +0 -214
- package/src/agent/state-body.ts +0 -589
- package/src/agent/structural-count.ts +0 -150
- package/src/agent/timeline-body.ts +0 -280
- package/src/agent/trace-log.ts +0 -43
- package/src/agent/types.ts +0 -979
- package/src/agent/verify.ts +0 -571
- package/src/agent/xychart-body.ts +0 -472
- package/src/architecture/config.ts +0 -282
- package/src/architecture/layout.ts +0 -496
- package/src/architecture/parser.ts +0 -375
- package/src/architecture/renderer.ts +0 -611
- package/src/architecture/types.ts +0 -113
- package/src/ascii/ansi.ts +0 -423
- package/src/ascii/architecture.ts +0 -210
- package/src/ascii/canvas.ts +0 -443
- package/src/ascii/class-diagram.ts +0 -697
- package/src/ascii/converter.ts +0 -475
- package/src/ascii/draw.ts +0 -1693
- package/src/ascii/edge-bundling.ts +0 -328
- package/src/ascii/edge-routing.ts +0 -330
- package/src/ascii/er-diagram.ts +0 -439
- package/src/ascii/gantt.ts +0 -276
- package/src/ascii/grid.ts +0 -747
- package/src/ascii/index.ts +0 -196
- package/src/ascii/journey.ts +0 -189
- package/src/ascii/meta.ts +0 -244
- package/src/ascii/multiline-utils.ts +0 -80
- package/src/ascii/pathfinder.ts +0 -301
- package/src/ascii/pie.ts +0 -67
- package/src/ascii/quadrant.ts +0 -158
- package/src/ascii/reverse.ts +0 -216
- package/src/ascii/sequence.ts +0 -499
- package/src/ascii/shapes/circle.ts +0 -27
- package/src/ascii/shapes/corners.ts +0 -143
- package/src/ascii/shapes/diamond.ts +0 -27
- package/src/ascii/shapes/hexagon.ts +0 -27
- package/src/ascii/shapes/index.ts +0 -106
- package/src/ascii/shapes/rectangle.ts +0 -168
- package/src/ascii/shapes/rounded.ts +0 -27
- package/src/ascii/shapes/special.ts +0 -332
- package/src/ascii/shapes/stadium.ts +0 -110
- package/src/ascii/shapes/state.ts +0 -192
- package/src/ascii/shapes/types.ts +0 -73
- package/src/ascii/timeline.ts +0 -128
- package/src/ascii/types.ts +0 -312
- package/src/ascii/validate.ts +0 -120
- package/src/ascii/width.ts +0 -81
- package/src/ascii/xychart.ts +0 -919
- package/src/browser.ts +0 -29
- package/src/class/layout.ts +0 -240
- package/src/class/parser.ts +0 -332
- package/src/class/renderer.ts +0 -638
- package/src/class/types.ts +0 -129
- package/src/cli/agent-instructions.ts +0 -1
- package/src/cli/am-bin.ts +0 -6
- package/src/cli/exit-codes.ts +0 -18
- package/src/cli/index.ts +0 -1117
- package/src/cli/init-agent.ts +0 -147
- package/src/color-resolver.ts +0 -152
- package/src/elk-instance.ts +0 -114
- package/src/er/layout.ts +0 -187
- package/src/er/parser.ts +0 -226
- package/src/er/renderer.ts +0 -792
- package/src/er/types.ts +0 -99
- package/src/font-manifest.ts +0 -27
- package/src/gantt/layout.ts +0 -365
- package/src/gantt/parser.ts +0 -282
- package/src/gantt/pipeline.ts +0 -27
- package/src/gantt/renderer.ts +0 -414
- package/src/gantt/schedule.ts +0 -513
- package/src/gantt/types.ts +0 -255
- package/src/index.ts +0 -368
- package/src/journey/layout.ts +0 -520
- package/src/journey/parser.ts +0 -218
- package/src/journey/renderer.ts +0 -811
- package/src/journey/types.ts +0 -144
- package/src/layout/geometry.ts +0 -182
- package/src/layout/pass.ts +0 -142
- package/src/layout/passes/index.ts +0 -3916
- package/src/layout-engine.ts +0 -1565
- package/src/layout-rubric.ts +0 -659
- package/src/mcp/artifacts.ts +0 -137
- package/src/mcp/dynamic-harness.ts +0 -31
- package/src/mcp/dynamic-modules.d.ts +0 -7
- package/src/mcp/facade.ts +0 -608
- package/src/mcp/harness-runtime.ts +0 -203
- package/src/mcp/hosted-server.ts +0 -468
- package/src/mcp/mcp-bin.ts +0 -3
- package/src/mcp/mcp-cli.ts +0 -82
- package/src/mcp/protocol.ts +0 -13
- package/src/mcp/sandbox.ts +0 -195
- package/src/mcp/sdk-decl.ts +0 -387
- package/src/mcp/server.ts +0 -362
- package/src/mcp/tool-surface.ts +0 -146
- package/src/mermaid-source.ts +0 -655
- package/src/multiline-utils.ts +0 -228
- package/src/parser.ts +0 -1031
- package/src/pie/layout.ts +0 -168
- package/src/pie/parser.ts +0 -136
- package/src/pie/renderer.ts +0 -234
- package/src/pie/types.ts +0 -82
- package/src/quadrant/layout.ts +0 -191
- package/src/quadrant/parser.ts +0 -183
- package/src/quadrant/renderer.ts +0 -322
- package/src/quadrant/types.ts +0 -113
- package/src/render-family-hooks.ts +0 -244
- package/src/renderer.ts +0 -1099
- package/src/route-contracts.ts +0 -2723
- package/src/scene/backend.ts +0 -76
- package/src/scene/fidelity.ts +0 -183
- package/src/scene/hybrid-backend.ts +0 -174
- package/src/scene/ir.ts +0 -181
- package/src/scene/marks.ts +0 -127
- package/src/scene/rough-backend.ts +0 -378
- package/src/scene/seed.ts +0 -46
- package/src/scene/style-registry.ts +0 -556
- package/src/sequence/layout.ts +0 -456
- package/src/sequence/parser.ts +0 -255
- package/src/sequence/renderer.ts +0 -604
- package/src/sequence/types.ts +0 -154
- package/src/shape-clipping.ts +0 -351
- package/src/shared/accessibility-directives.ts +0 -22
- package/src/shared/batched.ts +0 -61
- package/src/shared/color-math.ts +0 -72
- package/src/shared/svg-a11y.ts +0 -29
- package/src/shared/syntax-error.ts +0 -17
- package/src/shared/unicode-ranges.ts +0 -135
- package/src/styles.ts +0 -318
- package/src/svg-paths.ts +0 -28
- package/src/text-metrics.ts +0 -248
- package/src/theme.ts +0 -639
- package/src/timeline/layout.ts +0 -381
- package/src/timeline/parser.ts +0 -215
- package/src/timeline/renderer.ts +0 -538
- package/src/timeline/types.ts +0 -105
- package/src/types.ts +0 -454
- package/src/website-worker-modules.d.ts +0 -18
- package/src/xychart/axis-utils.ts +0 -109
- package/src/xychart/colors.ts +0 -124
- package/src/xychart/config.ts +0 -88
- package/src/xychart/layout.ts +0 -656
- package/src/xychart/parser.ts +0 -504
- package/src/xychart/renderer.ts +0 -640
- package/src/xychart/types.ts +0 -282
package/docs/testing-strategy.md
DELETED
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
# Testing strategy — what we test, how, and why
|
|
2
|
-
|
|
3
|
-
This document describes the testing approach **as it exists today**: the
|
|
4
|
-
tools we run, what each one actually proves, and the reasoning behind the
|
|
5
|
-
shape of the suite. It is a map, not a wish list. Where a gate is weaker
|
|
6
|
-
than it looks, this document says so — an honest map is more useful than a
|
|
7
|
-
flattering one.
|
|
8
|
-
|
|
9
|
-
For the *definition* of "good looking" and the determinism guarantees, see
|
|
10
|
-
[`quality.md`](./quality.md). For mutation specifics, see
|
|
11
|
-
[`mutation-testing.md`](./mutation-testing.md). For the layout/visual
|
|
12
|
-
contracts, see [`layout-characterization/README.md`](./layout-characterization/README.md).
|
|
13
|
-
|
|
14
|
-
## The central problem: this is a partly non-testable program
|
|
15
|
-
|
|
16
|
-
Most of what this project does has a computable correct answer: did we drop
|
|
17
|
-
a node, does the source re-parse, is the output byte-identical across runs.
|
|
18
|
-
Those are easy to gate.
|
|
19
|
-
|
|
20
|
-
But the thing the product is *for* — a **readable, good-looking diagram** —
|
|
21
|
-
has no computable oracle. "Looks good" is not a function we can assert. In
|
|
22
|
-
the testing literature this is the **test oracle problem**, and a program
|
|
23
|
-
whose correctness can't be mechanically decided is a **"non-testable
|
|
24
|
-
program"** (Weyuker). Diagram aesthetics are the textbook case.
|
|
25
|
-
|
|
26
|
-
We do not pretend to solve this with one gate. The strategy is a
|
|
27
|
-
**portfolio of partial oracles**: many independent, mostly-cheap checks,
|
|
28
|
-
each catching a different class of regression, with the expensive
|
|
29
|
-
human/LLM judgment reserved for the axis nothing else can cover. The
|
|
30
|
-
sections below are organized by *oracle type* — the kind of correctness
|
|
31
|
-
each gate can actually establish — because knowing what proof a gate
|
|
32
|
-
provides is the whole game (Loop 19: "CI-green is not the same as
|
|
33
|
-
audit-clean").
|
|
34
|
-
|
|
35
|
-
## Oracle types and the gates that use them
|
|
36
|
-
|
|
37
|
-
| Oracle type | What it can prove | Our gates |
|
|
38
|
-
|---|---|---|
|
|
39
|
-
| **Specified** | Output matches an explicit contract | Tier-1 structural `verify`, capabilities/schema tests, doc-sync guards |
|
|
40
|
-
| **Derived (golden)** | Output matches a previously-blessed artifact | ASCII goldens, SVG snapshots, contact sheets, screenshot baselines |
|
|
41
|
-
| **Derived (differential)** | Our output agrees with an external reference corpus | mermaid-docs corpus, MermaidSeqBench, upstream-suite bench |
|
|
42
|
-
| **Metamorphic** | Related inputs produce related outputs (no ground truth needed) | round-trip idempotence, cross-process/cross-runtime determinism |
|
|
43
|
-
| **Pseudo / adequacy** | The *tests themselves* are strong enough | Stryker mutation lanes, sabotage suite |
|
|
44
|
-
| **Heuristic / perceptual** | Geometry falls inside human-plausible bounds | `measureQuality`/`checkQuality`, ugly-detector, layout rubric, heuristic-tracker |
|
|
45
|
-
| **Human / model** | Subjective quality on the axis nothing else covers | LLM-as-judge (periodic), manual visual review |
|
|
46
|
-
|
|
47
|
-
The rest of this document walks each row: what it is, where it lives,
|
|
48
|
-
whether it gates per-PR, and what it does *not* prove.
|
|
49
|
-
|
|
50
|
-
## 1. Specified oracles — structural correctness
|
|
51
|
-
|
|
52
|
-
**Tier-1 `verify`** is the non-negotiable structural gate: no
|
|
53
|
-
`EMPTY_DIAGRAM`, `EDGE_MISANCHORED`, `OFF_CANVAS`, `GROUP_BREACH`,
|
|
54
|
-
`UNKNOWN_SHAPE`, or `LABEL_OVERFLOW`. It is reliable and universal across
|
|
55
|
-
families. **Tier-2** (geometric) and **Tier-3** (lint) are advisory.
|
|
56
|
-
|
|
57
|
-
Alongside it sit the **contract gates**: `am capabilities --json` schema
|
|
58
|
-
tests, `doc-sync`/`agent-doc-sync` tests, and the diagram-family
|
|
59
|
-
citizenship matrix. For an agent-native product the docs, schemas, CLI
|
|
60
|
-
help, and `llms.txt` *are* runtime surface (Loop 14), so they are tested
|
|
61
|
-
like code, not treated as prose.
|
|
62
|
-
|
|
63
|
-
**Runs:** every PR (`bun test src/__tests__/`).
|
|
64
|
-
**Does not prove:** that the diagram is *visually* good. `verify.ok` is
|
|
65
|
-
structural only — stated repeatedly because it has burned us (the Auth
|
|
66
|
-
Flow episode, Loop 15).
|
|
67
|
-
|
|
68
|
-
## 2. Derived oracles — goldens and snapshots
|
|
69
|
-
|
|
70
|
-
Blessed-artifact comparison for output that is deterministic but has no
|
|
71
|
-
independent spec:
|
|
72
|
-
|
|
73
|
-
- **ASCII goldens** — `scripts/update-ascii-goldens.ts`, `testdata/{unicode,ascii}/*.txt`.
|
|
74
|
-
- **SVG snapshots** and **contact sheets** — per-family rendered output.
|
|
75
|
-
- **Screenshot baselines** — `e2e/screenshots/baseline-*.png`, diffed against
|
|
76
|
-
fresh Playwright renders with a per-channel threshold in `e2e/browser.test.ts`.
|
|
77
|
-
- **Snapshot drift sentinel** — CI flags any change under `testdata/` so a
|
|
78
|
-
golden never moves silently.
|
|
79
|
-
|
|
80
|
-
**Runs:** ASCII/SVG goldens per PR. The browser/screenshot e2e suite also runs
|
|
81
|
-
per PR — it is the `e2e` job in `ci.yml` (`needs: test`), which installs
|
|
82
|
-
Chromium and runs `browser.test.ts` (screenshot diff), the CLI/security e2e,
|
|
83
|
-
and the single-binary e2e. The broad contact sheets are not on the per-PR gate.
|
|
84
|
-
**Does not prove:** that a *changed* golden is an improvement — only that
|
|
85
|
-
change was noticed. Judging the change still needs a human or the
|
|
86
|
-
before/after harness (`eval/layout-compare`).
|
|
87
|
-
|
|
88
|
-
## 3. Derived oracles — differential corpora
|
|
89
|
-
|
|
90
|
-
The strongest defense against our own blind spots is testing against
|
|
91
|
-
sources we did not write:
|
|
92
|
-
|
|
93
|
-
- **mermaid-docs corpus** (271 entries) — harvested from Mermaid's own
|
|
94
|
-
documentation; gates parse, verify, and round-trip.
|
|
95
|
-
- **MermaidSeqBench** (132 IBM-curated sequence diagrams) — parse rate,
|
|
96
|
-
structured-vs-opaque split, verify rate, round-trip stability.
|
|
97
|
-
- **upstream-suite bench** (`eval/mermaid-upstream-suite-bench/`, 658
|
|
98
|
-
imported cases from a *pinned* upstream commit) — with a **ratchet**
|
|
99
|
-
(`ratchet.json`) that fails the build if coverage drops or per-family
|
|
100
|
-
local-gap budgets grow.
|
|
101
|
-
|
|
102
|
-
These exist because our hand-written fixtures encode what we already knew
|
|
103
|
-
the parser modeled. Upstream examples are "adversarial in exactly the
|
|
104
|
-
right way" — they encode what real sources contain (wrapper-fidelity
|
|
105
|
-
lesson). The `@{shape}` silent-loss and ER `}o` bugs both escaped 2,200+
|
|
106
|
-
self-authored tests and were caught only by docs-derived sources.
|
|
107
|
-
|
|
108
|
-
**Runs:** every PR (corpus + seqbench + upstream-suite ratchet).
|
|
109
|
-
**Faithfulness count-oracle:** the corpus gate now also asserts that the
|
|
110
|
-
structured `{nodes, edges, groups}` tally survives a parse → serialize →
|
|
111
|
-
re-parse cycle for **every** renderable family
|
|
112
|
-
(`eval/shared/structural-count.ts`, gated in `agent-mermaid-corpus.test.ts`).
|
|
113
|
-
Round-trip *byte*-stability only proves serialize∘parse is idempotent; this
|
|
114
|
-
count check proves parse did not silently drop content — the ER `}o` class of
|
|
115
|
-
bug ("100% parse success is not faithfulness", Loop 17) now fails CI directly
|
|
116
|
-
rather than only where a hand-written oracle happened to bite.
|
|
117
|
-
|
|
118
|
-
## 4. Metamorphic oracles — relations instead of ground truth
|
|
119
|
-
|
|
120
|
-
When we can't say "the output is correct," we can say "these related runs
|
|
121
|
-
must agree." This sidesteps the oracle problem without a human:
|
|
122
|
-
|
|
123
|
-
- **Round-trip idempotence** — `parse → serialize → parse` is stable;
|
|
124
|
-
structured-mutation invariants via `fast-check` (the `property-*.test.ts`
|
|
125
|
-
suite).
|
|
126
|
-
- **Determinism** — three separate processes produce byte-identical layout
|
|
127
|
-
JSON; Bun and Node produce byte-identical JSON on the same source; ASCII
|
|
128
|
-
and PNG output hash-stable across 10+ repeated runs.
|
|
129
|
-
- **Layout/faithfulness relations** — `property-layout-metamorphic.test.ts`
|
|
130
|
-
formalizes relations that were previously implicit: determinism (same source
|
|
131
|
-
⇒ identical metrics), node-id **relabeling invariance** (ids carry no
|
|
132
|
-
meaning), **disconnected-node monotonicity** (adding an isolated node adds
|
|
133
|
-
exactly one node and drops nothing), and **edge-add monotonicity**.
|
|
134
|
-
Statement-permutation invariance is deliberately *not* asserted — source
|
|
135
|
-
order is a stated design property, so permuting statements may legitimately
|
|
136
|
-
change geometry.
|
|
137
|
-
|
|
138
|
-
**Runs:** every PR.
|
|
139
|
-
**Does not prove:** cross-architecture equality (x86_64 hash vs ARM64 hash
|
|
140
|
-
is not compared). That is the natural next place to *extend* the metamorphic
|
|
141
|
-
set, since the technique is the same.
|
|
142
|
-
|
|
143
|
-
### Seed policy: pinned gates, rolling finders
|
|
144
|
-
|
|
145
|
-
Every fast-check suite runs at one pinned global seed, set process-wide by
|
|
146
|
-
`src/__tests__/fc-seed.preload.ts` (wired via `bunfig.toml` `[test].preload`;
|
|
147
|
-
default seed `20260702`). A red property in CI is therefore a real,
|
|
148
|
-
reproducible counterexample — never a seed lottery. The 2026-07 audit caught
|
|
149
|
-
three suites flaking on rolled seeds (the route-contracts certificate property
|
|
150
|
-
at ~1 CI run in 7, issue #83; the parser Cartesian-product property; both now
|
|
151
|
-
pin the exact seed that exposed their bug, scoped via save/restore so the
|
|
152
|
-
global policy survives them).
|
|
153
|
-
|
|
154
|
-
- Reproduce a specific roll: `AM_FC_SEED=<int> bun test <file>`.
|
|
155
|
-
- Finder mode (deliberate randomness): `AM_FC_SEED=random bun test src/__tests__/`.
|
|
156
|
-
- The policy is itself gated: `fc-seed-policy.test.ts` fails if the preload is
|
|
157
|
-
unwired; `zzz-fc-seed-policy-epilogue.test.ts` (alphabetically last) fails if
|
|
158
|
-
any suite wipes the pin instead of restoring it.
|
|
159
|
-
|
|
160
|
-
Pinning is for *holding* known ground; randomness is for *finding* new
|
|
161
|
-
counterexamples ("an invariant enforced by a random property is a lottery,
|
|
162
|
-
not a gate" — `docs/contributing/lessons-learned.md`). Rolling seeds belong in
|
|
163
|
-
finder lanes: the deep-fuzz scripts under `eval/`, or deliberate
|
|
164
|
-
`AM_FC_SEED=random` sweeps. Before the pin was frozen, every unpinned suite was
|
|
165
|
-
swept across 48/24/12 seeds (scaled by runtime; 1,368 suite-runs total) with
|
|
166
|
-
zero failures — the pin does not freeze a known-bad ticket, and the sweep is
|
|
167
|
-
repeatable from the same knob.
|
|
168
|
-
|
|
169
|
-
## 5. Pseudo-oracles — is the suite itself strong enough?
|
|
170
|
-
|
|
171
|
-
Tests can be green and still worthless. Two gates test the tests:
|
|
172
|
-
|
|
173
|
-
- **Mutation testing (Stryker)** — scoped to the high-value ASCII/route
|
|
174
|
-
core, ~20 named lanes (`stryker.*.config.json`). A *survived* mutant is a
|
|
175
|
-
test gap until classified. Documented baseline kill rates are 38–75%,
|
|
176
|
-
with a written survivor catalog and explicit "accepted" classifications
|
|
177
|
-
(performance guards, unreachable-by-convention). Mutation testing has
|
|
178
|
-
earned its keep: it falsified an audit assumption and found dead code the
|
|
179
|
-
unit tests couldn't.
|
|
180
|
-
- **Sabotage suite** (`eval/sabotage/route-regressions.ts`) — deliberately
|
|
181
|
-
reverts a fixed bug in a detached worktree and asserts the suite goes
|
|
182
|
-
**red**, proving the regression test actually bites.
|
|
183
|
-
|
|
184
|
-
**Runs:** the broad route lanes are **scheduled nightly**
|
|
185
|
-
(`nightly-route-mutation.yml`: routes, route-certificates, subgraph-routing,
|
|
186
|
-
sabotage-routes — the ascii lane is manual-only), but every scheduled run since
|
|
187
|
-
2026-06-19 has been cancelled at the 90-minute cap before producing a score
|
|
188
|
-
(the unsharded routes lane alone exceeds it; PR #63 carries the sharding fix) —
|
|
189
|
-
until that lands, regenerate scores locally. A narrow module takes 5–15 minutes
|
|
190
|
-
locally; the full routes lane substantially longer. A **fast
|
|
191
|
-
incremental lane** (`stryker.incremental.config.json`, the `mutation-incremental`
|
|
192
|
-
CI job) mutates only the small pure faithfulness counter
|
|
193
|
-
(`src/agent/structural-count.ts`) with a sub-second unit runner, so it gates
|
|
194
|
-
**per-PR** (~1 min, measured 96% kill / break-threshold 90).
|
|
195
|
-
**Why this matters:** line coverage is reported per-PR but is a weak
|
|
196
|
-
adequacy signal — coverage is not strongly correlated with fault detection
|
|
197
|
-
once suite size is controlled (Inozemtseva & Holmes, ICSE 2014), whereas
|
|
198
|
-
mutant detection *is* correlated with real-fault detection (Just et al.,
|
|
199
|
-
FSE 2014). The mutation score is the truer number; today it comes from local runs (the nightly lane times out — see above).
|
|
200
|
-
|
|
201
|
-
## 6. Heuristic / perceptual oracles — geometry inside human bounds
|
|
202
|
-
|
|
203
|
-
This is where we approximate aesthetics deterministically:
|
|
204
|
-
|
|
205
|
-
- **`measureQuality` / `checkQuality`** — edge crossings, label
|
|
206
|
-
legibility, whitespace balance, label-edge proximity, aspect ratio,
|
|
207
|
-
gated by `QualityBounds`. Cheap and deterministic; covers all twelve
|
|
208
|
-
renderable families via `RenderedLayout` adapters.
|
|
209
|
-
- **ugly-detector** (`eval/ugly-detector/`) — geometric defect detection:
|
|
210
|
-
diagonal segments, floating endpoints, edges through nodes, hitches.
|
|
211
|
-
- **layout rubric / visual-rubric** — hard violations (must be 0) plus soft
|
|
212
|
-
thresholds (crossings, bends, port-anchored rate).
|
|
213
|
-
- **heuristic-tracker** — baseline-comparison of routing metrics with
|
|
214
|
-
improvement/regression deltas, now gated per PR (`heuristic-tracker.test.ts`):
|
|
215
|
-
hard violations must stay 0 and no tracked example may regress on a soft
|
|
216
|
-
metric without a reviewed `baseline.json` update in the same change.
|
|
217
|
-
- **route-contract tripwires** — `ROUTE_*` codes that must stay 0; any hit
|
|
218
|
-
means the layout pipeline regressed, not the diagram.
|
|
219
|
-
|
|
220
|
-
**Runs:** `measureQuality`, ugly-detector, the layout rubric, and the
|
|
221
|
-
heuristic-tracker ratchet all gate per PR.
|
|
222
|
-
**Bound provenance (Move 6):** each `QualityBounds` band now carries an
|
|
223
|
-
explicit basis — `edgeCrossings` is `evidence` (the one aesthetic with strong
|
|
224
|
-
human-subject support: Purchase 1997/2002), `labelLegibility` is `derived`
|
|
225
|
-
(labels must physically fit), `whitespaceBalance`/`labelEdgeProximity` are
|
|
226
|
-
`chosen` (plausible but unvalidated), and `aspectRatio` is a `sanity`
|
|
227
|
-
guardrail. `checkQuality` returns `ranked` violations tagged primary /
|
|
228
|
-
secondary / sanity so a consumer weights a crossings violation above a
|
|
229
|
-
whitespace one (`BOUND_PROVENANCE` in `src/agent/quality.ts`).
|
|
230
|
-
**Does not prove:** that the diagram is good to a *human* eye. The bands
|
|
231
|
-
are honest approximations with headroom — "we do not claim our metrics
|
|
232
|
-
match a human designer's eye; they catch the worst regressions"
|
|
233
|
-
(`quality.md`). Provenance makes the calibration honest; it does not make a
|
|
234
|
-
`chosen` band correct.
|
|
235
|
-
|
|
236
|
-
## 7. Human / model oracles — the axis nothing else covers
|
|
237
|
-
|
|
238
|
-
- **LLM-as-judge** (`eval/llm-judge/judge.ts`) — scores readability,
|
|
239
|
-
faithfulness, aesthetics (1–5) on a stratified corpus sample.
|
|
240
|
-
- **Manual visual review** — required reproducible artifacts for
|
|
241
|
-
layout/rendering changes (`contributing/visual-review-evidence.md`).
|
|
242
|
-
|
|
243
|
-
**Runs:** the real LLM judge is **periodic / pre-release only** — model
|
|
244
|
-
spend plus nondeterminism make it unfit for a per-PR gate. In CI it is
|
|
245
|
-
replaced by a deterministic mock.
|
|
246
|
-
**Protocol hardening (Move 1):** the readability/aesthetics axes of the CI
|
|
247
|
-
mock are still derived from the perceptual metrics (it is a wiring stub), but
|
|
248
|
-
the **faithfulness** axis now comes from `independentFaithfulness()` — a
|
|
249
|
-
structural parse → serialize → re-parse count check that does *not* consult
|
|
250
|
-
`measureQuality`, removing the circularity on that axis. The real judge has
|
|
251
|
-
primitives for the documented LLM-judge biases (Zheng et al., NeurIPS 2023):
|
|
252
|
-
`judgePairwiseDebiased` scores both orders and trusts only an agreeing verdict
|
|
253
|
-
(position bias), `assertJudgeIndependence` refuses a judge from the same model
|
|
254
|
-
family that authored the diagram (self-enhancement), and `JudgeReference`
|
|
255
|
-
threads a golden anchor (reference-guided scoring).
|
|
256
|
-
**Known limitation:** the mock's readability/aesthetics axes remain
|
|
257
|
-
metric-derived, so they cannot independently validate those metrics — only a
|
|
258
|
-
real judge run can.
|
|
259
|
-
|
|
260
|
-
## What runs where
|
|
261
|
-
|
|
262
|
-
`ci.yml` is the source of truth for what gates each PR — read it rather than a
|
|
263
|
-
table here, which would drift. In broad strokes:
|
|
264
|
-
|
|
265
|
-
- **Per-PR (`ci.yml`):** the unit/property suite (`bun test src/__tests__/`) —
|
|
266
|
-
Tier-1 verify, goldens, the differential + faithfulness + metamorphic gates,
|
|
267
|
-
`measureQuality`/ugly-detector/layout-rubric, the heuristic-tracker ratchet,
|
|
268
|
-
the corpus/seqbench/upstream benches — plus type check, the hero check, the
|
|
269
|
-
golden-drift gate, the browser/CLI/binary e2e job, and the fast incremental
|
|
270
|
-
mutation lane.
|
|
271
|
-
- **Nightly (`nightly-route-mutation.yml`):** the broad Stryker route lanes
|
|
272
|
-
and the sabotage suite (scheduled; currently cancelled at the timeout every
|
|
273
|
-
run — see §5).
|
|
274
|
-
- **Manual / periodic:** `layout-compare` before/after, the benchmark vs
|
|
275
|
-
competitors, and the real LLM-as-judge run.
|
|
276
|
-
|
|
277
|
-
## Why the suite is shaped this way
|
|
278
|
-
|
|
279
|
-
- **Cheap-and-deterministic gates per PR; expensive-and-noisy gates
|
|
280
|
-
off it.** Anything that is slow (full mutation), costly (live model), or
|
|
281
|
-
nondeterministic (real LLM judge, timing benchmarks) is deliberately not
|
|
282
|
-
a merge blocker, because a flaky or budget-dominating gate trains people
|
|
283
|
-
to ignore it.
|
|
284
|
-
- **Differential corpora over hand-written fixtures for compatibility
|
|
285
|
-
claims.** Self-authored tests share the author's blind spots; sources we
|
|
286
|
-
did not write do not.
|
|
287
|
-
- **Metamorphic relations where there is no oracle.** Determinism and
|
|
288
|
-
round-trip laws assert correctness without a blessed answer.
|
|
289
|
-
- **Mutation/sabotage to keep the suite honest**, because green tests and a
|
|
290
|
-
high coverage number are not the same as a suite that detects faults.
|
|
291
|
-
- **Layered verification (Tier 1/2/3)** so the reliable structural signal
|
|
292
|
-
is never diluted by the advisory geometric/lint signals.
|
|
293
|
-
|
|
294
|
-
## Honest gaps (current, not aspirational)
|
|
295
|
-
|
|
296
|
-
These are real today and are the natural targets for *enhancing* existing
|
|
297
|
-
gates rather than adding new machinery:
|
|
298
|
-
|
|
299
|
-
1. The per-PR aesthetic signal is still the weakest gate; the metrics are
|
|
300
|
-
admittedly rough. The CI LLM mock's readability/aesthetics axes remain
|
|
301
|
-
metric-derived (only its faithfulness axis is now independent), so it
|
|
302
|
-
cannot validate those metrics — only a real periodic judge run can.
|
|
303
|
-
2. The *broad* mutation lanes and sabotage are scheduled nightly but the
|
|
304
|
-
schedule has never completed a run (timeout — see §5); a fast incremental
|
|
305
|
-
lane gates the faithfulness counter per-PR, so most core modules' adequacy
|
|
306
|
-
is currently measured only by local runs. Line coverage is no
|
|
307
|
-
longer the per-PR headline (it is framed as a finder).
|
|
308
|
-
3. The benchmark is not on the PR gate (timing variance). Browser/screenshot
|
|
309
|
-
e2e and the heuristic-tracker ratchet now are.
|
|
310
|
-
4. Determinism is proven Bun↔Node on one architecture; cross-architecture
|
|
311
|
-
byte equality is not asserted.
|
|
312
|
-
5. `QualityBounds` thresholds are now provenance-tagged, but the `chosen`
|
|
313
|
-
bands are still not validated against human-perception evidence.
|
|
314
|
-
6. The snapshot drift sentinel warns but does not block.
|
|
315
|
-
|
|
316
|
-
The deepest gap is structural, and `project/lessons-learned.md` (Loop 13)
|
|
317
|
-
names it: every quality signal here is self-generated. The portfolio above
|
|
318
|
-
produces breadth and internal consistency; it cannot substitute for a real
|
|
319
|
-
external consumer.
|
|
320
|
-
|
|
321
|
-
## References
|
|
322
|
-
|
|
323
|
-
- Barr, Harman, McMinn, Shahbaz, Yoo — *The Oracle Problem in Software
|
|
324
|
-
Testing: A Survey*, IEEE TSE 2015.
|
|
325
|
-
- Chen et al. — *Metamorphic Testing: A Review of Challenges and
|
|
326
|
-
Opportunities*, ACM Computing Surveys 2018.
|
|
327
|
-
- Purchase — *Which Aesthetic Has the Greatest Effect on Human
|
|
328
|
-
Understanding?* (GD 1997) and *Metrics for Graph Drawing Aesthetics*
|
|
329
|
-
(JVLC 2002).
|
|
330
|
-
- Inozemtseva & Holmes — *Coverage Is Not Strongly Correlated with Test
|
|
331
|
-
Suite Effectiveness*, ICSE 2014.
|
|
332
|
-
- Just et al. — *Are Mutants a Valid Substitute for Real Faults in Software
|
|
333
|
-
Testing?*, FSE 2014.
|
|
334
|
-
- Zheng et al. — *Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena*,
|
|
335
|
-
NeurIPS 2023.
|
package/docs/theming.md
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
# Theming
|
|
2
|
-
|
|
3
|
-
Agentic Mermaid themes start from a two-color contract (`bg`, `fg`) and can be enriched with optional semantic slots. This keeps diagrams usable in live editors, documentation pages, and agent-generated artifacts without requiring a large design-token object.
|
|
4
|
-
|
|
5
|
-
> **Themes are styles.** Every built-in theme also registers as a
|
|
6
|
-
> palette-only *style*, so its name works anywhere a style is accepted and
|
|
7
|
-
> composes with full looks by stacking: `{ style: ['hand-drawn', 'dracula'] }`
|
|
8
|
-
> renders hand-drawn geometry with the Dracula palette. See
|
|
9
|
-
> [docs/style-authoring.md](./style-authoring.md) for the full model.
|
|
10
|
-
|
|
11
|
-
## Two-color foundation
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { renderMermaidSVG } from 'agentic-mermaid'
|
|
15
|
-
|
|
16
|
-
const svg = renderMermaidSVG(source, {
|
|
17
|
-
bg: '#0B1020',
|
|
18
|
-
fg: '#E5E7EB',
|
|
19
|
-
})
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
From those colors the renderer derives contrast-aware node fills, labels, edges, and accents. This is the safest default for agents: pick readable foreground/background colors and let the renderer complete the palette.
|
|
23
|
-
|
|
24
|
-
## Enriched mode
|
|
25
|
-
|
|
26
|
-
Use extra slots when your product already has semantic tokens:
|
|
27
|
-
|
|
28
|
-
```ts
|
|
29
|
-
const svg = renderMermaidSVG(source, {
|
|
30
|
-
bg: 'var(--canvas)',
|
|
31
|
-
fg: 'var(--text)',
|
|
32
|
-
line: 'var(--line)',
|
|
33
|
-
accent: 'var(--accent)',
|
|
34
|
-
muted: 'var(--muted)',
|
|
35
|
-
surface: 'var(--surface)',
|
|
36
|
-
border: 'var(--border)',
|
|
37
|
-
})
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Slots:
|
|
41
|
-
|
|
42
|
-
| Slot | Meaning |
|
|
43
|
-
|---|---|
|
|
44
|
-
| `bg` | SVG canvas/background. |
|
|
45
|
-
| `fg` | Primary text. |
|
|
46
|
-
| `line` | Connectors and strokes. |
|
|
47
|
-
| `accent` | Arrowheads and emphasis. |
|
|
48
|
-
| `muted` | Secondary labels. |
|
|
49
|
-
| `surface` | Node/card fill. |
|
|
50
|
-
| `border` | Node/card border. |
|
|
51
|
-
|
|
52
|
-
## CSS custom properties
|
|
53
|
-
|
|
54
|
-
CSS variables are first-class values:
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
const svg = renderMermaidSVG(source, {
|
|
58
|
-
bg: 'var(--diagram-bg)',
|
|
59
|
-
fg: 'var(--diagram-fg)',
|
|
60
|
-
accent: 'var(--diagram-accent)',
|
|
61
|
-
embedFontImport: false,
|
|
62
|
-
})
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Because the generated SVG references variables directly, host pages can switch light/dark themes without re-rendering the diagram.
|
|
66
|
-
|
|
67
|
-
## Built-in themes
|
|
68
|
-
|
|
69
|
-
Agentic Mermaid ships **21 built-in themes**:
|
|
70
|
-
|
|
71
|
-
- `paper`
|
|
72
|
-
- `dusk`
|
|
73
|
-
- `zinc-light`
|
|
74
|
-
- `zinc-dark`
|
|
75
|
-
- `tokyo-night`
|
|
76
|
-
- `tokyo-night-storm`
|
|
77
|
-
- `tokyo-night-light`
|
|
78
|
-
- `catppuccin-mocha`
|
|
79
|
-
- `catppuccin-latte`
|
|
80
|
-
- `nord`
|
|
81
|
-
- `nord-light`
|
|
82
|
-
- `dracula`
|
|
83
|
-
- `github-light`
|
|
84
|
-
- `github-dark`
|
|
85
|
-
- `solarized-light`
|
|
86
|
-
- `solarized-dark`
|
|
87
|
-
- `one-dark`
|
|
88
|
-
- `salmon`
|
|
89
|
-
- `salmon-dark`
|
|
90
|
-
- `tufte`
|
|
91
|
-
- `tufte-dark`
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
import { THEMES, renderMermaidSVG } from 'agentic-mermaid'
|
|
95
|
-
|
|
96
|
-
const svg = renderMermaidSVG(source, THEMES['tokyo-night'])
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Custom themes
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
import type { DiagramColors } from 'agentic-mermaid'
|
|
103
|
-
|
|
104
|
-
export const myTheme: DiagramColors = {
|
|
105
|
-
bg: '#111827',
|
|
106
|
-
fg: '#F9FAFB',
|
|
107
|
-
line: '#64748B',
|
|
108
|
-
accent: '#38BDF8',
|
|
109
|
-
muted: '#94A3B8',
|
|
110
|
-
surface: '#1F2937',
|
|
111
|
-
border: '#334155',
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Then pass it to any renderer:
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
renderMermaidSVG(source, myTheme)
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Shiki compatibility
|
|
122
|
-
|
|
123
|
-
Turn a Shiki or VS Code theme into a diagram palette:
|
|
124
|
-
|
|
125
|
-
```ts
|
|
126
|
-
import { fromShikiTheme, renderMermaidSVG } from 'agentic-mermaid'
|
|
127
|
-
import githubDark from 'shiki/themes/github-dark.mjs'
|
|
128
|
-
|
|
129
|
-
const colors = fromShikiTheme(githubDark)
|
|
130
|
-
const svg = renderMermaidSVG(source, colors)
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
`fromShikiTheme(theme)` reads the editor background/foreground and token colors, then maps them to Agentic Mermaid's semantic slots.
|
|
134
|
-
|
|
135
|
-
## Style + Palette stacks
|
|
136
|
-
|
|
137
|
-
Use `style` for renderer treatment and palettes, not Mermaid source edits:
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
const svg = renderMermaidSVG(source, {
|
|
141
|
-
style: ['publication-figure', 'zinc-light'],
|
|
142
|
-
seed: 2,
|
|
143
|
-
})
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
For per-element emphasis, keep using Mermaid-native directives such as `classDef`, `class`, `style`, and `linkStyle`. See [`api.md`](./api.md) for the full `RenderOptions` table.
|
|
147
|
-
|
|
148
|
-
## Security and fonts
|
|
149
|
-
|
|
150
|
-
Default SVG output includes a Google Fonts `@import` for convenience. For offline, strict, or agent-generated artifacts, use either:
|
|
151
|
-
|
|
152
|
-
```ts
|
|
153
|
-
renderMermaidSVG(source, { embedFontImport: false })
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
or strict mode:
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
renderMermaidSVG(source, { security: 'strict' })
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
`security: 'strict'` disables external-fetch references and is the recommended default for untrusted diagrams.
|