agentic-mermaid 0.1.2 → 0.3.0
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/AGENT_NATIVE.md +671 -0
- package/CHANGELOG.md +36 -0
- package/Instructions_for_agents.md +89 -0
- package/README.md +8 -8
- package/assets/hero.png +0 -0
- package/dist/agent-core.d.ts +2 -2
- package/dist/agent-core.js +2 -2
- package/dist/agent.d.ts +2 -2
- package/dist/agent.js +4 -4
- package/dist/agentic-mermaid-mcp.js +5 -5
- package/dist/am.js +8 -15
- package/dist/browser.global.js +777 -0
- package/dist/{chunk-WN3YDOBG.js → chunk-3QCXO4V6.js} +4 -4
- package/dist/{chunk-4QECACIA.js → chunk-AVCWKYII.js} +19 -19
- package/dist/{chunk-WI35L7IR.js → chunk-GILQUGFK.js} +2 -2
- package/dist/{chunk-QKDLMOJJ.js → chunk-HFD4MALA.js} +7 -9
- package/dist/{chunk-CDPKJ2BQ.js → chunk-UJNY65QS.js} +2 -2
- package/dist/{chunk-ZYMMKQ3I.js → chunk-WHYJLDYG.js} +299 -973
- package/dist/{index-D54dqSdC.d.ts → index-CLwYn6Im.d.ts} +7 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp-cli-SJVOGRA6.js +17 -0
- package/docs/README.md +35 -34
- package/docs/agent-api-cookbook.md +317 -0
- package/docs/agent-mutation-policy.md +104 -0
- package/docs/agent-workflow-examples.md +46 -0
- package/docs/api.md +418 -0
- package/docs/ascii.md +113 -0
- package/docs/browser.md +183 -0
- package/docs/code-mode-impact.md +214 -0
- package/docs/comparison.md +106 -0
- package/docs/computational-aesthetics-prototype-plan.md +252 -0
- package/docs/config.md +121 -0
- package/docs/custom-fonts.md +265 -0
- package/docs/custom-style-cookbook.md +275 -0
- package/docs/diagram-families.md +218 -0
- package/docs/features.md +154 -0
- package/docs/fork-differences.md +166 -0
- package/docs/getting-started.md +182 -0
- package/docs/issue-derived-test-cases.md +163 -0
- package/docs/mcp-code-mode-rationale.md +108 -0
- package/docs/mcp-http-transport.md +230 -0
- package/docs/mermaid-layout-complaints.md +851 -0
- package/docs/mutation-testing.md +285 -0
- package/docs/quality.md +224 -0
- package/docs/react.md +97 -0
- package/docs/style-authoring.md +336 -0
- package/docs/svg-semantic-contract.md +49 -0
- package/docs/testing-strategy.md +443 -0
- package/docs/theming.md +149 -0
- package/package.json +28 -9
- package/server.json +2 -2
- package/skills/agentic-mermaid-live-editor/SKILL.md +1 -1
- package/dist/mcp-cli-SBQSTJFC.js +0 -17
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# What is different about this fork?
|
|
2
|
+
|
|
3
|
+
This document describes **Agentic Mermaid**, the `adewale/agentic-mermaid` fork, relative to upstream `lukilabs/beautiful-mermaid`. It is intentionally product/documentation focused; upstreamable changes should still be split into small PRs.
|
|
4
|
+
|
|
5
|
+
## Live site
|
|
6
|
+
|
|
7
|
+
The canonical live site is **[agentic-mermaid.dev](https://agentic-mermaid.dev/)** — a Cloudflare Workers Static Assets deployment built from [`website/`](../website):
|
|
8
|
+
|
|
9
|
+
- Home & docs: <https://agentic-mermaid.dev/>
|
|
10
|
+
- Live editor: <https://agentic-mermaid.dev/editor>
|
|
11
|
+
- Family comparisons (Mermaid vs Beautiful Mermaid vs Agentic Mermaid): <https://agentic-mermaid.dev/comparisons/>
|
|
12
|
+
|
|
13
|
+
Alongside the static surface (the public website, machine-readable manifests, schemas, recipes, and skill files), the Cloudflare Worker serves a stateless hosted MCP endpoint at `/mcp` (`https://agentic-mermaid.dev/mcp`) — registry-checked tools: Code Mode `execute` in per-request Dynamic Worker isolates, `describe_sdk` for one family's mutation schema on demand, the `render_svg`/`render_ascii`/`render_png`/`verify`/`describe` pure tools, and the declarative `mutate`/`build` structured-edit tools. There is still no REST render API: `/mcp` speaks MCP JSON-RPC only.
|
|
14
|
+
|
|
15
|
+
GitHub Pages is no longer a deployed surface; its samples-gallery generator has been retired. The live editor is served at [agentic-mermaid.dev/editor](https://agentic-mermaid.dev/editor) and built by `scripts/site/editor.ts` (also used by `website/build.ts`), and is exercised in a real browser by `e2e/browser.test.ts`.
|
|
16
|
+
|
|
17
|
+
## Agent-native workflow (largest fork-vs-upstream gap)
|
|
18
|
+
|
|
19
|
+
Agentic Mermaid is published as `agentic-mermaid` and adds a typed editing surface for AI agents under the `agentic-mermaid/agent` subpath export, plus an `am` CLI and an `agentic-mermaid-mcp` Code Mode MCP server (stdio plus opt-in HTTP/SSE transport with managed render artifacts). A render-only library forces an agent to regenerate the whole diagram to change one node; here, new diagrams are authored as source then parsed/verified/rendered, while existing structured diagrams go parse → narrow → mutate → verify → serialize.
|
|
20
|
+
|
|
21
|
+
Every registered family is structured when narrowed; segment-preserving families retain unsupported statements in source order, and any whole-body fallback round-trips losslessly. Layout is deterministic and verified byte-identical across processes, and `verifyMermaid` returns structured structural, geometric, and lint warnings plus perceptual quality metrics covering every family. See [`AGENT_NATIVE.md`](../AGENT_NATIVE.md) and [`Instructions_for_agents.md`](../Instructions_for_agents.md). Upstream has no equivalent; for a three-way functionality view including Mermaid itself, see [`comparison.md`](./comparison.md).
|
|
22
|
+
|
|
23
|
+
## New and expanded diagram support
|
|
24
|
+
|
|
25
|
+
This fork renders a wider set of Mermaid families in both the gallery and editor:
|
|
26
|
+
|
|
27
|
+
- Flowcharts and state diagrams
|
|
28
|
+
- Architecture diagrams (`architecture-beta`)
|
|
29
|
+
- Sequence diagrams
|
|
30
|
+
- Class diagrams
|
|
31
|
+
- ER diagrams
|
|
32
|
+
- Timeline diagrams (`timeline`)
|
|
33
|
+
- User Journey diagrams (`journey`)
|
|
34
|
+
- XY charts (`xychart` and `xychart-beta`)
|
|
35
|
+
- Pie charts (`pie`, with `showData`)
|
|
36
|
+
- Quadrant charts (`quadrantChart`) — not yet rendered anywhere else in the beautiful-mermaid network
|
|
37
|
+
- Gantt charts (`gantt`) with date axes, sections, dependencies, milestones, exclusions, and vertical markers
|
|
38
|
+
- Mindmaps (`mindmap`) with indentation-sensitive hierarchy, shapes, icons, and classes
|
|
39
|
+
- Git graphs (`gitGraph`) with deterministic replayed commits, branches, merges, and cherry-picks
|
|
40
|
+
- Radar charts (`radar-beta`) — spider/star charts plotting multivariate profiles across equi-angular axes from a shared center
|
|
41
|
+
|
|
42
|
+
The live editor has registry-backed example coverage for every built-in family
|
|
43
|
+
(`src/__tests__/editor-examples.test.ts`). Browser E2E still spot-checks several
|
|
44
|
+
fork-added rendering paths: architecture, timeline, journey, and xychart.
|
|
45
|
+
|
|
46
|
+
## Style + Palette SVG rendering
|
|
47
|
+
|
|
48
|
+
The fork adds a consistent Style + Palette API across diagram families:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
renderMermaidSVG(source, {
|
|
52
|
+
style: ['publication-figure', 'github-light'],
|
|
53
|
+
seed: 2,
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
A style chooses the renderer treatment — for example `hand-drawn`, `watercolor`, `publication-figure`, or `ops-schematic`. A palette-only style chooses colors — for example `github-light`, `dracula`, or a custom JSON record with `colors`. Stacks merge left to right, so agents can keep visual requests out of Mermaid source while preserving deterministic geometry.
|
|
58
|
+
|
|
59
|
+
## Migrating from upstream: every export this fork does not have
|
|
60
|
+
|
|
61
|
+
Upstream Beautiful Mermaid's entry point exports 16 names. Ten are still
|
|
62
|
+
exported here with the same meaning: `renderMermaidSVG`, `renderMermaidASCII`,
|
|
63
|
+
`renderMermaidSVGAsync`, `fromShikiTheme`, `DEFAULTS`, and the `RenderOptions`,
|
|
64
|
+
`AsciiRenderOptions`, `DiagramColors`, `MermaidGraph`, and `PositionedGraph`
|
|
65
|
+
types.
|
|
66
|
+
|
|
67
|
+
These six are not, and each fails differently. `THEMES` is the one that bites
|
|
68
|
+
hardest, because destructuring it yields `undefined` rather than an import
|
|
69
|
+
error, so the failure lands later and elsewhere.
|
|
70
|
+
|
|
71
|
+
| Upstream | Replacement | Notes |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `THEMES` | `{ style: 'name' }` | Theme **names** survive as style names; the map does not. `THEMES['zinc-dark']` → `{ style: 'zinc-dark' }`. |
|
|
74
|
+
| `ThemeName` | `string`, validated by `knownStyles()` | Style names are open — custom styles register at runtime — so there is no closed union to import. |
|
|
75
|
+
| `parseMermaid` | `parseRegisteredMermaid` | **Different shape.** Upstream returns a `MermaidGraph` directly; this returns a result: `{ ok: true, value }` or `{ ok: false, error }`. Check `ok` instead of catching. |
|
|
76
|
+
| `renderMermaid` | `renderMermaidSVGAsync` | Upstream alias for the async SVG renderer. |
|
|
77
|
+
| `renderMermaidSync` | `renderMermaidSVG` | Upstream alias; `renderMermaidSVG` is already synchronous here. |
|
|
78
|
+
| `renderMermaidAscii` | `renderMermaidASCII` | Casing-only alias upstream. This fork exports the capitalised spelling only. |
|
|
79
|
+
|
|
80
|
+
So a `THEMES` port fails at runtime with `TypeError: Cannot read properties of
|
|
81
|
+
undefined (reading 'zinc-dark')`, while `parseMermaid` fails at import — and the
|
|
82
|
+
three aliases fail at import too, which is the easy case.
|
|
83
|
+
|
|
84
|
+
`zinc-light`, `zinc-dark`, `dracula`, `nord`, `tokyo-night`, and the rest of the
|
|
85
|
+
upstream theme names are all valid style names; `knownStyles()` lists every
|
|
86
|
+
registered one.
|
|
87
|
+
|
|
88
|
+
`src/__tests__/upstream-export-migration.test.ts` keeps this table honest: it
|
|
89
|
+
reads upstream's own type declarations and fails if an upstream export is
|
|
90
|
+
neither exported here nor documented above.
|
|
91
|
+
|
|
92
|
+
## Mermaid config and source wrappers
|
|
93
|
+
|
|
94
|
+
This fork supports Mermaid-style source wrappers before diagram headers, including:
|
|
95
|
+
|
|
96
|
+
- YAML frontmatter
|
|
97
|
+
- `%%{init: ...}%%` directives
|
|
98
|
+
- `%%{initialize: ...}%%` directives
|
|
99
|
+
- Mermaid comments before the header
|
|
100
|
+
|
|
101
|
+
These are merged with `options.mermaidConfig` where supported. XY chart and architecture rendering use this to honor Mermaid-compatible theme/config fields.
|
|
102
|
+
|
|
103
|
+
## Showcase and editor discovery
|
|
104
|
+
|
|
105
|
+
Users can discover fork features through:
|
|
106
|
+
|
|
107
|
+
1. The [examples page](https://agentic-mermaid.dev/examples/), including supported families, Style + Palette combinations, and the richer shared examples corpus.
|
|
108
|
+
2. The [live editor](https://agentic-mermaid.dev/editor), which starts with examples for every supported diagram family.
|
|
109
|
+
3. [`README.md`](../README.md) quick starts and docs routing.
|
|
110
|
+
4. [`CHANGELOG.md`](../CHANGELOG.md) for user-facing change history.
|
|
111
|
+
|
|
112
|
+
## Layout and quality work
|
|
113
|
+
|
|
114
|
+
- A layout before/after comparison harness (`eval/layout-compare/`) and per-family `RenderedLayout` adapters so perceptual metrics gate layout changes with evidence. Debug JSON can also expose opt-in graph route certificates, family edge-route certificates, region-containment certificates, and region/action sidecars for tooling; default JSON stays compact.
|
|
115
|
+
- Still different from the current upstream release (Beautiful Mermaid 1.1.3): decision-branch routing emits a diamond's branches from facet-mid ports as mirror-symmetric routes (the layout symmetry floor), and an edge to a subgraph attaches to its container with `direction` overrides honored inside it — a case upstream 1.1.3 still mis-routes (`mermaid-js/mermaid#2509` leaves it unsolved). Both are shown side by side on the [differences page](https://agentic-mermaid.dev/comparisons/).
|
|
116
|
+
- Already upstreamed: fan-in grouping (upstream #68/#69) and labeled fan-out trunk sharing with box-start connector placement (#111/#112/#113, upstream PR #113) landed here first and now render identically in Beautiful Mermaid 1.1.3 — they are no longer fork-only.
|
|
117
|
+
- ER cardinality parsing matches Mermaid's lexer exactly; malformed relationship lines error loudly instead of being silently dropped.
|
|
118
|
+
|
|
119
|
+
## Parser and semantic divergences from Mermaid.js
|
|
120
|
+
|
|
121
|
+
- **Subgraph membership is *first-defined-wins*.** A node belongs to the subgraph
|
|
122
|
+
where it is **first defined**, and a top-level reference counts as a definition —
|
|
123
|
+
so a node referenced at the top level and then listed inside a subgraph block
|
|
124
|
+
stays at the top level. Mermaid.js instead lets the subgraph *block* claim any
|
|
125
|
+
node it lists, regardless of a prior top-level reference. In the canonical Mermaid
|
|
126
|
+
docs example:
|
|
127
|
+
|
|
128
|
+
```mermaid
|
|
129
|
+
flowchart TB
|
|
130
|
+
c1-->a2
|
|
131
|
+
subgraph one
|
|
132
|
+
a1-->a2
|
|
133
|
+
end
|
|
134
|
+
subgraph two
|
|
135
|
+
b1-->b2
|
|
136
|
+
end
|
|
137
|
+
subgraph three
|
|
138
|
+
c1-->c2
|
|
139
|
+
end
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Mermaid.js places `a2` inside `one` and `c1` inside `three`; this fork keeps `a2`
|
|
143
|
+
and `c1` at the top level (only `a1`/`c2` are inside those subgraphs). See it both
|
|
144
|
+
ways: [open in Mermaid Live](https://mermaid.live/edit#pako:eNp10DELwjAQBeC_Et7cDjpmcBBXJ50kyzW5NoU2V9KEIqX_XbSoRXB87z44eDOsOIZG3clkPcWkrkcTlFLK7sryQPs1jLlqIg1eSeC1oe2Zg_txaZK1qZ6u-u98ZN48tF-JAj3HnloHjdkgee7ZQBs4ril3yWBBAcpJLvdgoVPMXCBKbjx0Td3IBfLgKPGppSZS_yYDhZvIJ7Jrk8TzOsRrj-UBwvBYkQ)
|
|
145
|
+
· [open in the fork editor](https://agentic-mermaid.dev/editor/#deflate:q1Yqzi8tSk5VslJKy8kvT85ILCpRCHGKyVNQUFBINtTVtUs0gnCKS5PSixILMhTy81IhIonI0ql5KWjqSsrzISJJIHVJuNVlFKVCTQRbmIxQqVQLAA).
|
|
146
|
+
|
|
147
|
+
This is a deliberate divergence, not a bug: it gives deterministic
|
|
148
|
+
*definition-scope* membership with no surprising re-parenting when a node is
|
|
149
|
+
mentioned again inside a container, consistent with the fork's goal of
|
|
150
|
+
predictable, source-preserving behavior rather than Mermaid pixel/layout parity
|
|
151
|
+
(see [#38](https://github.com/adewale/agentic-mermaid/issues/38)). Mermaid's own
|
|
152
|
+
users report *its* behavior as a bug (`mermaid-js/mermaid#738`, `#2707`). The rule
|
|
153
|
+
is inherited from upstream Beautiful Mermaid (introduced in its v1.0.0 rewrite),
|
|
154
|
+
not fork-invented, and is guarded by `src/__tests__/parser.test.ts` — a node
|
|
155
|
+
genuinely defined inside one subgraph and later referenced inside another
|
|
156
|
+
likewise stays in its first subgraph (it is never re-parented by a mere
|
|
157
|
+
reference).
|
|
158
|
+
|
|
159
|
+
## What is intentionally not in this fork
|
|
160
|
+
|
|
161
|
+
- No committed `dist/` artifacts.
|
|
162
|
+
- No large bundled upstream PR: upstream contributions should remain focused and independently reviewable.
|
|
163
|
+
|
|
164
|
+
## Upstreaming strategy
|
|
165
|
+
|
|
166
|
+
The fork should continue extracting small upstreamable PRs from broad fork work. This file is not the backlog: parked fork-port ideas live only under `PARK-3` in `TODO.md` until one is promoted to a focused issue.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Getting started (library)
|
|
2
|
+
|
|
3
|
+
A 5-minute guide for using `agentic-mermaid` as a plain rendering library: turn a
|
|
4
|
+
Mermaid string into **SVG**, **PNG**, or **ASCII/Unicode**. No agents, no server,
|
|
5
|
+
no browser — every function below runs synchronously in Node, Bun, or the browser.
|
|
6
|
+
|
|
7
|
+
> Editing diagrams with the typed parse → mutate → verify → serialize API is a
|
|
8
|
+
> separate surface — see the [agent API cookbook](./agent-api-cookbook.md). You do
|
|
9
|
+
> not need any of that just to render.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install agentic-mermaid
|
|
15
|
+
# or: bun add agentic-mermaid / pnpm add agentic-mermaid
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For repository development, install from source:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git clone https://github.com/adewale/agentic-mermaid
|
|
22
|
+
cd agentic-mermaid && bun install && bun run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Render to SVG
|
|
26
|
+
|
|
27
|
+
`renderMermaidSVG` takes Mermaid source and returns a self-contained SVG string.
|
|
28
|
+
It supports every registered diagram family (including flowchart, sequence,
|
|
29
|
+
class, ER, state, Gantt, Mindmap, and GitGraph) — just pass the source.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { renderMermaidSVG } from 'agentic-mermaid'
|
|
33
|
+
|
|
34
|
+
const svg = renderMermaidSVG(`flowchart TD
|
|
35
|
+
Start --> Stop`)
|
|
36
|
+
|
|
37
|
+
console.log(svg) // "<svg ...>...</svg>"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Write it to a file in Node/Bun:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { writeFileSync } from 'node:fs'
|
|
44
|
+
import { renderMermaidSVG } from 'agentic-mermaid'
|
|
45
|
+
|
|
46
|
+
writeFileSync('diagram.svg', renderMermaidSVG('flowchart LR\n A --> B --> C'))
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Render to PNG
|
|
50
|
+
|
|
51
|
+
PNG rendering uses a bundled native rasterizer, so `renderMermaidPNG` lives on the
|
|
52
|
+
`agentic-mermaid/agent` entry point. It returns a `Uint8Array` of PNG bytes.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { writeFileSync } from 'node:fs'
|
|
56
|
+
import { renderMermaidPNG } from 'agentic-mermaid/agent'
|
|
57
|
+
|
|
58
|
+
const png = renderMermaidPNG(`flowchart TD
|
|
59
|
+
Start --> Stop`, {
|
|
60
|
+
fitTo: { width: 1200 }, // constrain output width (optional)
|
|
61
|
+
background: '#ffffff', // PNG has no transparency by default
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
writeFileSync('diagram.png', png)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Portable PNG controls are `scale` (default `2`, for retina), `background`, and
|
|
68
|
+
the mutually exclusive `fitTo: { width? }` / `fitTo: { height? }`; the same
|
|
69
|
+
controls are available through the browser adapter, CLI, and local/hosted MCP.
|
|
70
|
+
Node/Bun additionally accepts trusted-host `fontDirs`, `loadSystemFonts`, and
|
|
71
|
+
the library-only `onWarning` callback.
|
|
72
|
+
|
|
73
|
+
## Render to ASCII / Unicode
|
|
74
|
+
|
|
75
|
+
Great for terminals, code reviews, and plain-text logs. Unicode box-drawing is the
|
|
76
|
+
default; pass `{ useAscii: true }` for pure ASCII.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { renderMermaidASCII } from 'agentic-mermaid'
|
|
80
|
+
|
|
81
|
+
const unicode = renderMermaidASCII('flowchart LR\n A --> B')
|
|
82
|
+
const ascii = renderMermaidASCII('flowchart LR\n A --> B', { useAscii: true })
|
|
83
|
+
|
|
84
|
+
console.log(unicode)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See [`ascii.md`](./ascii.md) for supported families and cell-to-region metadata.
|
|
88
|
+
|
|
89
|
+
## Theming
|
|
90
|
+
|
|
91
|
+
Build a palette from two colors, or select one discovered through
|
|
92
|
+
`knownStyleDescriptors()` or `am styles`. Colors are applied
|
|
93
|
+
as CSS variables, so the SVG stays self-contained.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { renderMermaidSVG } from 'agentic-mermaid'
|
|
97
|
+
|
|
98
|
+
// Two-color palette
|
|
99
|
+
const dark = renderMermaidSVG('flowchart TD\n A --> B', {
|
|
100
|
+
bg: '#1a1b26',
|
|
101
|
+
fg: '#a9b1d6',
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// A built-in palette (zinc-light, tokyo-night, nord, dracula, catppuccin-mocha, …)
|
|
105
|
+
const themed = renderMermaidSVG('flowchart TD\n A --> B', {
|
|
106
|
+
style: 'tokyo-night',
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Transparent background, for embedding on any page
|
|
110
|
+
const transparent = renderMermaidSVG('flowchart TD\n A --> B', {
|
|
111
|
+
transparent: true,
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Common `RenderOptions`: `bg`, `fg`, `font`, `transparent`, and `security`. See
|
|
116
|
+
[`theming.md`](./theming.md) for custom Palettes and Shiki/VS Code theme import.
|
|
117
|
+
|
|
118
|
+
### Untrusted input
|
|
119
|
+
|
|
120
|
+
If the Mermaid source is not yours, render with `security: 'strict'`. It disables
|
|
121
|
+
the web-font `@import` and strips any external-fetch references from the output, so
|
|
122
|
+
the SVG cannot phone home.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { renderMermaidSVG } from 'agentic-mermaid'
|
|
126
|
+
|
|
127
|
+
const safe = renderMermaidSVG(userProvidedSource, { security: 'strict' })
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## In the browser and in frameworks
|
|
131
|
+
|
|
132
|
+
`renderMermaidSVG` is synchronous and needs no DOM, so you can render during a
|
|
133
|
+
component's render pass and drop the string straight into the markup. In React,
|
|
134
|
+
memoize it to avoid re-rendering on every paint:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { useMemo } from 'react'
|
|
138
|
+
import { renderMermaidSVG } from 'agentic-mermaid'
|
|
139
|
+
|
|
140
|
+
function Diagram({ code }: { code: string }) {
|
|
141
|
+
const svg = useMemo(() => renderMermaidSVG(code), [code])
|
|
142
|
+
return <div dangerouslySetInnerHTML={{ __html: svg }} />
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
See [`react.md`](./react.md) for the zero-flash, live-theme-switching setup.
|
|
147
|
+
|
|
148
|
+
## Which import path?
|
|
149
|
+
|
|
150
|
+
| You want | Import from |
|
|
151
|
+
|---|---|
|
|
152
|
+
| SVG | `agentic-mermaid` |
|
|
153
|
+
| ASCII / Unicode | `agentic-mermaid` |
|
|
154
|
+
| PNG (native rasterizer) | `agentic-mermaid/agent` |
|
|
155
|
+
| Palettes (`knownStyleDescriptors`, `fromShikiTheme`) | `agentic-mermaid` |
|
|
156
|
+
| Everything in one path | `agentic-mermaid/agent` |
|
|
157
|
+
| Typed editing (parse/mutate/verify) | `agentic-mermaid/agent` |
|
|
158
|
+
|
|
159
|
+
`agentic-mermaid/agent` re-exports the renderers too, so if you would rather use a
|
|
160
|
+
single import path for all formats, import everything from there.
|
|
161
|
+
|
|
162
|
+
## Prefer the command line?
|
|
163
|
+
|
|
164
|
+
The same renderers ship as the `am` CLI — no code required. After the local
|
|
165
|
+
install above, use the package runner so the command resolves without a global
|
|
166
|
+
install:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npx --no-install agentic-mermaid render diagram.mmd --format svg
|
|
170
|
+
npx --no-install agentic-mermaid render diagram.mmd --format png --output diagram.png
|
|
171
|
+
npx --no-install agentic-mermaid render diagram.mmd --format ascii
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Run `npx --no-install agentic-mermaid --help` for the full command set. Inside
|
|
175
|
+
an npm script, the shorter `am …` binary name is available automatically.
|
|
176
|
+
|
|
177
|
+
## Next steps
|
|
178
|
+
|
|
179
|
+
- [`diagram-families.md`](./diagram-families.md) — every supported family with examples.
|
|
180
|
+
- [`theming.md`](./theming.md) — custom themes and Shiki import.
|
|
181
|
+
- [`api.md`](./api.md) — the full option and function reference.
|
|
182
|
+
- [`agent-api-cookbook.md`](./agent-api-cookbook.md) — typed editing (parse → mutate → verify → serialize).
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Issue-derived coverage evidence
|
|
2
|
+
|
|
3
|
+
Status: evidence and coverage inventory, not a fixture backlog. Root `TODO.md` is
|
|
4
|
+
the sole authority for scheduled work. Uncovered fixture and heuristic ideas
|
|
5
|
+
below are unscheduled unless a stable root TODO item promotes them.
|
|
6
|
+
|
|
7
|
+
These public Mermaid / Beautiful Mermaid issues explain what the existing
|
|
8
|
+
fixtures cover and preserve candidate evidence for future decisions. The goal is
|
|
9
|
+
not to clone every upstream bug; it is to retain representative examples that
|
|
10
|
+
teach the renderer/agent surface what users actually expect.
|
|
11
|
+
|
|
12
|
+
## Already covered or newly covered
|
|
13
|
+
|
|
14
|
+
- [mermaid-js/mermaid#5227 — Backwards arrows](https://github.com/mermaid-js/mermaid/issues/5227)
|
|
15
|
+
- Why it matters: feedback edges are common in auth/retry flows and should not scramble the primary left-to-right path.
|
|
16
|
+
- Current coverage: `src/__tests__/agent-auth-flow.test.ts` builds an auth flow through Agentic Mermaid mutations and asserts `C→B` / `F→E` route backwards while the primary LR path stays source-ordered.
|
|
17
|
+
- [mermaid-js/mermaid#7645 — block loading of external images](https://github.com/mermaid-js/mermaid/issues/7645)
|
|
18
|
+
- Why it matters: agent-generated diagrams are untrusted input.
|
|
19
|
+
- Current coverage: strict SVG/security tests assert external-fetch references are removed.
|
|
20
|
+
- [mermaid-js/mermaid#7695 — Trusted Types / CSP](https://github.com/mermaid-js/mermaid/issues/7695)
|
|
21
|
+
- Why it matters: generated SVG/HTML must be embeddable in locked-down apps.
|
|
22
|
+
- Current coverage: browser CSP/Trusted Types e2e exercises enforcement and strict render paths.
|
|
23
|
+
- [mermaid-js/mermaid#5632 — screen-reader/accessibility support](https://github.com/mermaid-js/mermaid/issues/5632)
|
|
24
|
+
- Why it matters: diagrams need non-visual summaries for users and agents.
|
|
25
|
+
- Current coverage: `am describe` / `describeMermaid(...,{format:'json'})` expose an AX-style tree and docs sync tests guard the surface.
|
|
26
|
+
- [lukilabs/beautiful-mermaid#119 — CJK label alignment](https://github.com/lukilabs/beautiful-mermaid/issues/119)
|
|
27
|
+
- Why it matters: ASCII renderers often break on fullwidth text.
|
|
28
|
+
- Current coverage: CJK width tests and ASCII rendering tests.
|
|
29
|
+
- [lukilabs/beautiful-mermaid#115 — text contrast on custom fills](https://github.com/lukilabs/beautiful-mermaid/issues/115)
|
|
30
|
+
- Why it matters: themeable diagrams must remain readable.
|
|
31
|
+
- Current coverage: auto-contrast and theme/renderer contrast tests.
|
|
32
|
+
- [lukilabs/beautiful-mermaid#111/#112 — ASCII fan-out trunks and box-start connectors](https://github.com/lukilabs/beautiful-mermaid/issues/111)
|
|
33
|
+
- Why it matters: sibling fan-outs should share a readable trunk and edge labels should stay on branches rather than forcing detours or floating connectors.
|
|
34
|
+
- Current coverage: `src/__tests__/ascii-pathfinder-trunk.test.ts` covers TD/LR labeled fan-out repros and bidirectional-label separation; `src/__tests__/ascii-box-start.test.ts` covers source-border connectors; ASCII determinism tests guard repeated routing stability; golden files pin exact ASCII/Unicode output.
|
|
35
|
+
- [lukilabs/beautiful-mermaid#69 — fan-in grouping](https://github.com/lukilabs/beautiful-mermaid/pull/69)
|
|
36
|
+
- Why it matters: unrelated fan-in groups should not cross into ambiguous shared trunks.
|
|
37
|
+
- Current coverage: `src/__tests__/ascii-fan-in-grouping.test.ts` covers target-aware grouping and cycle guards.
|
|
38
|
+
- [lukilabs/beautiful-mermaid#98 — nested-subgraph layout with direction](https://github.com/lukilabs/beautiful-mermaid/pull/98)
|
|
39
|
+
- Why it matters: subgraph direction overrides and container edges should not create phantom nodes or move children outside groups.
|
|
40
|
+
- Current coverage: `src/__tests__/subgraph-direction.test.ts` covers SVG geometry, ASCII one-row inner LR layout, subgraph-id edge attachment, 7-bit ASCII mode, nested child subgraph targets, styled/labeled container edges, and multi-edge containers; golden files pin exact ASCII/Unicode output.
|
|
41
|
+
- [lukilabs/beautiful-mermaid#121 — ER/class ASCII label truncation and stray connectors](https://github.com/lukilabs/beautiful-mermaid/issues/121)
|
|
42
|
+
- Why it matters: ER/class ASCII labels and compartment text are semantic content, not decoration; long labels must not silently disappear when connectors are tight.
|
|
43
|
+
- Current coverage: exact ASCII/Unicode golden files cover class compartments/relationship labels and ER relationship labels. ER same-row layout now widens the inter-entity gap to preserve full labels.
|
|
44
|
+
|
|
45
|
+
## Candidate fixture evidence (unscheduled)
|
|
46
|
+
|
|
47
|
+
- [mermaid-js/mermaid#6271 — unexpected graph direction](https://github.com/mermaid-js/mermaid/issues/6271)
|
|
48
|
+
- Suggested fixture: a graph whose author order implies a clear primary direction but whose cross/back edges tempt the layout engine to flip ranks. Assert source-order progression and bounded aspect ratio.
|
|
49
|
+
- [mermaid-js/mermaid#7785 — collapsible subgraphs via `@{ view: collapsed }`](https://github.com/mermaid-js/mermaid/pull/7785)
|
|
50
|
+
- Suggested fixture: parse/render normal nested subgraphs today; when collapse metadata appears, either model it explicitly or preserve source as opaque. Never silently drop the `@{ ... }` meaning.
|
|
51
|
+
- [Mermaid v11.3+ `@{ shape: ... }` typed node metadata](https://mermaid.js.org/syntax/flowchart.html) — **safety floor fixed as BUILD-23 / [#29](https://github.com/adewale/agentic-mermaid/issues/29); full typed-shape vocabulary remains #44**
|
|
52
|
+
- Why it matters: this syntax carries the ISO 5807/ANSI X3.5 flowchart symbol vocabulary (manual input, document, delay, preparation, …); Mermaid's docs use it extensively, so agent-generated sources will contain it.
|
|
53
|
+
- Current behavior (June 2026): the three issue #29 repro classes are pinned by `src/__tests__/flowchart-metadata.test.ts`; they no longer silently drop targets/edges or fabricate `shape`/`label` phantom nodes. Unsupported forms preserve source opaquely; supported label metadata renders as a conservative rectangle fallback.
|
|
54
|
+
- Candidate coverage: #44 records the full Mermaid v11 typed-shape vocabulary without weakening the no-silent-loss safety floor; this ledger does not schedule it.
|
|
55
|
+
- [Mermaid frontmatter `config.layout`/`config.look`](https://mermaid.js.org/intro/syntax-reference.html) — **wrapper-fidelity gaps found by probing the official examples, fixed as BUILD-21**
|
|
56
|
+
- Why it mattered: round-tripping a diagram through the editor flattened `config:`-nested frontmatter to top-level keys Mermaid ignores (silently killing the author's layout/look request on interop), duplicated `%%{init}%%` directives into synthesized frontmatter, and dropped leading comments.
|
|
57
|
+
- Current coverage: `src/__tests__/agent-wrapper-fidelity.test.ts` pins byte-verbatim wrapper round-trip (frontmatter, directives incl. multiline, leading comments, combined), mutation wrapper preservation, canonical-mode config nesting + directive folding, and the `COMMENT_DROPPED` lint matrix.
|
|
58
|
+
|
|
59
|
+
## Fork-network layout search notes
|
|
60
|
+
|
|
61
|
+
A May 2026 GitHub issue/PR search found recurring layout-quality themes in both Mermaid and Beautiful Mermaid:
|
|
62
|
+
|
|
63
|
+
- [mermaid-js/mermaid#6049 — Flowchart ugly self linking nodes](https://github.com/mermaid-js/mermaid/issues/6049)
|
|
64
|
+
- Fixture status: `src/__tests__/aesthetic-issue-regressions.test.ts` renders a flowchart self-loop and asserts the loop has no hard geometric defects; `src/__tests__/layout-quality-heuristics.test.ts` keeps the broader self-loop clearance guard.
|
|
65
|
+
- [mermaid-js/mermaid#5060 — Avoidable overlapping curves in flow-chart](https://github.com/mermaid-js/mermaid/issues/5060)
|
|
66
|
+
- Fixture status: `src/__tests__/aesthetic-issue-regressions.test.ts` renders repeated parallel labeled edges and asserts distinct edge paths, zero crossings, no hard defects, and separated label boxes.
|
|
67
|
+
- [mermaid-js/mermaid#6046 — subgraph links should affect positioning more than inter-graph links](https://github.com/mermaid-js/mermaid/issues/6046)
|
|
68
|
+
- Candidate fixture evidence: nested subgraphs with invisible/loose links; group order follows source intent and cross-group edges do not dominate internal layout.
|
|
69
|
+
- [mermaid-js/mermaid#2792 — graph lines sometimes overlap boxes](https://github.com/mermaid-js/mermaid/issues/2792)
|
|
70
|
+
- Fixture status: `src/__tests__/aesthetic-issue-regressions.test.ts` renders a transitive route and asserts the ugly-detector reports no edge-through-node defect.
|
|
71
|
+
- [lukilabs/beautiful-mermaid#83 — TD/TB flowchart layout flipping horizontal](https://github.com/lukilabs/beautiful-mermaid/issues/83)
|
|
72
|
+
- Candidate fixture evidence: vertical process with repeated feedback edges; TD/TB diagrams remain height-dominant or within a bounded aspect ratio.
|
|
73
|
+
- [lukilabs/beautiful-mermaid#68 — fan-in groups not target-aware](https://github.com/lukilabs/beautiful-mermaid/issues/68)
|
|
74
|
+
- Candidate fixture evidence: multiple roots feeding separate targets; roots cluster by target and unrelated routes do not share misleading trunks.
|
|
75
|
+
- [lukilabs/beautiful-mermaid#63 — misleading edge overlap in routing](https://github.com/lukilabs/beautiful-mermaid/pull/63)
|
|
76
|
+
- Candidate fixture evidence: two fan-in edges followed by two fan-out edges; an outgoing branch does not visually reuse an unrelated incoming corridor.
|
|
77
|
+
- [lukilabs/beautiful-mermaid#89 — CJK subgraph title layout drift](https://github.com/lukilabs/beautiful-mermaid/issues/89)
|
|
78
|
+
- Candidate fixture evidence: fullwidth group labels; group header bounds account for CJK width.
|
|
79
|
+
- [lukilabs/beautiful-mermaid#121 — ER/class ASCII labels truncated/overlapping](https://github.com/lukilabs/beautiful-mermaid/issues/121)
|
|
80
|
+
- Fixture status: representative class/ER golden files now assert labels survive and connectors remain attached; keep this theme in the generated matrix for longer label/attribute variants.
|
|
81
|
+
|
|
82
|
+
## Aesthetic-issue coverage audit (issue-keyed)
|
|
83
|
+
|
|
84
|
+
A June 2026 audit turned the 13 layout-aesthetic complaints in
|
|
85
|
+
[`mermaid-layout-complaints.md`](./mermaid-layout-complaints.md) into an
|
|
86
|
+
explicit coverage ledger. Direct issue-keyed fixtures now guard the complaints
|
|
87
|
+
that can be expressed against supported diagram families; broader existing
|
|
88
|
+
assertions are tagged where they already covered the behavior; unsupported,
|
|
89
|
+
deferred, and policy-out-of-scope cases remain recorded below.
|
|
90
|
+
|
|
91
|
+
- **Issue-keyed regression fixtures** —
|
|
92
|
+
[`src/__tests__/aesthetic-issue-regressions.test.ts`](../src/__tests__/aesthetic-issue-regressions.test.ts)
|
|
93
|
+
renders a small repro graph per complaint and asserts, through the real
|
|
94
|
+
renderer, that Agentic Mermaid does not exhibit it: `#6476` (avoidable edge
|
|
95
|
+
crossings → 0 on a planar bipartite graph), `#5601` (planar state diagram
|
|
96
|
+
stays planar), `#5060` (parallel labeled edges use distinct rendered paths,
|
|
97
|
+
keep labels separate, and produce no geometric defects),
|
|
98
|
+
`#2792` (transitive edge does not pass through an intervening node, via the
|
|
99
|
+
ugly-detector `edge-through-node` check), `#2131` (edge labels keep
|
|
100
|
+
clearance from unrelated nodes and from each other), and `#6336`/`#6049`
|
|
101
|
+
(state and flowchart self-loops render without hard defects).
|
|
102
|
+
- **Tagged existing assertions** (now greppable by issue number): `#815`
|
|
103
|
+
(declared node/source order — `agent-auth-flow.test.ts`,
|
|
104
|
+
`layout-quality-heuristics.test.ts`), `#1984`/`#3262` (scale-collapse
|
|
105
|
+
whitespace + aspect — `agent-quality.test.ts`), `#1301` (long-range Gantt
|
|
106
|
+
axis labels stay clear of task bars — `gantt-layout.test.ts`), and `#1765` (activation/note/block
|
|
107
|
+
clearance — `sequence-layout.test.ts`).
|
|
108
|
+
- **`#3723` (same-rank constraint)** — planned under `BUILD-24` as typed
|
|
109
|
+
request/mutation metadata, not new Mermaid syntax; its fixture lands with
|
|
110
|
+
that implementation. **`#5420` (manual node positioning)** remains out of
|
|
111
|
+
scope: arbitrary coordinates and dragging are distinct from structural
|
|
112
|
+
auto-layout constraints. There is therefore no #5420 regression fixture.
|
|
113
|
+
|
|
114
|
+
These guards assert "Agentic Mermaid does not exhibit the complaint," not
|
|
115
|
+
"the upstream Mermaid bug is fixed" — every cited issue is a defect in
|
|
116
|
+
mermaid-js's own dagre renderer, which this fork does not share (see
|
|
117
|
+
[`mermaid-layout-complaints.md`](./mermaid-layout-complaints.md) R4).
|
|
118
|
+
|
|
119
|
+
## Programmatic bad-layout heuristics
|
|
120
|
+
|
|
121
|
+
Current useful heuristics:
|
|
122
|
+
|
|
123
|
+
- `verifyMermaid` warnings: `OFF_CANVAS`, `GROUP_BREACH`, `NODE_OVERLAP`, `ROUTE_SELF_CROSS`, `LABEL_OVERFLOW`, `DUPLICATE_EDGE`, `UNREACHABLE_NODE`;
|
|
124
|
+
- `measureQuality(layoutMermaid(d))` / `checkQuality(...)`: edge crossings, label legibility, whitespace balance, edge-label clearance from non-attached nodes, other edge labels, and other edge paths, and aspect ratio;
|
|
125
|
+
- issue-keyed fixtures that gate selected repro diagrams individually, including zero crossings and label-vs-label box separation for parallel edge labels;
|
|
126
|
+
- family-specific geometry assertions, such as Auth Flow's source-order progression and backward feedback-edge routing;
|
|
127
|
+
- layout-quality heuristic tests for declared-direction progress (`TD`/`BT`/`LR`/`RL`), edge-vs-node collisions excluding attached endpoints, feedback-process cleanliness, root node vs top-level subgraph source order, and self-loop clearance;
|
|
128
|
+
- PNG/SVG screenshot comparison for artifacts that layout JSON cannot see, such as rounded-fill raster artifacts.
|
|
129
|
+
|
|
130
|
+
Candidate heuristic evidence (unscheduled):
|
|
131
|
+
|
|
132
|
+
- route corridor reuse by unrelated edge families;
|
|
133
|
+
- target-aware fan-in/fan-out clustering score;
|
|
134
|
+
- group-header text fit, especially with CJK/fullwidth labels.
|
|
135
|
+
|
|
136
|
+
Convention-derived validator candidates (from the ANSI X3.5/ISO 5807
|
|
137
|
+
drafting conventions catalogued in
|
|
138
|
+
[`mermaid-layout-complaints.md`](./mermaid-layout-complaints.md) R3 —
|
|
139
|
+
practitioner guides consistently name these as the top flowchart mistakes):
|
|
140
|
+
|
|
141
|
+
- **unlabeled decision branches**: a diamond node with two or more outgoing
|
|
142
|
+
edges where any edge lacks a label — cheap Tier 3 lint candidate
|
|
143
|
+
(`DECISION_BRANCH_UNLABELED`); complements issue #25 §8.2 diamond port
|
|
144
|
+
semantics;
|
|
145
|
+
- **entry/exit shape**: flowcharts conventionally have one start (a single
|
|
146
|
+
in-degree-0 node) and clearly marked endpoints (at least one sink) —
|
|
147
|
+
fits issue #26 workstream 14 as an analysis fact alongside the existing
|
|
148
|
+
graph entry/feedback-edge outputs, not as a hard error.
|
|
149
|
+
|
|
150
|
+
If promoted through root `TODO.md`, these could drive a generated fixture matrix
|
|
151
|
+
varying direction, feedback-edge density, self-loops, parallel edges, label
|
|
152
|
+
length, CJK labels, nested subgraphs, fan-in/fan-out shape, and styling. Each
|
|
153
|
+
case would assert semantic preservation first, then one or more layout
|
|
154
|
+
heuristics; screenshot tests would be reserved for genuinely pixel/raster-level
|
|
155
|
+
artifacts.
|
|
156
|
+
|
|
157
|
+
## Test-design rules for issue fixtures
|
|
158
|
+
|
|
159
|
+
- Prefer smallest meaningful source examples over screenshots alone.
|
|
160
|
+
- Assert semantics first: labels, edges, groups, source-preserved metadata.
|
|
161
|
+
- Use screenshot/SVG regression only when geometry/visual polish is the bug.
|
|
162
|
+
- For unsupported Mermaid syntax, assert opaque/source-preserved fallback rather than lossy normalization.
|
|
163
|
+
- For security issues, assert both removal of dangerous refs and preservation of safe SVG output.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# MCP Code Mode rationale
|
|
2
|
+
|
|
3
|
+
Local `agentic-mermaid-mcp` is intentionally Code Mode first. Its primary tool is `execute(code)`, which runs synchronous JavaScript against the typed `mermaid.*` SDK in a local `node:vm` sandbox. This is a local implementation inspired by Code Mode as a product shape; it is not Cloudflare Codemode, not backed by `@cloudflare/codemode`, and not an OS/container security boundary. The local helper tools (`describe_sdk`, `render_png`, and `describe`) are narrow conveniences, not a second full authoring API.
|
|
4
|
+
|
|
5
|
+
There is now also a **hosted** MCP at `https://agentic-mermaid.dev/mcp` (stateless Streamable HTTP; see the [as-built record](./project/archive/hosted-mcp-cloudflare-plan.md)). It keeps `execute` but runs agent code in a per-request Cloudflare Dynamic Worker isolate (`globalOutbound: null`, empty env, `cpuMs` budget) instead of a local `node:vm` — there the isolate configuration *is* the security boundary — and adds `describe_sdk` plus direct `render_svg`/`render_ascii`/`render_png`/`verify`/`describe` tools so schema discovery and common render/verify paths avoid a billable isolate, plus the declarative `mutate`/`build` tools (see below). Both share the same hardened `mermaid.*` facade; their semantics are pinned against each other by a differential test suite, with one explicit host-policy divergence: both hosted `renderMermaidSVG*` execute methods and the direct `render_svg` tool force `security: 'strict'` and `embedFontImport: false`, even if agent code asks for weaker values. Local Code Mode retains the library's caller-selectable policy.
|
|
6
|
+
|
|
7
|
+
## Why the MCP server exists
|
|
8
|
+
|
|
9
|
+
Agents often need a multi-step diagram transaction:
|
|
10
|
+
|
|
11
|
+
1. parse source;
|
|
12
|
+
2. narrow to a mutable family;
|
|
13
|
+
3. apply one or more typed mutations;
|
|
14
|
+
4. verify and inspect the result;
|
|
15
|
+
5. serialize only after verify passes.
|
|
16
|
+
|
|
17
|
+
As separate MCP tools, that workflow becomes many tool calls and loses useful in-call state. In Code Mode it is one call: the agent writes the small algorithm and the server preserves lineage/tracing inside the execution.
|
|
18
|
+
|
|
19
|
+
## Code Mode first, plus a narrow declarative edit surface
|
|
20
|
+
|
|
21
|
+
Code Mode stays the primary tool for multi-step logic. But `execute` asks the
|
|
22
|
+
model to write correct sandboxed JavaScript, and a weaker model drives that
|
|
23
|
+
poorly (serialization pitfalls, provenance rules, sync-only constraints) when
|
|
24
|
+
all it wanted was to apply a few structured edits. So the hosted surface adds
|
|
25
|
+
exactly **two** declarative tools — `mutate` (edit a `source`) and `build`
|
|
26
|
+
(author from a `family`) — that take a JSON op list and return one canonical
|
|
27
|
+
`{ ok, family, source, verify }` envelope. They run verify internally and only
|
|
28
|
+
emit source when it passes, so the verify-before-commit contract holds without
|
|
29
|
+
the model writing it. Both funnel through the same validated `mutateChecked`
|
|
30
|
+
core as Code Mode's `mermaid.mutate`, so an op is rejected identically either
|
|
31
|
+
way — there is no second implementation to drift.
|
|
32
|
+
|
|
33
|
+
We still do **not** explode the surface into `parse`/`narrow`/`serialize`/… as
|
|
34
|
+
separate tools: those are the composable steps `execute` exists to sequence in
|
|
35
|
+
one call, and a full per-operation MCP API would multiply round trips, weaken
|
|
36
|
+
in-call lineage, and be another public contract to keep in lockstep. `mutate`
|
|
37
|
+
and `build` are the deliberate exception because a *structured edit* is the one
|
|
38
|
+
workflow that (a) is common, (b) needs no arbitrary logic, and (c) a weak model
|
|
39
|
+
gets wrong through `execute`. For everything richer, use `execute`, the CLI
|
|
40
|
+
(`am mutate --ops`, `am verify`, `am render`), or a library import.
|
|
41
|
+
|
|
42
|
+
## What the non-Code-Mode MCP tools are for
|
|
43
|
+
|
|
44
|
+
Local MCP keeps only three helpers:
|
|
45
|
+
|
|
46
|
+
- `describe_sdk({ family, detail })` returns version-matched mutation operations for one family without running Code Mode. `detail: "signatures"` returns a compact menu; `detail: "fields"` returns the exact field schema. The initial `execute` declaration stays limited to the core SDK, while `mermaid.describeOps` and `mermaid.opSignatures` expose the same registry inside an execution.
|
|
47
|
+
|
|
48
|
+
- `render_png(source)` exists because PNG is binary output and returning base64 from a dedicated MCP tool is simpler than putting binary handling into Code Mode snippets. Local and hosted tools share portable `scale`, `background`, and mutually exclusive `fitTo.width`/`fitTo.height` controls; local additionally accepts trusted-host `fontDirs`/`loadSystemFonts` remedies and returns deterministic configuration/font-coverage warnings. For clients that cannot comfortably carry large base64 payloads, `render_png({source, output:"file"})` writes a managed local artifact and `output:"url"` returns an HTTP-served artifact when the server runs with HTTP/SSE transport. Because those modes create managed files, the local tool is annotated as non-read-only and non-idempotent.
|
|
49
|
+
- `describe(source)` exists because one-shot natural-language summaries are common for screen readers, docs, and context compaction.
|
|
50
|
+
|
|
51
|
+
The hosted endpoint adds the same direct discovery tool and direct pure tools (`render_svg`, `render_ascii`, `render_png`, `verify`, `describe`) because every hosted `execute` contacts a Dynamic Worker; schema discovery and common render/verify calls should be ordinary Worker invocations eligible for the private compute cache. Hosted `mutate` and `build` are the only declarative authoring tools, and they exist to apply typed op lists with the verify-before-emit contract without asking a weaker model to write JavaScript. They do not introduce a separate mutation engine.
|
|
52
|
+
|
|
53
|
+
Direct render tools accept shared render fields only through the canonical
|
|
54
|
+
nested `options` object, generated from the shared RenderOptions descriptors.
|
|
55
|
+
Palette selection uses `options.style`; `theme` and top-level
|
|
56
|
+
`bg`/`fg`/`style`/`seed` are not tool inputs.
|
|
57
|
+
|
|
58
|
+
Local managed artifacts are generated under one exclusively owned server artifact directory with safe names, per-file and aggregate limits, persisted TTL cleanup, MIME type, byte count, and SHA-256 integrity metadata; they are not arbitrary user-chosen file writes. A second live owner fails closed instead of racing a stale manifest. Hosted `render_png` returns base64 only.
|
|
59
|
+
|
|
60
|
+
## Equivalence example
|
|
61
|
+
|
|
62
|
+
`examples/mcp-vs-cli-complex-diagrams.ts` builds the same complicated diagrams two ways: an Auth Flow flowchart with feedback loops and an Order Domain ER diagram.
|
|
63
|
+
|
|
64
|
+
- MCP Code Mode: `tools/call execute` runs parse → narrow → mutate[] → verify → serialize.
|
|
65
|
+
- CLI: `am mutate <diagram>.mmd --ops ops.json --json` runs the same typed mutation batch and verify-before-emit contract.
|
|
66
|
+
|
|
67
|
+
The example asserts that both channels produce byte-identical Mermaid source for every case. This is the supported equivalence story: **MCP Code Mode and CLI/library can produce the same diagrams**. Hosted `mutate`/`build` are a bounded shortcut for the same typed op-list workflows, not a replacement for Code Mode when custom control flow is needed.
|
|
68
|
+
|
|
69
|
+
## Transports
|
|
70
|
+
|
|
71
|
+
The default transport is stdio for local MCP clients:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
agentic-mermaid-mcp
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
HTTP/SSE reachability is available when a client needs a network endpoint. See [`mcp-http-transport.md`](./mcp-http-transport.md) for the full quickstart, JSON-RPC examples, option table, and security defaults:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
agentic-mermaid-mcp --transport http --host 127.0.0.1 --port 3000 \
|
|
81
|
+
--artifact-dir .agentic-mermaid-artifacts
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The HTTP transport exposes `/sse` for MCP SSE sessions, `/message?sessionId=...` for session messages, `/rpc` for direct JSON-RPC tests/integrations, `/health`, and `/artifacts/<name>` for managed outputs. It binds to loopback by default; non-loopback binding requires `--auth-token`, and `/rpc`/`/message` require `content-type: application/json` so browser-simple CSRF posts are rejected. Use an explicit host only when you have reviewed the sandbox and artifact exposure boundary.
|
|
85
|
+
|
|
86
|
+
Example stdio `.mcp.json` entry:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"agentic-mermaid": {
|
|
92
|
+
"command": "npx",
|
|
93
|
+
"args": ["-y", "agentic-mermaid-mcp"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Example HTTP launch command for clients that manage MCP SSE URLs separately:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npx -y agentic-mermaid-mcp --transport http --host 127.0.0.1 --port 3000
|
|
103
|
+
# non-loopback requires --auth-token <token>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## When to add more MCP tools
|
|
107
|
+
|
|
108
|
+
Add another non-Code-Mode MCP tool only with evidence that a real client cannot use `execute`, hosted `mutate`/`build`, or the CLI/library path. Until then, keep the surface small: one compositional tool, direct pure render/verify/describe tools where they avoid hosted isolate cost, and the two declarative structured-edit tools.
|