agentic-mermaid 0.4.1 → 0.5.3

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.
Files changed (253) hide show
  1. package/AGENT_NATIVE.md +94 -627
  2. package/CHANGELOG.md +651 -0
  3. package/Instructions_for_agents.md +44 -23
  4. package/LICENSES/Khroma-MIT.txt +21 -0
  5. package/LICENSES/Mermaid-MIT.txt +21 -0
  6. package/LICENSES/es-toolkit-MIT.txt +21 -0
  7. package/LICENSES/pele-MIT.txt +40 -0
  8. package/LICENSES/zenuml-core-MIT.txt +21 -0
  9. package/README.md +93 -50
  10. package/SECURITY.md +28 -12
  11. package/THIRD_PARTY_NOTICES.md +60 -0
  12. package/assets/hero.png +0 -0
  13. package/dist/agent-core.d.ts +478 -210
  14. package/dist/agent-core.js +1 -396
  15. package/dist/agent.d.ts +17 -8
  16. package/dist/agent.js +1 -408
  17. package/dist/agentic-mermaid-mcp.js +1 -11
  18. package/dist/am.js +1 -34562
  19. package/dist/browser-lazy/chunks/agentic-producer-core-CC6OOLDW.js +1 -0
  20. package/dist/browser-lazy/chunks/architecture-QUFVKYJR.js +13 -0
  21. package/dist/browser-lazy/chunks/block-6J3Q63BO.js +11 -0
  22. package/dist/browser-lazy/chunks/builtin-backends-7SOZZHPF.js +12 -0
  23. package/dist/browser-lazy/chunks/c4-SQVBZAKJ.js +10 -0
  24. package/dist/browser-lazy/chunks/chunk-2GPK4VFF.js +5 -0
  25. package/dist/browser-lazy/chunks/chunk-2I4UPL7Q.js +3 -0
  26. package/dist/browser-lazy/chunks/chunk-2SH76OTH.js +1 -0
  27. package/dist/browser-lazy/chunks/chunk-2UIA2IME.js +3 -0
  28. package/dist/browser-lazy/chunks/chunk-4LHYF3BS.js +1 -0
  29. package/dist/browser-lazy/chunks/chunk-5B2Z7575.js +1 -0
  30. package/dist/browser-lazy/chunks/chunk-5FQ534HP.js +1 -0
  31. package/dist/browser-lazy/chunks/chunk-5UVGUSD6.js +1 -0
  32. package/dist/browser-lazy/chunks/chunk-5X6MJX3H.js +1 -0
  33. package/dist/browser-lazy/chunks/chunk-AMJLVPUB.js +4 -0
  34. package/dist/browser-lazy/chunks/chunk-BU5LHXNJ.js +3 -0
  35. package/dist/browser-lazy/chunks/chunk-BY2CPG6B.js +1 -0
  36. package/dist/browser-lazy/chunks/chunk-CN7WTBWB.js +1 -0
  37. package/dist/browser-lazy/chunks/chunk-CQE4HQEW.js +1 -0
  38. package/dist/browser-lazy/chunks/chunk-CSFUKSU6.js +1 -0
  39. package/dist/browser-lazy/chunks/chunk-DF6765YX.js +17 -0
  40. package/dist/browser-lazy/chunks/chunk-E2WMJZNM.js +1 -0
  41. package/dist/browser-lazy/chunks/chunk-FAIMVOX5.js +6 -0
  42. package/dist/browser-lazy/chunks/chunk-GVOEAY52.js +1 -0
  43. package/dist/browser-lazy/chunks/chunk-HLWUNUCM.js +1 -0
  44. package/dist/browser-lazy/chunks/chunk-ICC7HBJX.js +1 -0
  45. package/dist/browser-lazy/chunks/chunk-J35HAQQF.js +20 -0
  46. package/dist/browser-lazy/chunks/chunk-J7FFAFQF.js +1 -0
  47. package/dist/browser-lazy/chunks/chunk-LH7HUDKW.js +1 -0
  48. package/dist/browser-lazy/chunks/chunk-N5ELX7LR.js +2 -0
  49. package/dist/browser-lazy/chunks/chunk-NMQQMRIR.js +1 -0
  50. package/dist/browser-lazy/chunks/chunk-NO7ZIVRU.js +1 -0
  51. package/dist/browser-lazy/chunks/chunk-OZ443IVJ.js +16 -0
  52. package/dist/browser-lazy/chunks/chunk-PQGPS2YV.js +7 -0
  53. package/dist/browser-lazy/chunks/chunk-QA6GJQ4X.js +1 -0
  54. package/dist/browser-lazy/chunks/chunk-RIVTHZAQ.js +1 -0
  55. package/dist/browser-lazy/chunks/chunk-SZELX2EJ.js +1 -0
  56. package/dist/browser-lazy/chunks/chunk-TYZOZXUJ.js +22 -0
  57. package/dist/browser-lazy/chunks/chunk-UL6NDWLL.js +1 -0
  58. package/dist/browser-lazy/chunks/chunk-VQYYGAXP.js +1 -0
  59. package/dist/browser-lazy/chunks/chunk-VWVZGQE2.js +1 -0
  60. package/dist/browser-lazy/chunks/chunk-X2UYKWKM.js +4 -0
  61. package/dist/browser-lazy/chunks/chunk-YCEICNM6.js +1 -0
  62. package/dist/browser-lazy/chunks/chunk-Z3FDIVLN.js +20 -0
  63. package/dist/browser-lazy/chunks/class-5QA4SCTS.js +13 -0
  64. package/dist/browser-lazy/chunks/decode-63UIZGD2.js +1 -0
  65. package/dist/browser-lazy/chunks/elk.bundled-L4CADV5W.js +24 -0
  66. package/dist/browser-lazy/chunks/er-7ZSKGN7Y.js +11 -0
  67. package/dist/browser-lazy/chunks/eventmodeling-2BPLHWRN.js +19 -0
  68. package/dist/browser-lazy/chunks/flowchart-NEIMZTB5.js +4 -0
  69. package/dist/browser-lazy/chunks/forest-implementation-AEP24AIP.js +1 -0
  70. package/dist/browser-lazy/chunks/gantt-RDPIFYAF.js +11 -0
  71. package/dist/browser-lazy/chunks/gitgraph-N4Y5RYB7.js +9 -0
  72. package/dist/browser-lazy/chunks/ishikawa-LD3YBDJN.js +6 -0
  73. package/dist/browser-lazy/chunks/journey-6YQR5DJX.js +16 -0
  74. package/dist/browser-lazy/chunks/kanban-PLMJ7NBW.js +20 -0
  75. package/dist/browser-lazy/chunks/mermaid-yaml-runtime-QVYX4EWK.js +136 -0
  76. package/dist/browser-lazy/chunks/mindmap-K2UBFO3Y.js +12 -0
  77. package/dist/browser-lazy/chunks/packet-CUW4QY6Y.js +7 -0
  78. package/dist/browser-lazy/chunks/pie-7F7UUCG3.js +15 -0
  79. package/dist/browser-lazy/chunks/quadrant-TOONO2WC.js +10 -0
  80. package/dist/browser-lazy/chunks/radar-J6JVWVAX.js +16 -0
  81. package/dist/browser-lazy/chunks/render-core-BZOM3K7D.js +3 -0
  82. package/dist/browser-lazy/chunks/requirement-CMAKDJPO.js +19 -0
  83. package/dist/browser-lazy/chunks/sankey-AWXQEP3F.js +13 -0
  84. package/dist/browser-lazy/chunks/sequence-Q2RJRB4L.js +5 -0
  85. package/dist/browser-lazy/chunks/state-WRBFQEDX.js +4 -0
  86. package/dist/browser-lazy/chunks/timeline-D2KILFXM.js +6 -0
  87. package/dist/browser-lazy/chunks/treemap-N3VYX5D4.js +6 -0
  88. package/dist/browser-lazy/chunks/xychart-G73OGK66.js +16 -0
  89. package/dist/browser-lazy/chunks/zenuml-H4BXNYXR.js +16 -0
  90. package/dist/browser-lazy/index.d.ts +544 -275
  91. package/dist/browser-lazy/index.js +1 -1
  92. package/dist/browser.global.js +802 -565
  93. package/dist/chunk-3LGLPG33.js +2 -0
  94. package/dist/chunk-7CRDX2QR.js +2 -0
  95. package/dist/chunk-7PPW2BMO.js +2 -0
  96. package/dist/chunk-DQDKA5ND.js +2 -0
  97. package/dist/chunk-EHCMJUMD.js +52 -0
  98. package/dist/chunk-GVCHLSHH.js +4 -0
  99. package/dist/chunk-H3NCS2XZ.js +19 -0
  100. package/dist/chunk-JZOJ4YGS.js +201 -0
  101. package/dist/chunk-MKE7GNYU.js +146 -0
  102. package/dist/chunk-NKNFOREZ.js +2 -0
  103. package/dist/chunk-O7H2UX5K.js +2 -0
  104. package/dist/chunk-OMY6NRQD.js +58 -0
  105. package/dist/chunk-UA234O4M.js +4 -0
  106. package/dist/chunk-VUFVLGTH.js +2 -0
  107. package/dist/chunk-XU5LPD2D.js +2 -0
  108. package/dist/cli-YGGTJZH7.js +226 -0
  109. package/dist/elk-constructor.js +2 -0
  110. package/dist/elk-constructor.node.js +11 -0
  111. package/dist/index-EeXqJXr5.d.ts +1223 -0
  112. package/dist/index.d.ts +4 -1
  113. package/dist/index.js +1 -334
  114. package/dist/jsonl-RPJY6YWO.js +2 -0
  115. package/dist/mcp-cli-63DYXTVD.js +2 -0
  116. package/dist/{index-BGA_-6LV.d.ts → paint-certification-6rwQjIv_.d.ts} +5283 -6173
  117. package/dist/server-5NEOHOFS.js +524 -0
  118. package/dist/svg-styles-BdnoM7AT.d.ts +724 -0
  119. package/dist/svg-styles.d.ts +1 -0
  120. package/dist/svg-styles.js +2 -0
  121. package/dist/svg.d.ts +13 -0
  122. package/dist/svg.js +2 -0
  123. package/dist/types-BcS52Mjt.d.ts +1360 -0
  124. package/dist/zenuml/chunks/appearance-UOQ5KA6O.js +1 -0
  125. package/dist/zenuml/chunks/builtin-backends-KDKE7YHO.js +12 -0
  126. package/dist/zenuml/chunks/chunk-42DXZ5C6.js +4 -0
  127. package/dist/zenuml/chunks/chunk-7TVYPTDW.js +1 -0
  128. package/dist/zenuml/chunks/chunk-EVPSMEKN.js +1 -0
  129. package/dist/zenuml/chunks/chunk-OXQWRSBM.js +20 -0
  130. package/dist/zenuml/chunks/chunk-QWX77U7G.js +2 -0
  131. package/dist/zenuml/chunks/chunk-RLJEI7YN.js +29 -0
  132. package/dist/zenuml/chunks/chunk-RZ6XK5CD.js +29 -0
  133. package/dist/zenuml/chunks/decode-BWERFDGK.js +1 -0
  134. package/dist/zenuml/chunks/mermaid-yaml-runtime-KZVU74WU.js +136 -0
  135. package/dist/zenuml/chunks/render-core-V5RQ737O.js +3 -0
  136. package/dist/zenuml/chunks/zenuml-EA2ZFRUX.js +20 -0
  137. package/dist/zenuml-frame.global.js +3626 -0
  138. package/dist/zenuml.d.ts +83 -0
  139. package/dist/zenuml.js +1 -0
  140. package/docs/MCP-DIRECTORY-LISTINGS.md +5 -1
  141. package/docs/README.md +59 -103
  142. package/docs/agent-api-cookbook.md +26 -16
  143. package/docs/agent-mutation-policy.md +86 -15
  144. package/docs/agent-workflow-examples.md +1 -1
  145. package/docs/api-advanced.md +385 -0
  146. package/docs/api.md +320 -366
  147. package/docs/ascii.md +40 -4
  148. package/docs/browser.md +46 -7
  149. package/docs/choosing-a-diagram.md +148 -0
  150. package/docs/code-mode-impact.md +1 -0
  151. package/docs/comparison.md +244 -28
  152. package/docs/computational-aesthetics-prototype-plan.md +10 -10
  153. package/docs/config.md +60 -2
  154. package/docs/custom-fonts.md +78 -21
  155. package/docs/diagram-families.md +160 -10
  156. package/docs/eventmodeling-and-zenuml.md +165 -0
  157. package/docs/features.md +21 -19
  158. package/docs/fork-differences.md +105 -32
  159. package/docs/getting-started.md +56 -51
  160. package/docs/layout-certification.md +126 -0
  161. package/docs/mcp-code-mode-rationale.md +20 -12
  162. package/docs/mcp-http-transport.md +14 -8
  163. package/docs/quality.md +145 -15
  164. package/docs/react.md +76 -31
  165. package/docs/style-authoring.md +23 -11
  166. package/docs/svg-semantic-contract.md +104 -4
  167. package/docs/testing-strategy.md +684 -126
  168. package/docs/theming.md +27 -8
  169. package/examples/styles/readme-hero.md +25 -0
  170. package/examples/styles/readme-hero.mmd +13 -0
  171. package/examples/styles/readme-hero.style.json +7 -0
  172. package/package.json +114 -57
  173. package/server.json +2 -2
  174. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +26 -8
  175. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +13 -3
  176. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +2 -1
  177. package/skills/agentic-mermaid-diagram-workflow/references/flowchart.md +9 -6
  178. package/skills/agentic-mermaid-diagram-workflow/references/hosted-mcp.md +1 -0
  179. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +4 -3
  180. package/skills/agentic-mermaid-diagram-workflow/references/timeline.md +7 -6
  181. package/skills/agentic-mermaid-diagram-workflow/references/upstream/agentflow.md +574 -0
  182. package/skills/agentic-mermaid-diagram-workflow/references/upstream/architecture.md +10 -2
  183. package/skills/agentic-mermaid-diagram-workflow/references/upstream/c4.md +18 -0
  184. package/skills/agentic-mermaid-diagram-workflow/references/upstream/classDiagram.md +123 -0
  185. package/skills/agentic-mermaid-diagram-workflow/references/upstream/cynefin.md +6 -1
  186. package/skills/agentic-mermaid-diagram-workflow/references/upstream/entityRelationshipDiagram.md +129 -9
  187. package/skills/agentic-mermaid-diagram-workflow/references/upstream/eventmodeling.md +22 -0
  188. package/skills/agentic-mermaid-diagram-workflow/references/upstream/flowchart.md +188 -60
  189. package/skills/agentic-mermaid-diagram-workflow/references/upstream/gitgraph.md +13 -7
  190. package/skills/agentic-mermaid-diagram-workflow/references/upstream/mindmap.md +110 -1
  191. package/skills/agentic-mermaid-diagram-workflow/references/upstream/packet.md +38 -0
  192. package/skills/agentic-mermaid-diagram-workflow/references/upstream/requirementDiagram.md +115 -0
  193. package/skills/agentic-mermaid-diagram-workflow/references/upstream/sequenceDiagram.md +101 -0
  194. package/skills/agentic-mermaid-diagram-workflow/references/upstream/stateDiagram.md +87 -0
  195. package/skills/agentic-mermaid-diagram-workflow/references/upstream/swimlanes.md +105 -2
  196. package/skills/agentic-mermaid-diagram-workflow/references/upstream/timeline.md +12 -6
  197. package/skills/agentic-mermaid-diagram-workflow/references/upstream/usecase.md +953 -0
  198. package/skills/agentic-mermaid-diagram-workflow/references/upstream/venn.md +77 -0
  199. package/skills/agentic-mermaid-diagram-workflow/references/upstream/xyChart.md +1 -1
  200. package/dist/browser-lazy/chunks/architecture-KTHE2HX3.js +0 -31
  201. package/dist/browser-lazy/chunks/chunk-2XCPFAD5.js +0 -46
  202. package/dist/browser-lazy/chunks/chunk-3H4F7RBT.js +0 -1
  203. package/dist/browser-lazy/chunks/chunk-4EVLW2NJ.js +0 -1
  204. package/dist/browser-lazy/chunks/chunk-5Q4S74UO.js +0 -1
  205. package/dist/browser-lazy/chunks/chunk-6OAPWSDO.js +0 -1
  206. package/dist/browser-lazy/chunks/chunk-A7L4WWVW.js +0 -143
  207. package/dist/browser-lazy/chunks/chunk-C7FJO2I3.js +0 -4
  208. package/dist/browser-lazy/chunks/chunk-D3XXDKIO.js +0 -1
  209. package/dist/browser-lazy/chunks/chunk-DXA5WL7H.js +0 -4
  210. package/dist/browser-lazy/chunks/chunk-EPFMQPXX.js +0 -1
  211. package/dist/browser-lazy/chunks/chunk-FFOHLPDA.js +0 -2
  212. package/dist/browser-lazy/chunks/chunk-FLD63DXE.js +0 -2
  213. package/dist/browser-lazy/chunks/chunk-G6OLSHRG.js +0 -7
  214. package/dist/browser-lazy/chunks/chunk-GRXCKTHX.js +0 -0
  215. package/dist/browser-lazy/chunks/chunk-I6VE56S7.js +0 -1
  216. package/dist/browser-lazy/chunks/chunk-KJVNXJ5Y.js +0 -1
  217. package/dist/browser-lazy/chunks/chunk-L227EPFP.js +0 -11
  218. package/dist/browser-lazy/chunks/chunk-LNIHDJSF.js +0 -1
  219. package/dist/browser-lazy/chunks/chunk-M6BT2HIP.js +0 -1
  220. package/dist/browser-lazy/chunks/chunk-NZRUMODH.js +0 -1
  221. package/dist/browser-lazy/chunks/chunk-OFRMKQA6.js +0 -1
  222. package/dist/browser-lazy/chunks/chunk-P7HMSKHJ.js +0 -1
  223. package/dist/browser-lazy/chunks/chunk-PXKL3O6H.js +0 -1
  224. package/dist/browser-lazy/chunks/chunk-PZEWZT35.js +0 -1
  225. package/dist/browser-lazy/chunks/chunk-STQRDZ67.js +0 -1
  226. package/dist/browser-lazy/chunks/chunk-SUFMSWTX.js +0 -1
  227. package/dist/browser-lazy/chunks/chunk-T7IJ6V4B.js +0 -3
  228. package/dist/browser-lazy/chunks/chunk-UAEZO5VL.js +0 -1
  229. package/dist/browser-lazy/chunks/chunk-WEUWIFG3.js +0 -1
  230. package/dist/browser-lazy/chunks/chunk-X64T74C5.js +0 -24
  231. package/dist/browser-lazy/chunks/class-F7R6TJ73.js +0 -9
  232. package/dist/browser-lazy/chunks/er-BDK7CM5L.js +0 -9
  233. package/dist/browser-lazy/chunks/flowchart-KFU6XV7S.js +0 -4
  234. package/dist/browser-lazy/chunks/gantt-I64VVDSP.js +0 -28
  235. package/dist/browser-lazy/chunks/gitgraph-EDUVJ5IJ.js +0 -8
  236. package/dist/browser-lazy/chunks/journey-TLO2RNM3.js +0 -40
  237. package/dist/browser-lazy/chunks/mindmap-OJCNDYPM.js +0 -9
  238. package/dist/browser-lazy/chunks/pie-HVG6XO7K.js +0 -19
  239. package/dist/browser-lazy/chunks/quadrant-U6S2L4MJ.js +0 -24
  240. package/dist/browser-lazy/chunks/radar-ZDLOBTVG.js +0 -32
  241. package/dist/browser-lazy/chunks/render-core-Y2DFNMQG.js +0 -12
  242. package/dist/browser-lazy/chunks/sequence-Z4WFS3VB.js +0 -12
  243. package/dist/browser-lazy/chunks/state-2HV2YGN3.js +0 -4
  244. package/dist/browser-lazy/chunks/timeline-XM4UFPOC.js +0 -20
  245. package/dist/browser-lazy/chunks/xychart-7JDHWTQY.js +0 -36
  246. package/dist/chunk-GGXCNCNA.js +0 -4118
  247. package/dist/chunk-IVD4NXNE.js +0 -615
  248. package/dist/chunk-JDMRPUAG.js +0 -37
  249. package/dist/chunk-JWAAW3FH.js +0 -149
  250. package/dist/chunk-LCGBT32P.js +0 -62036
  251. package/dist/chunk-RWMZRUIC.js +0 -4715
  252. package/dist/mcp-cli-4MLKC3ZH.js +0 -17
  253. package/docs/mutation-testing.md +0 -285
@@ -2,6 +2,16 @@
2
2
 
3
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
4
 
5
+ Scope checked on **2026-10-17**: Agentic source at
6
+ [`3ef2fb8`](https://github.com/adewale/agentic-mermaid/tree/3ef2fb8beff21359fb6e3b798e025a3d69311539),
7
+ Beautiful main at
8
+ [`2ac8bbbb`](https://github.com/lukilabs/beautiful-mermaid/tree/2ac8bbbb060ca0a65a6a21f3200bd99b1587b488)
9
+ and the package comparator `beautiful-mermaid@1.1.3`. Source capability is not
10
+ deployment evidence: Agentic source declares 0.4.2, while npm and the public
11
+ site/MCP still serve 0.4.1 at this check. See [#378](https://github.com/adewale/agentic-mermaid/issues/378).
12
+ Open PRs are proposals, not upstream releases; the related Zombie/C4 comparison
13
+ and historical-version qualifications are in [`comparison.md`](./comparison.md#zombie-mermaid-and-c4-bloodlines).
14
+
5
15
  ## Live site
6
16
 
7
17
  The canonical live site is **[agentic-mermaid.dev](https://agentic-mermaid.dev/)** — a Cloudflare Workers Static Assets deployment built from [`website/`](../website):
@@ -10,6 +20,7 @@ The canonical live site is **[agentic-mermaid.dev](https://agentic-mermaid.dev/)
10
20
  - Live editor: <https://agentic-mermaid.dev/editor>
11
21
  - Family comparisons (Mermaid vs Beautiful Mermaid vs Agentic Mermaid): <https://agentic-mermaid.dev/comparisons/>
12
22
 
23
+ <!-- complete: hosted-mcp-tools -->
13
24
  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
25
 
15
26
  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`.
@@ -22,10 +33,11 @@ Every registered family is structured when narrowed; segment-preserving families
22
33
 
23
34
  ## New and expanded diagram support
24
35
 
25
- This fork renders a wider set of Mermaid families in both the gallery and editor:
36
+ The checked source renders a wider set of Mermaid families in both the gallery and editor:
26
37
 
38
+ <!-- complete: family-ids -->
27
39
  - Flowcharts and state diagrams
28
- - Architecture diagrams (`architecture-beta`)
40
+ - Architecture diagrams (`architecture-beta`, or `architecture`)
29
41
  - Sequence diagrams
30
42
  - Class diagrams
31
43
  - ER diagrams
@@ -33,13 +45,14 @@ This fork renders a wider set of Mermaid families in both the gallery and editor
33
45
  - User Journey diagrams (`journey`)
34
46
  - XY charts (`xychart` and `xychart-beta`)
35
47
  - Pie charts (`pie`, with `showData`)
36
- - Quadrant charts (`quadrantChart`) — not yet rendered anywhere else in the beautiful-mermaid network
48
+ - Quadrant charts (`quadrantChart`)
37
49
  - Gantt charts (`gantt`) with date axes, sections, dependencies, milestones, exclusions, and vertical markers
38
50
  - Mindmaps (`mindmap`) with indentation-sensitive hierarchy, shapes, icons, and classes
39
51
  - Git graphs (`gitGraph`) with deterministic replayed commits, branches, merges, and cherry-picks
40
52
  - Radar charts (`radar-beta`) — spider/star charts plotting multivariate profiles across equi-angular axes from a shared center
53
+ - Sankey diagrams (`sankey`, `sankey-beta`) — CSV-style flows whose ribbon widths are conserved across stages (`FLOW_IMBALANCE` flags an unbalanced node)
41
54
 
42
- The live editor has registry-backed example coverage for every built-in family
55
+ The source editor has registry-backed example coverage for every built-in family
43
56
  (`src/__tests__/editor-examples.test.ts`). Browser E2E still spot-checks several
44
57
  fork-added rendering paths: architecture, timeline, journey, and xychart.
45
58
 
@@ -85,9 +98,9 @@ three aliases fail at import too, which is the easy case.
85
98
  upstream theme names are all valid style names; `knownStyles()` lists every
86
99
  registered one.
87
100
 
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.
101
+ The table above provides migration guidance. Installed package consumer tests
102
+ check the shipped runtime exports and TypeScript declarations, including refusal
103
+ of removed aliases.
91
104
 
92
105
  ## Mermaid config and source wrappers
93
106
 
@@ -100,6 +113,8 @@ This fork supports Mermaid-style source wrappers before diagram headers, includi
100
113
 
101
114
  These are merged with `options.mermaidConfig` where supported. XY chart and architecture rendering use this to honor Mermaid-compatible theme/config fields.
102
115
 
116
+ Frontmatter is read as Mermaid reads it, with js-yaml's `JSON_SCHEMA` rules, and frontmatter that is not valid YAML rejects the diagram, as in Mermaid. `%%{init}%%` directives keep their lenient reader, because Mermaid reads them with `JSON.parse` rather than YAML.
117
+
103
118
  ## Showcase and editor discovery
104
119
 
105
120
  Users can discover fork features through:
@@ -112,18 +127,35 @@ Users can discover fork features through:
112
127
  ## Layout and quality work
113
128
 
114
129
  - 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.
130
+ - The version-pinned Beautiful Mermaid 1.1.3 comparison records different decision-branch routing and subgraph-container attachment. Agentic uses facet-mid diamond ports and honors container direction overrides. Inspect the same-source [comparison page](https://agentic-mermaid.dev/comparisons/) for the deployed examples; selected similar or different renders do not establish general parity, merged ancestry or the status of an upstream issue.
131
+ - Implemented here, with upstream proposals still open as of 2026-10-17:
132
+ fan-in grouping ([Beautiful Mermaid PR #69](https://github.com/lukilabs/beautiful-mermaid/pull/69))
133
+ and labeled fan-out trunk sharing with box-start connector placement
134
+ ([PR #113](https://github.com/lukilabs/beautiful-mermaid/pull/113)). Open proposals
135
+ are not evidence of upstream release inclusion or identical rendering.
117
136
  - ER cardinality parsing matches Mermaid's lexer exactly; malformed relationship lines error loudly instead of being silently dropped.
118
137
 
119
- ## Parser and semantic divergences from Mermaid.js
138
+ ## Parser semantics and migration boundaries
139
+
140
+ **Membership has two stages: collect candidates, then resolve ownership.**
141
+ Flowchart and ER use the shared **first-subgraph-to-close** rule for competing
142
+ candidates: at each `end`, keep candidates not already owned by an earlier-closed
143
+ subgraph, once each. An inner subgraph closes before its enclosing subgraph.
144
+ Creation and membership are separate decisions:
120
145
 
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:
146
+ - Flowchart node statements and edge endpoints collect their identities in the
147
+ current subgraph, even when already known. A `style` statement that creates a
148
+ node does not collect it. References to a declared subgraph collect its group
149
+ identity, independently of whether its declaration precedes the reference.
150
+ Group references resolve after declarations close; the result is a tree, so
151
+ a reference cannot make a group contain itself or one of its ancestors.
152
+ - ER collects entity declarations and entity endpoints of relations, even for
153
+ entities already named at top level. A prior top-level mention does not prevent
154
+ a later ER subgraph from keeping that entity. A style directive alone does not
155
+ collect an entity; a relation endpoint naming an already-opened group refers
156
+ to its boundary. A reference before that group's declaration creates an entity.
157
+
158
+ For example:
127
159
 
128
160
  ```mermaid
129
161
  flowchart TB
@@ -139,22 +171,56 @@ Users can discover fork features through:
139
171
  end
140
172
  ```
141
173
 
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).
174
+ Here `one` keeps `a1` and `a2`, and `three` keeps `c1` and `c2`. The earlier edge
175
+ created `c1` and `a2` without assigning a group. When two subgraphs collect the
176
+ same candidate, the one that closes first keeps it. A later cross-group link
177
+ does not move an identity out of an already-closed owner. Serialization emits
178
+ this resolved membership before links so the same rule applies on re-reading.
179
+
180
+ The [Flowchart candidate collector](https://github.com/adewale/agentic-mermaid/blob/3ef2fb8beff21359fb6e3b798e025a3d69311539/src/parser.ts#L1276-L1321),
181
+ [shared membership authority](https://github.com/adewale/agentic-mermaid/blob/3ef2fb8beff21359fb6e3b798e025a3d69311539/src/shared/subgraph-membership.ts)
182
+ and [ER public-boundary regressions](https://github.com/adewale/agentic-mermaid/blob/3ef2fb8beff21359fb6e3b798e025a3d69311539/src/__tests__/er-subgraph-membership.test.ts)
183
+ record this rule. Agreement on this grammar decision is not a promise of
184
+ Mermaid pixel/layout parity. Current deliberate reader extensions and source
185
+ preservation limits live in [`project/divergences.md`](./project/divergences.md).
186
+
187
+ State resolves authored identities and scopes before building either the
188
+ editable body or the render graph. A reference inside a composite can establish
189
+ the scope of a later definition; a root reference alone establishes no parent.
190
+ Each identity belongs to one scope, and a composite retains its first placement
191
+ when reopened. Initial and final `[*]` endpoints each name one pseudostate per
192
+ scope, with independent identities in concurrent regions. Generated region and
193
+ endpoint names cannot alias authored names.
194
+ The writer checks its emitted ownership against the typed body using that same
195
+ resolver. An edit that cannot retain the requested scope returns an error;
196
+ for example, moving a state to root while a transition inside its former
197
+ composite would claim it again. Move or remove the conflicting transition first.
198
+
199
+ Named floating notes (`note "text" as N`) retain their text and scope in
200
+ `StateBody.floatingNotes`. Their identities are independent of state identities,
201
+ so a state and a note may both be named `N`. The State operations
202
+ `add_floating_note`, `set_floating_note_text` and `remove_floating_note` edit
203
+ these annotations. Scope rename, removal and dissolution carry the annotations
204
+ with their scope; serialization, SVG and terminal rendering preserve them.
205
+
206
+ ### ER parent endpoints
207
+
208
+ ER's left endpoint can use `u` for the parent marker, independently of the four
209
+ crow's-foot cardinalities. The native and typed models retain `parent`; SVG
210
+ draws a hollow diamond and terminal output draws `◇` (`o` in plain ASCII). The
211
+ writer and `add_relation` admit this marker only before the connector, where
212
+ pinned Mermaid's lexer accepts it.
213
+
214
+ ### Sequence text controls
215
+
216
+ Sequence `wrap:` and `nowrap:` are source controls, separated from text before
217
+ entity decoding. Messages, notes, participant aliases, box titles and fragment
218
+ captions retain the control; explicit controls override the diagram default.
219
+ SVG measures wrapped text with a pixel budget; terminal output uses its own cell
220
+ budget. An explicit `nowrap:` still preserves authored line breaks. Typed text
221
+ edits retain the control, and typed strings beginning with control-like text are
222
+ encoded as literal text. `set_message_wrap` and `set_fragment_message_wrap` accept
223
+ `true`, `false`, or `null` to restore inheritance.
158
224
 
159
225
  ## What is intentionally not in this fork
160
226
 
@@ -164,3 +230,10 @@ Users can discover fork features through:
164
230
  ## Upstreaming strategy
165
231
 
166
232
  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.
233
+
234
+ ## Original upstream assertion runs
235
+
236
+ The [original assertion runner](../eval/mermaid-upstream-assertions/README.md)
237
+ executes pinned source test bodies rather than harvested input samples. Its
238
+ family breakdown distinguishes native refusals, assertion mismatches, unmapped
239
+ APIs, reference-control failures, skips and collection errors.
@@ -1,12 +1,10 @@
1
- # Getting started (library)
1
+ # Getting started
2
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.
3
+ Render Mermaid source to SVG, PNG or terminal text. The examples below use
4
+ `agentic-mermaid/agent`, one entry for rendering and typed editing in Node 22+
5
+ or Bun 1.4.0+. Browser rendering has a separate asynchronous entry, shown below.
6
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.
7
+ For editing operations, continue with the [editing cookbook](agent-api-cookbook.md).
10
8
 
11
9
  ## Install
12
10
 
@@ -15,6 +13,8 @@ npm install agentic-mermaid
15
13
  # or: bun add agentic-mermaid / pnpm add agentic-mermaid
16
14
  ```
17
15
 
16
+ ### Repository development
17
+
18
18
  For repository development, install from source:
19
19
 
20
20
  ```bash
@@ -29,21 +29,13 @@ It supports every registered diagram family (including flowchart, sequence,
29
29
  class, ER, state, Gantt, Mindmap, and GitGraph) — just pass the source.
30
30
 
31
31
  ```ts
32
- import { renderMermaidSVG } from 'agentic-mermaid'
32
+ import { writeFileSync } from 'node:fs'
33
+ import { renderMermaidSVG } from 'agentic-mermaid/agent'
33
34
 
34
35
  const svg = renderMermaidSVG(`flowchart TD
35
36
  Start --> Stop`)
36
37
 
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'))
38
+ writeFileSync('diagram.svg', svg)
47
39
  ```
48
40
 
49
41
  ## Render to PNG
@@ -64,9 +56,11 @@ const png = renderMermaidPNG(`flowchart TD
64
56
  writeFileSync('diagram.png', png)
65
57
  ```
66
58
 
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.
59
+ Portable PNG controls are `scale` (default `2`, for retina), `background`,
60
+ the mutually exclusive `fitTo: { width? }` / `fitTo: { height? }`, and
61
+ `minLabelPx` (legibility floor, default `9`; `0` disables the
62
+ `BELOW_READABLE_SIZE` warning); the same controls are available through the
63
+ browser adapter, CLI, and local/hosted MCP.
70
64
  Node/Bun additionally accepts trusted-host `fontDirs`, `loadSystemFonts`, and
71
65
  the library-only `onWarning` callback.
72
66
 
@@ -76,7 +70,7 @@ Great for terminals, code reviews, and plain-text logs. Unicode box-drawing is t
76
70
  default; pass `{ useAscii: true }` for pure ASCII.
77
71
 
78
72
  ```ts
79
- import { renderMermaidASCII } from 'agentic-mermaid'
73
+ import { renderMermaidASCII } from 'agentic-mermaid/agent'
80
74
 
81
75
  const unicode = renderMermaidASCII('flowchart LR\n A --> B')
82
76
  const ascii = renderMermaidASCII('flowchart LR\n A --> B', { useAscii: true })
@@ -93,7 +87,7 @@ Build a palette from two colors, or select one discovered through
93
87
  as CSS variables, so the SVG stays self-contained.
94
88
 
95
89
  ```ts
96
- import { renderMermaidSVG } from 'agentic-mermaid'
90
+ import { renderMermaidSVG } from 'agentic-mermaid/agent'
97
91
 
98
92
  // Two-color palette
99
93
  const dark = renderMermaidSVG('flowchart TD\n A --> B', {
@@ -118,52 +112,63 @@ Common `RenderOptions`: `bg`, `fg`, `font`, `transparent`, and `security`. See
118
112
  ### Untrusted input
119
113
 
120
114
  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.
115
+ the web-font `@import` and rejects output with external-fetch references. See
116
+ [the security boundary](../SECURITY.md) for the guarantees and limits.
123
117
 
124
118
  ```ts
125
- import { renderMermaidSVG } from 'agentic-mermaid'
119
+ import { renderMermaidSVG } from 'agentic-mermaid/agent'
126
120
 
121
+ const userProvidedSource = 'flowchart TD\n A --> B' // replace with input from your application
127
122
  const safe = renderMermaidSVG(userProvidedSource, { security: 'strict' })
128
123
  ```
129
124
 
130
125
  ## In the browser and in frameworks
131
126
 
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:
127
+ Use the browser ESM entry in client components. It avoids the Node/native entry
128
+ and loads only the selected diagram family:
135
129
 
136
- ```tsx
137
- import { useMemo } from 'react'
138
- import { renderMermaidSVG } from 'agentic-mermaid'
130
+ ```ts
131
+ import { renderMermaidSVGAsync } from 'agentic-mermaid/browser/lazy'
139
132
 
140
- function Diagram({ code }: { code: string }) {
141
- const svg = useMemo(() => renderMermaidSVG(code), [code])
142
- return <div dangerouslySetInnerHTML={{ __html: svg }} />
143
- }
133
+ const svg = await renderMermaidSVGAsync('flowchart LR\n A --> B', {
134
+ security: 'strict',
135
+ idPrefix: 'example-diagram', // use a unique prefix per inline diagram
136
+ })
144
137
  ```
145
138
 
146
- See [`react.md`](./react.md) for the zero-flash, live-theme-switching setup.
139
+ The returned string is not a DOM-insertion API. Follow [`browser.md`](./browser.md)
140
+ for parsed-XML insertion and CSP policy, or the complete [`React component`](./react.md)
141
+ for cancellation, unique IDs, error handling and live theme switching. For a
142
+ server component or build step, the synchronous `agentic-mermaid` entry remains
143
+ the simpler choice.
147
144
 
148
- ## Which import path?
145
+ ## Other runtimes and advanced imports
149
146
 
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` |
147
+ | Runtime or task | Entry |
148
+ | --- | --- |
149
+ | Node/Bun rendering and typed editing, including native PNG | `agentic-mermaid/agent` |
150
+ | Browser rendering with deferred family loading | `agentic-mermaid/browser/lazy` |
151
+ | Typed editing in a browser or Worker, without native PNG | `agentic-mermaid/agent/core` |
152
+ | Style utilities such as `fromShikiTheme`, or renderer host adapters | `agentic-mermaid` |
158
153
 
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.
154
+ The root entry remains supported. The agent entry re-exports the synchronous
155
+ renderers but does not include every root utility. See the
156
+ [API reference](api.md) for the full exports and the [browser guide](browser.md)
157
+ for runtime-specific integration.
161
158
 
162
159
  ## Prefer the command line?
163
160
 
164
161
  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:
162
+ install above, create a source file:
163
+
164
+ ```bash
165
+ cat > diagram.mmd <<'MMD'
166
+ flowchart LR
167
+ A --> B --> C
168
+ MMD
169
+ ```
170
+
171
+ Use the package runner so the command resolves without a global install:
167
172
 
168
173
  ```bash
169
174
  npx --no-install agentic-mermaid render diagram.mmd --format svg
@@ -179,4 +184,4 @@ an npm script, the shorter `am …` binary name is available automatically.
179
184
  - [`diagram-families.md`](./diagram-families.md) — every supported family with examples.
180
185
  - [`theming.md`](./theming.md) — custom themes and Shiki import.
181
186
  - [`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).
187
+ - [`agent-api-cookbook.md`](./agent-api-cookbook.md) — typed editing (parse → narrow → mutate → verify → serialize).
@@ -0,0 +1,126 @@
1
+ # Bounded layout certification
2
+
3
+ All 17 native families expose layout evidence through the existing SVG, PNG,
4
+ ASCII and layout receipt APIs. `verifyMermaid` includes graphical evidence;
5
+ debug layout includes `paintCertification`, which `measureQuality` and
6
+ `checkQuality` consume. Quality reports paint confidence under its own
7
+ `paintCertification` metric; it does not change the label-fit score. A certificate reports `passed`, `failed` or `unverified`,
8
+ its native coordinate unit, coverage, bounded work and limitations.
9
+
10
+ ```ts
11
+ const result = renderMermaidSVGWithReceipt(source, { layoutSafety: 'strict' })
12
+ console.log(result.receipt.layoutCertification)
13
+ ```
14
+
15
+ The default `report` policy preserves explicit limitations. It still rejects
16
+ proven native text/marker occlusion and enforces production layout-pass
17
+ contracts. `strict` requires a passed final certificate, including for plain
18
+ string renders; missing evidence, exhausted checks, custom graphical backends,
19
+ and unverified interactive states cannot become successful strict renders.
20
+ Output security remains a separate policy.
21
+
22
+ ## Pixel geometry
23
+
24
+ The graphical checker consumes the admitted Scene from the exact positioned
25
+ artifact and the retained family projection. It does not reparse source or run
26
+ layout again. Text uses the original prepared runs and occupied bands. Typed
27
+ paths, strokes, joins, caps, markers and composed transforms contribute paint
28
+ envelopes. Unknown artwork and lowering-time text fallback are explicit.
29
+
30
+ One outward viewport expansion can contain these envelopes without moving
31
+ nodes, changing data values, rerouting relationships or changing membership.
32
+ The final viewport is checked again. The SVG keeps its requested display
33
+ dimensions and aspect ratio; its viewBox describes the expanded user-unit region. The receipt
34
+ binds the proof to the secured SVG digest also used for PNG rasterization.
35
+
36
+ Paint order determines occlusion. A later opaque rectangle that contains a
37
+ whole occupied text region proves that text is hidden. Conservative path
38
+ envelopes, rotated empty corners and partial intersections do not prove hidden
39
+ ink; an unresolved candidate remains unverified. Tree visits and primitive
40
+ comparisons share a 400,000-operation budget, in addition to the 100,000-pair
41
+ limit. Identical marker artwork
42
+ repainted by an owned carrier is evaluated at its final paint position.
43
+ Occlusion scans stop at their explicit comparison budget instead of returning
44
+ a successful result from an unfinished scan.
45
+
46
+ These are native geometry guarantees. They do not prove every antialiased
47
+ pixel for an arbitrary installed font, host stylesheet, custom backend or
48
+ interactive state. Crisp palettes and role styles use the same retained native
49
+ geometry; rough backends and shadow ink remain outside the proof. Declared translucency and intentional overlap between data
50
+ marks retain their meaning. Text/source correspondence and quantitative chart
51
+ placement remain separate from aesthetic preferences.
52
+
53
+ ## Terminal cells
54
+
55
+ Terminal proof consumes the final native cell document and exact encoded
56
+ output, independently of pixel geometry. It checks retained measured text,
57
+ wide-grapheme continuations, typed stroke/marker glyphs, ownership,
58
+ memberships, endpoint references and allocated containment frames. Encoded
59
+ ANSI/HTML output is compared with the same retained cells. A renderer returning
60
+ text without a native document is unverified.
61
+
62
+ Receipt evaluation remains lazy under `report`: text-only callers do not pay
63
+ for a certificate. Strict callers require it before receiving output. The scan
64
+ has explicit operation, output-size and issue limits. Native representation
65
+ choices, such as replacing a continuous curve with cells, are reported
66
+ separately from cell-layout correctness. Unrelated edge shafts may share cells
67
+ as straight perpendicular crossings; declared bundles retain their intentional
68
+ joins. The checker uses each owner's painted direction, so a merged junction
69
+ cannot lend one route another route's stroke.
70
+
71
+ Explicitly connected routes prove a path through their final visible owned
72
+ stroke and marker cells. An internally allocated immutable path can witness
73
+ that proof, but every point is checked again after composition. Missing, stale
74
+ or ambiguous witnesses use the same bounded traversal and cumulative budget.
75
+ Other routes retain endpoint and marker checks without a complete path proof.
76
+ Full correspondence with authored source remains the family renderer's contract.
77
+
78
+ Class keeps a valid compact layout. If allocation fails or its actual contacts
79
+ are invalid, bounded recovery reserves separate routes, endpoint labels and
80
+ namespace crossings before painting. It keeps text upright in all four layout
81
+ directions and preserves authored identities, markers and note targets. Unboxed
82
+ interfaces keep their captions and publish the actual owned lollipop as their
83
+ physical surface. Hyperlink footer rows and their complete text extents are
84
+ reserved before recovery is painted; safe links stay inert and unsafe actions
85
+ remain source-only under the existing security policy. Both representations
86
+ still use the same final operation and output limits. An unfinished check cannot
87
+ become a passed certificate.
88
+
89
+ ## Priority and pass budgets
90
+
91
+ Preserve authored identities, labels, endpoints, membership and chart values.
92
+ Then satisfy hard geometry and content visibility. Route clarity, crossings,
93
+ bends, preferred ports, symmetry and compactness can improve within those
94
+ constraints; a lower-priority preference cannot silently break a higher one.
95
+
96
+ Production passes enforce their declared order, geometry freeze, metric
97
+ allowances and renewed route certificates. Measurements come from actual
98
+ before/after geometry. Metric requests are selective; enabling a budget does
99
+ not request every rubric metric for every pass. Bounded final graph candidates
100
+ cannot hide a pass-contract error behind another successful layout.
101
+
102
+ Some priorities require explicit local tradeoffs. Separating ambiguous shared
103
+ duplicate routes can justify a bounded crossing cost for that same proposal.
104
+ Fewer bends alone cannot buy a new crossing. An actual repair of a route through
105
+ a node, a diagonal or an invalid endpoint approach can justify a bounded bend
106
+ cost or losing a preferred port. An endpoint approach is checked against the
107
+ actual shape boundary, separately from its preferred attachment ports.
108
+ Opposite-direction shafts sharing positive-length collinear ink are measured
109
+ separately from ordinary crossings and deliberate same-direction fan trunks.
110
+ A merely symmetric reciprocal lane must keep an already valid canonical
111
+ contact. The owning regressions record these cases alongside the existing final
112
+ hard checks.
113
+
114
+ Final graph candidates first pass authored correspondence and hard geometry.
115
+ The bounded preference comparison follows the
116
+ [graph priority order](quality.md#layout-priorities-and-their-limits): readable
117
+ group titles, crossings, padded label conflicts, avoidable bends, preferred
118
+ endpoint contacts, peer alignment and canvas area. A candidate with a better
119
+ lower-priority score cannot displace one with a better earlier score. This final
120
+ comparison does not excuse a production pass-contract error.
121
+
122
+ A repaired viewport with non-scaling strokes is unverified: keeping the display
123
+ size changes the stroke extent in user units. Endpoint checks allow an arrow’s
124
+ stroke to meet its declared endpoint’s owned outline; the marker body must stay
125
+ outside the filled interior. Repaint equality includes resource geometry,
126
+ orientation, stroke units and the composed transform.
@@ -1,7 +1,14 @@
1
1
  # MCP Code Mode rationale
2
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
-
3
+ <!-- complete: local-mcp-tools -->
4
+ Local `agentic-mermaid-mcp` and hosted MCP expose the same declarative `mutate`
5
+ and `build` tools. Prefer them for ordered structured edits: JSON ops go through
6
+ one shared validator, transaction, and verify-before-emit gate. `execute(code)`
7
+ remains available for custom synchronous logic against `mermaid.*`. Locally it
8
+ runs in `node:vm`, which is not an OS/container security boundary.
9
+ The local helpers are `describe_sdk`, `render_png`, and `describe`.
10
+
11
+ <!-- complete: hosted-mcp-tools -->
5
12
  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
13
 
7
14
  ## Why the MCP server exists
@@ -16,13 +23,13 @@ Agents often need a multi-step diagram transaction:
16
23
 
17
24
  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
25
 
19
- ## Code Mode first, plus a narrow declarative edit surface
26
+ ## Declarative edits first; Code Mode for custom logic
20
27
 
21
- Code Mode stays the primary tool for multi-step logic. But `execute` asks the
28
+ Code Mode handles custom multi-step logic. However, `execute` asks the
22
29
  model to write correct sandboxed JavaScript, and a weaker model drives that
23
30
  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`
31
+ all it wanted was to apply a few structured edits. Both surfaces therefore expose
32
+ **two** declarative tools — `mutate` (edit a `source`) and `build`
26
33
  (author from a `family`) — that take a JSON op list and return one canonical
27
34
  `{ ok, family, source, verify }` envelope. They run verify internally and only
28
35
  emit source when it passes, so the verify-before-commit contract holds without
@@ -41,14 +48,15 @@ gets wrong through `execute`. For everything richer, use `execute`, the CLI
41
48
 
42
49
  ## What the non-Code-Mode MCP tools are for
43
50
 
44
- Local MCP keeps only three helpers:
51
+ Local MCP also provides three helpers:
45
52
 
46
53
  - `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
54
 
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.
55
+ - `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`, `minLabelPx`, and mutually exclusive `fitTo.width`/`fitTo.height` controls; local additionally accepts trusted-host `fontDirs`/`loadSystemFonts` remedies. Both return deterministic configuration and raster-legibility warnings, with native hosts also reporting glyph coverage. 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
56
  - `describe(source)` exists because one-shot natural-language summaries are common for screen readers, docs, and context compaction.
50
57
 
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.
58
+ <!-- complete: hosted-mcp-tools -->
59
+ The hosted endpoint adds the same direct discovery tool (`describe_sdk`) 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
60
 
53
61
  Direct render tools accept shared render fields only through the canonical
54
62
  nested `options` object, generated from the shared RenderOptions descriptors.
@@ -90,7 +98,7 @@ Example stdio `.mcp.json` entry:
90
98
  "mcpServers": {
91
99
  "agentic-mermaid": {
92
100
  "command": "npx",
93
- "args": ["-y", "agentic-mermaid-mcp"]
101
+ "args": ["-y", "agentic-mermaid", "mcp"]
94
102
  }
95
103
  }
96
104
  }
@@ -99,10 +107,10 @@ Example stdio `.mcp.json` entry:
99
107
  Example HTTP launch command for clients that manage MCP SSE URLs separately:
100
108
 
101
109
  ```sh
102
- npx -y agentic-mermaid-mcp --transport http --host 127.0.0.1 --port 3000
110
+ npx -y agentic-mermaid mcp --transport http --host 127.0.0.1 --port 3000
103
111
  # non-loopback requires --auth-token <token>
104
112
  ```
105
113
 
106
114
  ## When to add more MCP tools
107
115
 
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.
116
+ Add another non-Code-Mode MCP tool only with evidence that a real client cannot use `execute`, `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.