agentic-mermaid 0.1.1 → 0.2.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.
Files changed (340) hide show
  1. package/AGENT_NATIVE.md +155 -91
  2. package/CHANGELOG.md +163 -4
  3. package/Instructions_for_agents.md +10 -10
  4. package/LICENSES/Apache-2.0.txt +202 -0
  5. package/README.md +31 -38
  6. package/THIRD_PARTY_NOTICES.md +29 -0
  7. package/assets/hero.png +0 -0
  8. package/dist/agent-core.d.ts +463 -0
  9. package/dist/agent-core.js +397 -0
  10. package/dist/agent.d.ts +73 -1868
  11. package/dist/agent.js +336 -37325
  12. package/dist/agentic-mermaid-mcp.js +7 -38399
  13. package/dist/am.js +33626 -40446
  14. package/dist/chunk-2P5FKUQC.js +3485 -0
  15. package/dist/chunk-2S3VSS6I.js +149 -0
  16. package/dist/chunk-2SILJDW2.js +37 -0
  17. package/dist/chunk-BJYMBT4I.js +61963 -0
  18. package/dist/chunk-FDM43XU7.js +615 -0
  19. package/dist/chunk-MYPDVZCO.js +4702 -0
  20. package/dist/index-DWPa2MJs.d.ts +6780 -0
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +310 -33014
  23. package/dist/mcp-cli-5J47WEY3.js +17 -0
  24. package/docs/README.md +39 -31
  25. package/docs/agent-api-cookbook.md +44 -35
  26. package/docs/agent-mutation-policy.md +1 -1
  27. package/docs/agent-workflow-examples.md +2 -2
  28. package/docs/api.md +284 -77
  29. package/docs/ascii.md +26 -16
  30. package/docs/code-mode-impact.md +214 -0
  31. package/docs/comparison.md +23 -11
  32. package/docs/computational-aesthetics-prototype-plan.md +252 -0
  33. package/docs/config.md +26 -10
  34. package/docs/custom-fonts.md +265 -0
  35. package/docs/custom-style-cookbook.md +130 -9
  36. package/docs/diagram-families.md +48 -23
  37. package/docs/features.md +59 -52
  38. package/docs/fork-differences.md +6 -3
  39. package/docs/getting-started.md +23 -16
  40. package/docs/issue-derived-test-cases.md +29 -22
  41. package/docs/mcp-code-mode-rationale.md +13 -6
  42. package/docs/mcp-http-transport.md +20 -13
  43. package/docs/mermaid-layout-complaints.md +66 -52
  44. package/docs/mutation-testing.md +145 -66
  45. package/docs/quality.md +23 -14
  46. package/docs/react.md +2 -2
  47. package/docs/schemas/style-spec.schema.json +1221 -30
  48. package/docs/style-authoring.md +241 -38
  49. package/docs/svg-semantic-contract.md +49 -0
  50. package/docs/testing-strategy.md +166 -58
  51. package/docs/theming.md +19 -32
  52. package/examples/styles/catalog.json +54 -0
  53. package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
  54. package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
  55. package/examples/styles/cupertino-prototype.mmd +10 -0
  56. package/examples/styles/cupertino-prototype.style.json +63 -0
  57. package/examples/styles/mid-century-report.style.json +2 -2
  58. package/examples/styles/star-chart-atlas.style.json +2 -1
  59. package/examples/styles/transit-route-map.style.json +2 -2
  60. package/examples/styles/vercel-inspired-prototype.mmd +6 -0
  61. package/examples/styles/vercel-inspired-prototype.style.json +87 -0
  62. package/package.json +85 -45
  63. package/server.json +2 -2
  64. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
  65. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
  66. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
  67. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
  68. package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
  69. package/TODO.md +0 -684
  70. package/dist/index-wjRjbsP-.d.ts +0 -1102
  71. package/docs/assets/improvements/box-start-connector.png +0 -0
  72. package/docs/assets/improvements/comment-dropped-lint.png +0 -0
  73. package/docs/assets/improvements/er-content-loss.png +0 -0
  74. package/docs/assets/improvements/fan-in-trunks.png +0 -0
  75. package/docs/assets/improvements/gantt-family.png +0 -0
  76. package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
  77. package/docs/assets/improvements/gantt-verify-seam.png +0 -0
  78. package/docs/assets/improvements/subgraph-container-edges.png +0 -0
  79. package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
  80. package/docs/assets/improvements/wrapper-init-directive.png +0 -0
  81. package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
  82. package/docs/assets/style-cookbook/mid-century-report.png +0 -0
  83. package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
  84. package/docs/assets/style-cookbook/transit-route-map.png +0 -0
  85. package/docs/contributing/adding-diagram-types.md +0 -144
  86. package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
  87. package/docs/contributing/diagram-family-citizenship.md +0 -82
  88. package/docs/contributing/harvesting-upstream-tests.md +0 -126
  89. package/docs/contributing/lessons-learned.md +0 -276
  90. package/docs/contributing/releasing.md +0 -82
  91. package/docs/contributing/visual-review-evidence.md +0 -53
  92. package/docs/design/families/README.md +0 -26
  93. package/docs/design/families/architecture-beta.md +0 -48
  94. package/docs/design/families/flowchart-parser-conformance.md +0 -22
  95. package/docs/design/families/gantt-research.md +0 -137
  96. package/docs/design/families/gantt.md +0 -329
  97. package/docs/design/families/journey-agentic-cards-before.png +0 -0
  98. package/docs/design/families/journey-experience-curve-implementation.png +0 -0
  99. package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
  100. package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
  101. package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
  102. package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
  103. package/docs/design/families/journey-migration-parity.md +0 -439
  104. package/docs/design/families/journey-section-overlap-after.png +0 -0
  105. package/docs/design/families/journey-section-overlap-before.png +0 -0
  106. package/docs/design/families/journey-usage-research.md +0 -423
  107. package/docs/design/families/journey.md +0 -153
  108. package/docs/design/families/xychart.md +0 -85
  109. package/docs/design/system/README.md +0 -45
  110. package/docs/design/system/abstraction-audit.md +0 -224
  111. package/docs/design/system/abstraction-recommendations.md +0 -655
  112. package/docs/design/system/architecture.mmd +0 -29
  113. package/docs/design/system/architecture.svg +0 -137
  114. package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
  115. package/docs/design/system/layout-rubric.md +0 -138
  116. package/docs/design/system/route-contracts.md +0 -848
  117. package/docs/design/system/source-preservation-ladder.md +0 -52
  118. package/docs/design/system/styles-rollout.md +0 -216
  119. package/docs/design/system/ugly-layouts.md +0 -119
  120. package/docs/layout-characterization/README.md +0 -245
  121. package/docs/layout-characterization/contact-sheet-families.md +0 -498
  122. package/docs/layout-characterization/contact-sheet.md +0 -638
  123. package/docs/layout-characterization/properties.md +0 -281
  124. package/docs/layout-characterization/visual-quality.md +0 -160
  125. package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
  126. package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
  127. package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
  128. package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
  129. package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
  130. package/docs/layout-characterization/visual-snapshots/journey.svg +0 -98
  131. package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
  132. package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
  133. package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
  134. package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
  135. package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
  136. package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
  137. package/docs/project/divergences.md +0 -98
  138. package/docs/project/dogfooding-docs-strategy.md +0 -66
  139. package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
  140. package/docs/project/lessons-learned.md +0 -1019
  141. package/docs/project/remove-role-styling-plan.md +0 -176
  142. package/examples/agent-improve-auth-flow.ts +0 -206
  143. package/examples/agent-loop.ts +0 -53
  144. package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
  145. package/llms.txt +0 -104
  146. package/skill-evals/README.md +0 -77
  147. package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
  148. package/skill-evals/fixtures/class-payment/input.mmd +0 -4
  149. package/skill-evals/fixtures/er-orders/input.mmd +0 -10
  150. package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
  151. package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
  152. package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
  153. package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
  154. package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
  155. package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
  156. package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
  157. package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
  158. package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
  159. package/skill-evals/shared-benchmark.json +0 -510
  160. package/src/agent/analyze.ts +0 -157
  161. package/src/agent/apply.ts +0 -146
  162. package/src/agent/architecture-body.ts +0 -458
  163. package/src/agent/certificates.ts +0 -110
  164. package/src/agent/class-body.ts +0 -319
  165. package/src/agent/core.ts +0 -207
  166. package/src/agent/create.ts +0 -106
  167. package/src/agent/describe.ts +0 -368
  168. package/src/agent/er-body.ts +0 -224
  169. package/src/agent/facts.ts +0 -360
  170. package/src/agent/families-builtin.ts +0 -920
  171. package/src/agent/families.ts +0 -232
  172. package/src/agent/family-layouts.ts +0 -832
  173. package/src/agent/flowchart-body.ts +0 -372
  174. package/src/agent/flowchart-unsupported.ts +0 -243
  175. package/src/agent/font-coverage.ts +0 -288
  176. package/src/agent/gantt-body.ts +0 -495
  177. package/src/agent/index.ts +0 -10
  178. package/src/agent/journey-body.ts +0 -374
  179. package/src/agent/label-metrics.ts +0 -28
  180. package/src/agent/layout-to-rendered.ts +0 -63
  181. package/src/agent/mutate.ts +0 -97
  182. package/src/agent/mutation-ops.ts +0 -51
  183. package/src/agent/op-schema.ts +0 -443
  184. package/src/agent/parse.ts +0 -223
  185. package/src/agent/pie-body.ts +0 -270
  186. package/src/agent/png.ts +0 -171
  187. package/src/agent/quadrant-body.ts +0 -336
  188. package/src/agent/quality.ts +0 -363
  189. package/src/agent/readability-audit.ts +0 -92
  190. package/src/agent/rendered-route-audit.ts +0 -61
  191. package/src/agent/sequence-body.ts +0 -345
  192. package/src/agent/serialize.ts +0 -214
  193. package/src/agent/state-body.ts +0 -589
  194. package/src/agent/structural-count.ts +0 -150
  195. package/src/agent/timeline-body.ts +0 -280
  196. package/src/agent/trace-log.ts +0 -43
  197. package/src/agent/types.ts +0 -995
  198. package/src/agent/verify.ts +0 -603
  199. package/src/agent/xychart-body.ts +0 -472
  200. package/src/architecture/config.ts +0 -282
  201. package/src/architecture/layout.ts +0 -496
  202. package/src/architecture/parser.ts +0 -375
  203. package/src/architecture/renderer.ts +0 -611
  204. package/src/architecture/types.ts +0 -113
  205. package/src/ascii/ansi.ts +0 -423
  206. package/src/ascii/architecture.ts +0 -210
  207. package/src/ascii/canvas.ts +0 -443
  208. package/src/ascii/class-diagram.ts +0 -697
  209. package/src/ascii/converter.ts +0 -475
  210. package/src/ascii/draw.ts +0 -1693
  211. package/src/ascii/edge-bundling.ts +0 -328
  212. package/src/ascii/edge-routing.ts +0 -330
  213. package/src/ascii/er-diagram.ts +0 -439
  214. package/src/ascii/gantt.ts +0 -276
  215. package/src/ascii/grid.ts +0 -747
  216. package/src/ascii/index.ts +0 -196
  217. package/src/ascii/journey.ts +0 -169
  218. package/src/ascii/meta.ts +0 -244
  219. package/src/ascii/multiline-utils.ts +0 -80
  220. package/src/ascii/pathfinder.ts +0 -301
  221. package/src/ascii/pie.ts +0 -67
  222. package/src/ascii/quadrant.ts +0 -158
  223. package/src/ascii/reverse.ts +0 -216
  224. package/src/ascii/sequence.ts +0 -499
  225. package/src/ascii/shapes/circle.ts +0 -27
  226. package/src/ascii/shapes/corners.ts +0 -143
  227. package/src/ascii/shapes/diamond.ts +0 -27
  228. package/src/ascii/shapes/hexagon.ts +0 -27
  229. package/src/ascii/shapes/index.ts +0 -106
  230. package/src/ascii/shapes/rectangle.ts +0 -168
  231. package/src/ascii/shapes/rounded.ts +0 -27
  232. package/src/ascii/shapes/special.ts +0 -332
  233. package/src/ascii/shapes/stadium.ts +0 -110
  234. package/src/ascii/shapes/state.ts +0 -192
  235. package/src/ascii/shapes/types.ts +0 -73
  236. package/src/ascii/timeline.ts +0 -141
  237. package/src/ascii/types.ts +0 -312
  238. package/src/ascii/validate.ts +0 -120
  239. package/src/ascii/width.ts +0 -81
  240. package/src/ascii/wrap.ts +0 -131
  241. package/src/ascii/xychart.ts +0 -919
  242. package/src/browser.ts +0 -29
  243. package/src/class/layout.ts +0 -240
  244. package/src/class/parser.ts +0 -332
  245. package/src/class/renderer.ts +0 -638
  246. package/src/class/types.ts +0 -129
  247. package/src/cli/agent-instructions.ts +0 -1
  248. package/src/cli/am-bin.ts +0 -6
  249. package/src/cli/exit-codes.ts +0 -18
  250. package/src/cli/index.ts +0 -1132
  251. package/src/cli/init-agent.ts +0 -147
  252. package/src/cli/run-entrypoint.ts +0 -10
  253. package/src/color-resolver.ts +0 -152
  254. package/src/elk-instance.ts +0 -114
  255. package/src/er/layout.ts +0 -187
  256. package/src/er/parser.ts +0 -226
  257. package/src/er/renderer.ts +0 -792
  258. package/src/er/types.ts +0 -99
  259. package/src/family-rubric.ts +0 -425
  260. package/src/font-manifest.ts +0 -31
  261. package/src/gantt/layout.ts +0 -365
  262. package/src/gantt/parser.ts +0 -282
  263. package/src/gantt/pipeline.ts +0 -27
  264. package/src/gantt/renderer.ts +0 -414
  265. package/src/gantt/schedule.ts +0 -513
  266. package/src/gantt/types.ts +0 -255
  267. package/src/index.ts +0 -368
  268. package/src/journey/layout.ts +0 -554
  269. package/src/journey/parse-core.ts +0 -251
  270. package/src/journey/parser.ts +0 -101
  271. package/src/journey/renderer.ts +0 -917
  272. package/src/journey/types.ts +0 -144
  273. package/src/layout/geometry.ts +0 -182
  274. package/src/layout/pass.ts +0 -142
  275. package/src/layout/passes/index.ts +0 -3916
  276. package/src/layout-engine.ts +0 -1565
  277. package/src/layout-rubric.ts +0 -659
  278. package/src/mcp/artifacts.ts +0 -137
  279. package/src/mcp/dynamic-harness.ts +0 -31
  280. package/src/mcp/dynamic-modules.d.ts +0 -7
  281. package/src/mcp/facade.ts +0 -608
  282. package/src/mcp/harness-runtime.ts +0 -203
  283. package/src/mcp/hosted-server.ts +0 -468
  284. package/src/mcp/mcp-bin.ts +0 -3
  285. package/src/mcp/mcp-cli.ts +0 -82
  286. package/src/mcp/protocol.ts +0 -13
  287. package/src/mcp/sandbox.ts +0 -195
  288. package/src/mcp/sdk-decl.ts +0 -391
  289. package/src/mcp/server.ts +0 -362
  290. package/src/mcp/tool-surface.ts +0 -146
  291. package/src/mermaid-source.ts +0 -655
  292. package/src/multiline-utils.ts +0 -228
  293. package/src/parser.ts +0 -1031
  294. package/src/pie/layout.ts +0 -168
  295. package/src/pie/parser.ts +0 -136
  296. package/src/pie/renderer.ts +0 -234
  297. package/src/pie/types.ts +0 -82
  298. package/src/quadrant/layout.ts +0 -191
  299. package/src/quadrant/parser.ts +0 -183
  300. package/src/quadrant/renderer.ts +0 -322
  301. package/src/quadrant/types.ts +0 -113
  302. package/src/render-family-hooks.ts +0 -244
  303. package/src/renderer.ts +0 -1099
  304. package/src/route-contracts.ts +0 -2723
  305. package/src/scene/backend.ts +0 -76
  306. package/src/scene/fidelity.ts +0 -183
  307. package/src/scene/hybrid-backend.ts +0 -174
  308. package/src/scene/ir.ts +0 -181
  309. package/src/scene/marks.ts +0 -127
  310. package/src/scene/rough-backend.ts +0 -378
  311. package/src/scene/seed.ts +0 -46
  312. package/src/scene/style-registry.ts +0 -556
  313. package/src/sequence/layout.ts +0 -456
  314. package/src/sequence/parser.ts +0 -255
  315. package/src/sequence/renderer.ts +0 -604
  316. package/src/sequence/types.ts +0 -154
  317. package/src/shape-clipping.ts +0 -351
  318. package/src/shared/accessibility-directives.ts +0 -22
  319. package/src/shared/batched.ts +0 -61
  320. package/src/shared/color-math.ts +0 -93
  321. package/src/shared/svg-a11y.ts +0 -29
  322. package/src/shared/syntax-error.ts +0 -17
  323. package/src/shared/unicode-ranges.ts +0 -135
  324. package/src/styles.ts +0 -318
  325. package/src/svg-paths.ts +0 -28
  326. package/src/text-metrics.ts +0 -248
  327. package/src/theme.ts +0 -710
  328. package/src/timeline/layout.ts +0 -381
  329. package/src/timeline/parser.ts +0 -215
  330. package/src/timeline/renderer.ts +0 -538
  331. package/src/timeline/types.ts +0 -105
  332. package/src/types.ts +0 -462
  333. package/src/website-worker-modules.d.ts +0 -18
  334. package/src/xychart/axis-utils.ts +0 -109
  335. package/src/xychart/colors.ts +0 -124
  336. package/src/xychart/config.ts +0 -88
  337. package/src/xychart/layout.ts +0 -656
  338. package/src/xychart/parser.ts +0 -504
  339. package/src/xychart/renderer.ts +0 -640
  340. package/src/xychart/types.ts +0 -282
package/docs/api.md CHANGED
@@ -1,11 +1,59 @@
1
1
  # API reference
2
2
 
3
- Agentic Mermaid exposes two library surfaces:
3
+ Agentic Mermaid exposes these library surfaces:
4
4
 
5
- - `agentic-mermaid` — renderer-focused public API for SVG and ASCII/Unicode output.
6
- - `agentic-mermaid/agent` — agent-native API with parse/narrow/mutate/verify/serialize plus SVG, PNG, and ASCII output helpers.
5
+ - `agentic-mermaid` — runtime-neutral renderer API for SVG, ASCII/Unicode,
6
+ and host-injected browser PNG output.
7
+ - `agentic-mermaid/agent` — agent-native API with
8
+ parse/narrow/mutate/verify/serialize plus SVG, native Node/Bun PNG, and ASCII
9
+ output helpers.
10
+ - `agentic-mermaid/agent/core` — the same structured-edit, SVG, and ASCII
11
+ surface without the native PNG dependency; use this entry in browser and
12
+ workerd bundles.
13
+
14
+ Capability reports, the pinned upstream manifest, and trusted Node-host
15
+ resource resolution remain repository audit/host tooling rather than published
16
+ runtime entry points.
7
17
 
8
18
  Use `agentic-mermaid/agent` when you want one import path for agents.
19
+ Use `agentic-mermaid/agent/core` when the target runtime cannot load Node native
20
+ addons.
21
+
22
+ ### Canonical requests and comparable receipts
23
+
24
+ Every first-party renderer enters through the same immutable internal request
25
+ boundary: source wrappers/config, the Style stack, colors, font, security, and
26
+ shared options are normalized once. Receipt-bearing variants make that boundary
27
+ observable without exporting its executable implementation types or changing
28
+ the existing convenience return types:
29
+
30
+ ```ts
31
+ import {
32
+ renderMermaidASCIIWithReceipt,
33
+ renderMermaidPNGWithReceipt,
34
+ renderMermaidSVGWithReceipt,
35
+ } from 'agentic-mermaid/agent'
36
+
37
+ const options = { style: 'hand-drawn', seed: 7, embedFontImport: false }
38
+ const svg = renderMermaidSVGWithReceipt(source, options)
39
+ const png = renderMermaidPNGWithReceipt(source, options)
40
+ const text = renderMermaidASCIIWithReceipt(source, { ...options, colorMode: 'none' })
41
+
42
+ console.assert(svg.receipt.sharedRequestDigest === png.receipt.sharedRequestDigest)
43
+ console.assert(svg.receipt.appearanceDigest === text.receipt.appearanceDigest)
44
+ ```
45
+
46
+ Each `RenderRequestReceipt` contains `version`, `output`,
47
+ `sharedRequestDigest`, output-specific `requestDigest`, and
48
+ `appearanceDigest`. Its `diagnostics` array records stable request-resolution,
49
+ compatibility, applicability, projection, and output-policy decisions. In
50
+ particular, `RENDER_OPTION_NOT_APPLICABLE` makes an authored family-scoped
51
+ option that the selected family does not consume observable instead of letting
52
+ it change request identity silently. CLI JSON results and local/hosted MCP
53
+ render results expose the same receipt. Use `validateSerializableRenderOptions(value)` and
54
+ `sharedRenderOptionsJsonSchema()` for untrusted advanced option objects, or
55
+ `styleInputJsonSchema()` for a standalone convenience `style` field; unknown
56
+ fields, `null`, functions, prototype keys, and non-finite values are rejected.
9
57
 
10
58
  ## Output helpers
11
59
 
@@ -18,7 +66,9 @@ const svg = renderMermaidSVG(`flowchart TD
18
66
  A --> B`, { security: 'strict' })
19
67
  ```
20
68
 
21
- `renderMermaidSVG(input, options?)` accepts a Mermaid source string or `ValidDiagram` and returns an SVG string.
69
+ `renderMermaidSVG(input, options?)` accepts a Mermaid source string or any open
70
+ `ParsedDiagram` envelope returned by `parseRegisteredMermaid` and returns an SVG
71
+ string.
22
72
 
23
73
  ### PNG
24
74
 
@@ -35,20 +85,26 @@ const png = renderMermaidPNG(`flowchart TD
35
85
  writeFileSync('diagram.png', png)
36
86
  ```
37
87
 
38
- `renderMermaidPNG(input, options?)` accepts a Mermaid source string or `ValidDiagram` and returns `Uint8Array` PNG bytes.
88
+ `renderMermaidPNG(input, options?)` accepts a Mermaid source string or any open
89
+ `ParsedDiagram` envelope returned by `parseRegisteredMermaid` and returns
90
+ `Uint8Array` PNG bytes. SVG, ASCII/Unicode, layout, native PNG, and browser PNG
91
+ accept the same parsed-or-source input contract; an unregistered preserved
92
+ envelope round-trips exactly and returns its stable capability diagnostic rather
93
+ than falling through to Flowchart.
39
94
 
40
- `PngOptions`:
95
+ `PngOptions` extends the shared `RenderOptions` contract used by SVG. The
96
+ canonical machine-readable field set is returned by
97
+ `sharedRenderOptionsJsonSchema()`; the table below contains only PNG-specific
98
+ controls:
41
99
 
42
- | Option | Type | Default | Meaning |
100
+ | Option | Type | Default | Availability and meaning |
43
101
  |---|---|---:|---|
44
- | `scale` | `number` | `2` | Zoom multiplier when `fitTo` is not set. |
45
- | `background` | `string` | `'white'` | PNG background color. |
46
- | `fitTo` | `{ width?: number; height?: number }` | — | Constrain output to a width or height. |
47
- | `style` | `StyleInput \| StyleInput[]` | — | Style name \| spec \| stack, same as `RenderOptions.style`. |
48
- | `seed` | `number` | `0` | Ink-wobble seed for styled looks, same as `RenderOptions.seed`. |
49
- | `fontDirs` | `string[]` | — | Extra font directories: custom styles that reference unbundled families, and scripts the bundled fonts don't cover (CJK, emoji). CLI: `--font-dirs <dirs>` (comma-separated). |
50
- | `loadSystemFonts` | `boolean` | `false` | Also load OS-installed fonts. Trades cross-machine determinism for glyph coverage; coverage warnings are skipped (system coverage is unknown). CLI: `--system-fonts`. |
51
- | `onWarning` | `(w: PngFontWarning) => void` | stderr | Receives `PNG_FONT_COVERAGE` warnings (characters no loaded font covers, grouped per script). Without a handler they are written to stderr — tofu is never silent. |
102
+ | `scale` | `number` | `2` | Portable: native/browser library, CLI, and local/hosted MCP. Zoom multiplier when `fitTo` is not set. |
103
+ | `background` | `string` | artifact background, then white | Portable on the same surfaces. Safe explicit PNG background color. |
104
+ | `fitTo` | `{ width?: number; height?: number }` | — | Portable on the same surfaces. Constrain output to exactly one positive width or height. |
105
+ | `fontDirs` | `string[]` | — | Trusted native-host input: Node/Bun library, CLI, and local MCP only. Extra font directories for unbundled families and scripts the bundled fonts do not cover. CLI: `--font-dirs <dirs>` (comma-separated). |
106
+ | `loadSystemFonts` | `boolean` | `false` | Trusted native-host input on the same native surfaces. Trades cross-machine determinism for glyph coverage. CLI: `--system-fonts`. |
107
+ | `onWarning` | `(w: PngFontWarning) => void` | stderr | Native library callback only. Receives `PNG_FONT_COVERAGE` warnings; callbacks never enter serializable requests or receipts. |
52
108
 
53
109
  PNG rasterization uses offline `@resvg/resvg-js` with bundled fonts for
54
110
  deterministic same-machine output: Inter (the default face — the same family
@@ -67,6 +123,48 @@ do not resolve CSS custom properties — `renderMermaidPNG` inlines the
67
123
  resolved family before rasterizing; do the same if you feed the raw SVG to
68
124
  your own pipeline.
69
125
 
126
+ For complete custom-Style recipes using `font`, `fontDirs`, browser faces, and
127
+ SVG font declarations, see [Fonts in custom styles](./custom-fonts.md).
128
+
129
+ PNG output declares the shared sRGB policy with `sRGB` and `cICP` metadata,
130
+ places `cICP` before image data, and deliberately emits no conflicting ICC
131
+ profile. SVG and PNG consume the same resolved graphical colors before
132
+ rasterization.
133
+
134
+ #### Trusted host-selected graphical backends
135
+
136
+ Executable backends are bound by the host, never selected by `RenderOptions` or
137
+ serialized Style data. These factories apply the same canonical request,
138
+ Scene-admission, SVG-security, receipt, PNG-output-policy, and color-profile
139
+ contracts as their default counterparts:
140
+
141
+ ```ts
142
+ import {
143
+ createMermaidBrowserPNGRenderer,
144
+ createMermaidRenderer,
145
+ } from 'agentic-mermaid'
146
+ import { createMermaidPNGRenderer } from 'agentic-mermaid/agent'
147
+
148
+ const backendPolicy = { selectBackend: () => 'backend:acme/renderer' }
149
+ const svgRenderer = createMermaidRenderer({ backendPolicy })
150
+ const nodePngRenderer = createMermaidPNGRenderer({ backendPolicy })
151
+ const browserPngRenderer = createMermaidBrowserPNGRenderer({
152
+ backendPolicy,
153
+ rasterize: async (securedSvg, context) => ({
154
+ png: await rasterizeWithCanvas(securedSvg, context.outputPolicy),
155
+ }),
156
+ })
157
+ ```
158
+
159
+ Register and conformance-check the named backend before constructing these
160
+ renderers. The Node/Bun factory reuses the built-in `@resvg/resvg-js` adapter;
161
+ the browser factory wraps a trusted injected rasterizer, which receives only
162
+ the admitted and secured SVG plus the complete resolved portable output policy.
163
+ Its rasterizer must apply `fitTo` and `background`, not only `scale`.
164
+ `renderMermaidSVG`, `renderMermaidPNG`, and
165
+ `renderMermaidPNGInBrowserWithReceipt` remain the compatible default-backend
166
+ entry points.
167
+
70
168
  ### ASCII / Unicode
71
169
 
72
170
  ```ts
@@ -78,7 +176,16 @@ const ascii = renderMermaidASCII(`flowchart LR
78
176
  A --> B`, { useAscii: true })
79
177
  ```
80
178
 
81
- `renderMermaidASCII(input, options?)` accepts a Mermaid source string or `ValidDiagram` and returns terminal text.
179
+ `renderMermaidASCII(input, options?)` accepts a Mermaid source string or any open
180
+ `ParsedDiagram` envelope returned by `parseRegisteredMermaid` and returns terminal
181
+ text.
182
+
183
+ `AsciiRenderOptions` also extends the same shared `RenderOptions` contract.
184
+ Terminal-only controls and the explicit losses involved in projecting a
185
+ graphical appearance onto terminal cells are documented in
186
+ [`ascii.md`](./ascii.md).
187
+ `colorMode: 'html'` returns an escaped terminal projection through this same
188
+ function; it is not a separate CLI output format or a `renderMermaidHTML` API.
82
189
 
83
190
  `AsciiRenderOptions`:
84
191
 
@@ -90,51 +197,107 @@ const ascii = renderMermaidASCII(`flowchart LR
90
197
  | `boxBorderPadding` | `number` | `1` | Inner box padding. |
91
198
  | `colorMode` | `string` | `'auto'` | `'none'`, `'auto'`, `'ansi16'`, `'ansi256'`, `'truecolor'`, or `'html'`. |
92
199
  | `theme` | `Partial<AsciiTheme>` | — | Override ASCII colors. |
93
- | `mermaidConfig` | `MermaidRuntimeConfig` | — | Mermaid-style runtime config. |
94
- | `ganttToday` | `string` | unset | Explicit "today" for the Gantt `todayMarker`; same deterministic clock behavior as SVG. |
95
-
96
- ## SVG render options
97
-
98
- `renderMermaidSVG` accepts `RenderOptions`:
99
-
100
- | Option | Type | Default | Meaning |
101
- |---|---|---:|---|
102
- | `bg` | `string` | `#FFFFFF` | Background color or CSS variable. |
103
- | `fg` | `string` | `#27272A` | Foreground color or CSS variable. |
104
- | `line` | `string?` | — | Edge/connector color. |
105
- | `accent` | `string?` | — | Arrow heads and highlights. |
106
- | `muted` | `string?` | — | Secondary text/labels. |
107
- | `surface` | `string?` | — | Node fill tint. |
108
- | `border` | `string?` | — | Node stroke color. |
109
- | `font` | `string` | `Inter` | Font family. |
110
- | `style` | `string \| StyleSpec \| (string \| StyleSpec)[]` | — | How the diagram looks: a registered style name (`'hand-drawn'`, `'tufte'`, any palette like `'dracula'`), an inline public `StyleSpec`, or a stack merged left→right (`['hand-drawn', 'dracula']`). See `docs/style-authoring.md`. |
111
- | `seed` | `number` | `0` | Deterministic re-roll for stochastic styles — shuffles ink wobble, never layout. |
112
- | `transparent` | `boolean` | `false` | Transparent SVG background. |
113
- | `padding` | `number` | `40` | Canvas padding. |
114
- | `nodeSpacing` | `number` | `24` | Horizontal sibling spacing. |
115
- | `layerSpacing` | `number` | `40` | Vertical layer spacing. |
116
- | `componentSpacing` | `number` | `24` | Disconnected component spacing. |
117
- | `interactive` | `boolean` | `false` | XY chart hover tooltips. |
118
- | `shadow` | `boolean` | `false` | Explicit drop shadows. |
119
- | `mermaidConfig` | `MermaidRuntimeConfig` | — | Runtime Mermaid config. |
120
- | `embedFontImport` | `boolean` | `true` | Include Google Fonts `@import`; set false for offline SVG/PNG. |
121
- | `compact` | `boolean` | `false` | Compact SVG output while preserving agent hooks. |
122
- | `idPrefix` | `string` | `''` | Namespace generated SVG def ids. |
123
- | `security` | `'default' | 'strict'` | `'default'` | `strict` disables external-fetch references. |
124
- | `ganttToday` | `string` | unset | Explicit "today" for the Gantt `todayMarker` (date in the diagram's `dateFormat` or ISO `YYYY-MM-DD`). Gantt never reads the wall clock; without this the marker is not drawn. |
200
+ | `targetWidth` | `number` | unset | Hard maximum line width in terminal display cells. Uses grapheme-safe fitting; impossible geometry throws `AsciiWidthError`. |
201
+ | `maxWidth` | `number` | unset | Deprecated best-effort label wrapping. It does **not** guarantee the output width. Do not combine with `targetWidth`. |
202
+ | `onProjectionDiagnostic` | `(diagnostic: TerminalProjectionDiagnostic) => void` | — | Host callback for explicit graphical-to-terminal projection losses; non-serializable and excluded from receipts. |
203
+
204
+ `AsciiWidthError` has code `ASCII_TARGET_WIDTH_IMPOSSIBLE` plus
205
+ `requestedWidth`, `requiredWidth`, `family`, and `reason` (`MINIMUM_GEOMETRY`,
206
+ `UNBREAKABLE_GRAPHEME`, or `INVALID_WIDTH`). The same fields are returned by
207
+ CLI JSON and hosted MCP errors. CLI: `am render diagram.mmd --format unicode
208
+ --target-width 80`; hosted `render_ascii`: `{ source, targetWidth: 80 }`.
209
+ Omitting both width options preserves the unconstrained output path.
210
+
211
+ ## Shared render options
212
+
213
+ SVG, PNG, ASCII, and Unicode adapters accept this serializable `RenderOptions`
214
+ field set. The built-in-family column exposes family applicability; the
215
+ terminal column records whether text output consumes a field, projects it with
216
+ an explicit diagnostic, or declares it inapplicable. Output-specific controls
217
+ remain in their respective sections.
218
+
219
+ <!-- BEGIN GENERATED SHARED RENDER OPTIONS -->
220
+ | Option | Type | Effective default | Meaning | Built-in families | Terminal |
221
+ |---|---|---|---|---|---|
222
+ | `bg` | `string` | `#FFFFFF` | Background color or CSS variable. | all | consumed |
223
+ | `fg` | `string` | `#27272A` | Primary foreground and text color. | all | consumed |
224
+ | `line` | `string` | derived | Connector and secondary-line color. | all | consumed |
225
+ | `accent` | `string` | derived | Arrowhead, highlight, and data accent color. | all | consumed |
226
+ | `muted` | `string` | derived | Secondary text and label color. | all | projected — terminal themes have no dedicated muted-text role |
227
+ | `surface` | `string` | derived | Node and group surface color. | all | projected — terminal cells do not paint graphical surfaces |
228
+ | `border` | `string` | derived | Node and group border color. | all | consumed |
229
+ | `font` | `string` | `Inter` | CSS font family or stack. | all | projected — the host terminal owns the font face |
230
+ | `style` | `StyleInput \| StyleInput[]` | `crisp` | Registered Style/Palette name, inline StyleSpec, or left-to-right stack. | all | consumed |
231
+ | `padding` | `number` | `40` | Canvas padding in SVG user units. | flowchart, state, architecture | not-applicable — terminal output uses paddingX, paddingY, and boxBorderPadding |
232
+ | `nodeSpacing` | `number` | `24` | Horizontal spacing between sibling nodes. | flowchart, state, class, er, architecture | not-applicable — terminal layout has a cell-grid spacing contract |
233
+ | `layerSpacing` | `number` | `40` | Vertical spacing between graph layers. | flowchart, state, class, er, architecture | not-applicable — terminal layout has a cell-grid spacing contract |
234
+ | `wrappingWidth` | `number` | unset | Flowchart measured-label wrapping budget in pixels. | flowchart | not-applicable — terminal output uses maxWidth or targetWidth |
235
+ | `componentSpacing` | `number` | extension-defined | Spacing between disconnected graph components for compatible extension families; no built-in family currently consumes it. | none — extension-defined | not-applicable — terminal layout has a cell-grid spacing contract |
236
+ | `transparent` | `boolean` | `false` | Omit the painted SVG canvas background. | all | projected — terminal output has no painted canvas background |
237
+ | `interactive` | `boolean` | `false` | Enable hover tooltips for supported chart data points. | xychart, pie, quadrant | projected — terminal output is a static semantic projection |
238
+ | `shadow` | `boolean` | `false` | Paint explicit drop shadows on node shapes. | flowchart, state, sequence, timeline, class, er, journey, xychart, pie, quadrant, gantt, mindmap, gitgraph | projected — elevation projects to borders and labels |
239
+ | `class` | `{ hierarchicalNamespaces?: boolean }` | `hierarchicalNamespaces: true` | Class-diagram rendering controls. | class | not-applicable — this option configures graphical class layout |
240
+ | `architecture` | `{ visual?: ArchitectureVisualOverrides }` | built-in metrics | Sparse architecture renderer visual metric and paint overrides. | architecture | not-applicable — this option configures graphical architecture rendering |
241
+ | `timeline` | `{ maxWidth?: number }` | `maxWidth`: unset | Timeline layout controls. | timeline | not-applicable — terminal output uses maxWidth or targetWidth |
242
+ | `journey` | `{ experienceCurve?: boolean }` | `experienceCurve: true` | User-journey graphical controls. | journey | not-applicable — experience curves are graphical-only |
243
+ | `gantt` | `{ dependencyArrows?: boolean; criticalPath?: boolean }` | both `false` | Gantt dependency and critical-path overlays. | gantt | not-applicable — graphical Gantt connector emphasis is not represented in cells |
244
+ | `mermaidConfig` | `MermaidRuntimeConfig` | source config | Mermaid-style recursive runtime configuration. | all | consumed |
245
+ | `embedFontImport` | `boolean` | `false` | Embed the Google Fonts import in SVG styles; PNG forces this off for offline rasterization. | all | not-applicable — terminal output embeds no web-font import |
246
+ | `compact` | `boolean` | `false` | Compact SVG serialization while preserving agent hooks. | all | not-applicable — compact controls SVG serialization |
247
+ | `idPrefix` | `string` | unset | Non-empty namespace for generated SVG definition IDs and local references. | all | not-applicable — terminal output has no SVG definition ids |
248
+ | `security` | `'default' \| 'strict'` | `default` | Active SVG content is rejected in every mode; strict additionally rejects every external reference. Raw Mermaid themeCSS is rejected in both modes. | all | not-applicable — terminal text has its own control-character and HTML-color safety projection |
249
+ | `ganttToday` | `string` | unset | Explicit deterministic date for the Gantt today marker. | gantt | consumed |
250
+ | `seed` | `number` | `0` | Deterministic re-roll seed for stochastic Styles. | all | not-applicable — terminal glyph geometry is deterministic and has no stochastic ink |
251
+ <!-- END GENERATED SHARED RENDER OPTIONS -->
252
+
253
+ `Built-in families: all` means the field is family-neutral. `none —
254
+ extension-defined` means no built-in currently consumes it. An external
255
+ `FamilyDescriptor` opts into any family-scoped field it consumes through its
256
+ frozen `applicableRenderOptions` array; an omitted or empty declaration means
257
+ none, and authored values receive `RENDER_OPTION_NOT_APPLICABLE` in the render
258
+ receipt.
259
+
260
+ `onConfigDiagnostic?: (diagnostic: ConfigDiagnostic) => void` is deliberately
261
+ outside the serializable field set. Library callers can collect qualified
262
+ `INEFFECTIVE_CONFIG` warnings without changing output bytes; CLI, MCP, editor,
263
+ and JSON Schema surfaces return diagnostics as data instead of accepting a
264
+ function.
265
+
266
+ ### SVG semantic identity and accessibility
267
+
268
+ All built-in families expose the same inspectable element contract:
269
+
270
+ - every source-semantic Scene mark has a deterministic `data-id` and closed
271
+ `data-role`; identity is unique within one SVG (layout furniture retains typed
272
+ Scene identity without bloating the DOM);
273
+ - source relations use `data-from` and `data-to`; source `className` tokens stay
274
+ on the identified element's `class` attribute;
275
+ - typed relations expose `role="graphics-symbol"`,
276
+ `aria-roledescription="relation"`, and an `aria-label` derived from endpoints
277
+ plus the authored relation label;
278
+ - public Scene types expose `SvgSemanticIdentity`,
279
+ `SvgSemanticAccessibility`, and `SvgRelationSemantics`;
280
+ - `idPrefix` rewrites local DOM `id` references, not source-facing `data-id`.
281
+
282
+ Built-in concrete palettes are contrast-normalized at render time: normal text
283
+ roles meet WCAG AA 4.5:1 and meaningful relation lines/markers meet 3:1 against
284
+ the page background. Unresolved runtime CSS variables cannot be statically
285
+ certified and pass through unchanged. See
286
+ [`svg-semantic-contract.md`](./svg-semantic-contract.md) for the complete contract.
125
287
 
126
288
  For JSON files, use
127
289
  [`docs/schemas/style-spec.schema.json`](./schemas/style-spec.schema.json). The
128
290
  same schema is exported from the npm package as
129
291
  `agentic-mermaid/style-spec.schema.json`; see
130
292
  [`custom-style-cookbook.md`](./custom-style-cookbook.md) for complete style
131
- files and screenshots.
293
+ files and screenshots, and [`custom-fonts.md`](./custom-fonts.md) for font
294
+ resolution across output surfaces.
132
295
 
133
296
  ## Agent edit API
134
297
 
135
298
  ```ts
136
299
  import {
137
- parseMermaid,
300
+ parseRegisteredMermaid,
138
301
  asFlowchart,
139
302
  mutate,
140
303
  verifyMermaid,
@@ -150,43 +313,85 @@ Core functions:
150
313
 
151
314
  | Function | Purpose |
152
315
  |---|---|
153
- | `parseMermaid(source)` | Parse Mermaid source to `Result<ValidDiagram, ParseError[]>`. |
154
- | `asFlowchart(d)` / `asState(d)` / `asSequence(d)` / `asTimeline(d)` / `asClass(d)` / `asEr(d)` / `asJourney(d)` / `asArchitecture(d)` / `asXyChart(d)` / `asPie(d)` / `asQuadrant(d)` / `asGantt(d)` | Narrow to a mutable family or return `null`. |
316
+ | `parseRegisteredMermaid(source)` | Parse Mermaid source to `Result<ValidDiagram, ParseError[]>`. |
317
+ | Family narrower | Narrow to a mutable family or return `null`; obtain the current generated name from `am capabilities --json`. |
155
318
  | `mutate(d, op)` | Apply a kind-discriminated typed mutation. |
156
319
  | `verifyMermaid(d)` | Return structural warnings and layout evidence. |
157
320
  | `analyzeMermaid(d)` / `analyzeMermaidSource(source)` | Return deterministic non-rendering analysis: feedback edges, source-only action records, and Gantt critical-path/slack summary when available. |
158
321
  | `describeMermaidFacts(d)` / `checkMermaid(d, spec)` | Return deterministic semantic fact lines, or check required/forbidden facts such as `edge Processing -> [*] : done`, `member Duck +quack()`, `task Docs start after core`. |
159
322
  | `serializeMermaid(d)` | Emit source only after verifying. |
160
- | `layoutMermaid(d)` | Return layout JSON for quality/inspection; `layoutMermaid(d, { debug: true })` includes graph route certificates, family edge-route certificates (class/ER/architecture/sequence), region-containment certificates (timeline/charts), and V1 region/action sidecars. Edge certificates include exact ports plus side/slot/role port assignments where applicable. |
161
- | `measureQuality(layout)` / `checkQuality(layout)` | Perceptual quality metrics. |
323
+ | `layoutMermaid(d)` | Return layout JSON for quality/inspection; `layoutMermaid(d, { debug: true })` includes graph route certificates, family edge-route certificates (class/ER/architecture/sequence), region-containment certificates (timeline/charts), and semantic region/action sidecars (`cluster`, `lane`, `band`, `compartment`, `plot`, `ring`). Edge certificates include exact ports plus side/slot/role port assignments where applicable. |
324
+ | `renderMermaidWithActions(d, request)` | Render SVG, PNG, ASCII, or Unicode and return one inert action/hit-region sidecar for admitted Flowchart/Class/Gantt interactions and Sequence actor-menu links. An SVG href is `embedded-inert` only when matching inert metadata is present in the returned SVG; PNG/terminal actions, strict-mode hrefs, and all callbacks are `sidecar-only` and never execute. Terminal artifacts also return projection `warnings`, and terminal render failure throws instead of returning an empty success artifact. |
325
+ | `measureQuality(layout, colors?)` / `checkQuality(layout, bounds?, colors?)` | Perceptual quality metrics, including fail-closed contrast (`null` when requested paints are unresolved), nearest-node spacing, and element density. Rendered audits can supply exact foreground/background associations through `textPairs`. |
162
326
  | `describeMermaid(d, { format })` | Prose, AX-tree, or facts summary (`format: "text" | "json" | "facts"`). |
163
327
 
164
- Typed mutation families:
165
-
166
- | Family | Narrower | Common ops |
167
- |---|---|---|
168
- | Flowchart | `asFlowchart` | `add_node`, `remove_node`, `rename_node`, `set_label`, `add_edge`, `remove_edge` |
169
- | State | `asState` | `add_state`, `remove_state`, `rename_state`, `set_state_label`, `add_transition`, `remove_transition`, `set_transition_label`, `make_composite` |
170
- | Sequence | `asSequence` | `add_participant`, `remove_participant`, `add_message`, `remove_message`, `set_message_text` |
171
- | Timeline | `asTimeline` | `set_title`, `add_section`, `add_period`, `add_event`, remove/set variants |
172
- | Class | `asClass` | `add_class`, `remove_class`, `rename_class`, `add_member`, `add_relation`, notes |
173
- | ER | `asEr` | `add_entity`, `remove_entity`, `rename_entity`, `add_attribute`, `add_relation` |
174
- | Journey | `asJourney` | `set_title`, `add_section`, `add_task`, `set_task_score`, `set_task_actors`, `rename_actor`, … |
175
- | XY chart | `asXyChart` | `set_title`, `set_x_axis`, `set_y_axis`, `add_series`, `set_series_values`, `reorder_series`, … |
176
- | Architecture | `asArchitecture` | `add_service`, `move_service`, `add_group`, `add_edge`, `rename_service`, … |
177
- | Pie | `asPie` | `set_title`, `set_show_data`, `add_slice`, `remove_slice`, `rename_slice`, `set_slice_value`, `reorder_slice` |
178
- | Quadrant | `asQuadrant` | `set_title`, `set_axis_labels`, `set_quadrant_label`, `add_point`, `remove_point`, `move_point`, `rename_point` |
179
- | Gantt | `asGantt` | `set_title`, `add_section`, `rename_section`, `add_task`, `set_task_status`, `set_task_dates`, … |
328
+ The family registry is the operation authority. Use `am capabilities --json`
329
+ for the current roster and field schemas, or call `describeOps(family)` and
330
+ `opSignatures(family)` at runtime. The generated SDK declaration projects the
331
+ same descriptors; this reference deliberately does not copy an exhaustive
332
+ family/operation table.
180
333
 
181
334
  Opaque fallback bodies (any unmodeled syntax) are source-level-only: edit source deliberately, then parse and verify again.
182
335
 
336
+ ## Capability and extension discovery
337
+
338
+ Repository audit tooling can import `createSectionACapabilityReport()` from
339
+ `src/section-a-capability-report.ts`. It returns the JSON-safe, registry-derived
340
+ request/backend/output/family/Scene matrix. `am capabilities --json` →
341
+ `sectionA` intentionally exposes only its version, pin, digest, counts,
342
+ no-absent status, and directions to this full report. Validate a stored snapshot with
343
+ `validateSectionACapabilityReport(report)`. The generated human projection is
344
+ [`project/section-a-capability-report.md`](./project/section-a-capability-report.md).
345
+ Keeping this audit surface out of the package prevents the full characterization
346
+ and upstream syntax corpora from entering renderer/browser bundles.
347
+
348
+ Canonical extension identities are kind-qualified (`look:`, `palette:`,
349
+ `backend:`, `family:`, `role:`, and `resource:`), versioned, provenance-bearing,
350
+ and collision-safe. New graphical backends declare feature/operation-level
351
+ Scene primitive capability claims; the registry rejects an empty, duplicate,
352
+ cross-target, or otherwise invalid claim set. Every external backend, and every
353
+ external family that supplies `lowerScene`, must also declare an explicit
354
+ compatible `identity.compatibility.scene` range (Scene v2: `^2.0.0`). The host
355
+ checks that range before running backend conformance or other executable
356
+ witnesses; only the internal built-in enrollment path receives compatibility
357
+ defaults.
358
+
359
+ ### Current customization and extension inventory
360
+
361
+ This is the current authoritative inventory. Field-level `RenderOptions` and
362
+ `StyleSpec` details remain in their generated tables above rather than being
363
+ copied here.
364
+
365
+ | Level | Public seam | What it can change | Boundary and availability |
366
+ |---|---|---|---|
367
+ | Mermaid-authored appearance | frontmatter/init config, theme variables, family style statements such as classes and link styles | Syntax-defined colors, labels, family geometry, and interaction metadata where the family advertises support | Source-level and family-dependent. Raw `themeCSS` is recognized but diagnosed at the render boundary because its selectors and markup can escape an imported SVG; use `StyleSpec` instead. |
368
+ | One-off render overrides | `RenderOptions` | Palette channels, font family, spacing/geometry controls, deterministic seed, security, accessibility-related output options, and a Style stack | The generated field×surface matrix marks each serializable shared field `forwarded`, `host-enforced`, or `unavailable`. Hosted SVG and editor SVG enforce strict security with external font imports disabled; effective receipts reflect those constraints. Host callbacks are library-only and never enter receipts. |
369
+ | One-off declarative style | inline `StyleSpec` or a left-to-right `StyleInput[]` stack | Safe palette, font, stroke/fill treatment, backdrop, exact semantic-role defaults, named semantic slots, V1 `category` bindings, non-color cues, and inspect-only contrast/accent-area/mono-role constraints | JSON-safe and executable-code-free. Bindings supply defaults beneath authored family paint and semantics; constraints diagnose final effective paint without repainting or relayout. This is the lowest-complexity custom Style path. |
370
+ | Named Palette/Look | `registerStyle`, `getStyle`, `knownStyleDescriptors` | Installs a versioned `palette:` or `look:` name backed by exactly the same `StyleSpec` accepted inline | Descriptors expose one `kind` (`look` or `palette`), explicit `isDefault`, and one stable `inputName`. In-process host registry. A CLI/MCP/server sees a registration only when that host installs it at startup. |
371
+ | Theme conversion | `fromShikiTheme` | Converts a Shiki-compatible editor theme into diagram colors | Pure library helper; the result is ordinary declarative color input. |
372
+ | Live host retheming | CSS custom-property values in graphical color/font inputs | Lets a host page switch SVG palette and font values without re-rendering | SVG/browser-only and limited to safe property values; this is not a raw CSS rule or selector hook. Static outputs need values resolved under their rasterization environment to remain reproducible. |
373
+ | Terminal output projection | `AsciiRenderOptions` (`useAscii`, `paddingX`, `paddingY`, `boxBorderPadding`, `colorMode`, `theme`, `targetWidth`/`maxWidth`, `onProjectionDiagnostic`) | Selects Unicode/ASCII encoding, cell spacing, width policy, ANSI/HTML colors, terminal-only theme overrides, and projection-loss reporting | Output-adapter customization, not a second shared Style system. Serializable fields have transport-specific availability; the diagnostic callback is host-only and remains outside receipts. |
374
+ | Fonts and installed resources | `font`, Node PNG `fontDirs`/`loadSystemFonts`/`onWarning`, browser `BrowserPngRasterizer`, `ResourceManifest`, and repository host tooling via `NodeResourceResolver` | Selects a safe font stack, supplies host-dependent raster fonts, reports missing glyph coverage, or verifies bounded installed bytes | Font family names do not install fonts. Browser and warning callbacks remain outside serializable options and every digest. Node `fontDirs`/`loadSystemFonts` are trusted host inputs outside shared `RenderOptions` and the shared/appearance digests, but their resolved PNG output policy is included in the output-specific request digest; runtime provenance still marks host-dependent resources explicitly. Manifests require path, size, media-type, digest, and licence evidence and never fall back to network access. |
375
+ | Graphical backend | `registerBackend`, `runBackendConformance`, `createMermaidRenderer`, `createMermaidPNGRenderer`, `createMermaidBrowserPNGRenderer` (each with a host-only `backendPolicy`) | Serializes the typed Scene contract with a different drawing implementation for SVG, native Node/Bun PNG, and injected-rasterizer browser PNG | Trusted in-process host only. Host registrations must explicitly declare compatible core and Scene ranges; identity/compatibility admission precedes executable conformance. Registration then must pass bounded, deterministic, semantic, well-formed, secure SVG conformance plus an exact witness for every first-party core primitive/feature/operation claim; namespaced extension claims without a core witness remain explicitly unverified. All listed factories use the same admitted and secured graphical request; PNG adapters do not reparse or rerender source. Serializable styles and `RenderOptions` cannot select arbitrary executable backends. |
376
+ | Diagram family | `registerFamily`, `getFamilyConformanceReport`, `parseRegisteredMermaid`, `projectPositionedView` | Adds a namespaced language with detection, parse/preservation, verification, layout, Scene/SVG, terminal, and discovery claims | Every versioned `family:<owner/name>` descriptor declares a compatible core range and supplies one bounded canonical `example`. It also lists consumed family-scoped shared fields in `applicableRenderOptions`; omission means none, unknown or duplicate fields fail registration, and the frozen declaration appears in the capability report. Registration stages the frozen candidate, runs native claims twice through canonical parse/serialize, non-empty positive-bounds layout, strict SVG, portable PNG pre-raster, terminal, Scene and verify paths, and rolls back on failure, reentrancy or nondeterminism. Discovery reports `native` only beside a passed per-capability witness. Native tuples still require layout + `projectPositioned`, Scene requires layout + `lowerScene`, and extension verification requires its hook plus executable SVG. An external Scene family additionally declares a compatible Scene range, and its example witnesses every positive role/primitive cell. Built-in-only unions stay closed; extension bodies use the open envelope. Remote transports gain the family only when their trusted host installs it. |
377
+ | Scene semantics | `SceneDoc`, typed connectors/markers/hit geometry, namespaced `SceneRole` | Lets a family/backend exchange identity, relationship, accessibility, geometry, and terminal-projection intent | This is a versioned typed contract, not a raw SVG hook. Unknown namespaced roles deliberately receive inert identity-only traits and cannot acquire core behavior by local-name collision. There is no public arbitrary primitive/trait mutation registry. |
378
+ | Browser PNG host adapter | `renderMermaidPNGInBrowserWithReceipt(..., rasterize)` or reusable `createMermaidBrowserPNGRenderer({ rasterize, backendPolicy? })` | Supplies Canvas/OffscreenCanvas rasterization and reports font provenance | Trusted callback receives only the admitted, secured canonical SVG; the library re-applies the PNG color-profile gate and retains the same logical receipt as the native PNG path. |
379
+ | Identity plumbing | `canonicalExtensionId`, `parseExtensionId`, `createExtensionIdentity`, `registerExtension`, `ExtensionCollisionError` | Gives kind-specific registries stable names, parsing, versions, provenance, compatibility ranges, and collision rejection | Low-level plumbing, not a stand-alone extension registry or rendering hook. Stable short inputs belong to kind-specific descriptors. |
380
+
381
+ There is currently no BrandPack registry, public role-trait registration,
382
+ arbitrary SVG/CSS hook, or Treatment hook. Semantic slots and the closed V1
383
+ `category` binding API are ordinary `StyleSpec` fields; other Scene channels are
384
+ not publicly bindable without new executable family witnesses. B4 remains the
385
+ unpromoted, evidence-gated BrandPack distribution envelope only. A future
386
+ Treatment seam is a separate decision and is not implied by B4.
387
+
183
388
  ## CLI
184
389
 
185
390
  ```bash
186
391
  am render diagram.mmd --format svg > diagram.svg
187
- am render diagram.mmd --format png --output diagram.png
392
+ am render diagram.mmd --format png --output diagram.png --fit-width 1200 --bg '#fff'
188
393
  am render diagram.mmd --format ascii > diagram.txt
189
- am render diagram.mmd --format json --certificates > layout-with-routes.json
394
+ am render diagram.mmd --format layout --certificates > layout-with-routes.json
190
395
  am verify diagram.mmd
191
396
  am describe diagram.mmd --format facts
192
397
  am mutate diagram.mmd --op '{"kind":"add_node","id":"Cache","label":"Cache"}' --json
@@ -194,18 +399,20 @@ am capabilities --json
194
399
  am init-agent --dir . --json
195
400
  ```
196
401
 
197
- PNG is single-input and requires `--output` so binary bytes are never accidentally printed to a terminal. `am init-agent` writes a non-clobbering agent-agnostic onboarding bundle (`AGENTS.md`, root `skills/`, and `.mcp.json`) into a consumer repo.
402
+ PNG is single-input and requires `--output` so binary bytes are never accidentally printed to a terminal. Portable controls are `--scale`, `--bg`, and the mutually exclusive `--fit-width`/`--fit-height`; native-host font controls are `--font-dirs` and `--system-fonts`. `am init-agent` writes a non-clobbering agent-agnostic onboarding bundle (`AGENTS.md`, root `skills/`, and `.mcp.json`) into a consumer repo.
198
403
 
199
404
  ## MCP
200
405
 
201
- The published package exposes Node-runnable bins: `am`, `agentic-mermaid`, and `agentic-mermaid-mcp`.
406
+ The published package exposes Node-runnable bins: `am`, the package-runner
407
+ alias `agentic-mermaid`, and `agentic-mermaid-mcp`.
202
408
 
203
409
  Local `agentic-mermaid-mcp` is Code Mode-first and exposes:
204
410
 
205
411
  - `execute(code)` — primary Code Mode tool with global `mermaid.*` SDK.
206
- - `render_png` — narrow helper returning base64 PNG bytes, or managed file/URL artifacts via `output: "file"|"url"`.
412
+ - `describe_sdk({ family, detail })` — version-matched compact signatures or exact mutation fields for one family.
413
+ - `render_png` — narrow helper returning base64 PNG bytes, or managed file/URL artifacts via `output: "file"|"url"`; accepts portable `scale`/`background`/`fitTo`, plus local-only `fontDirs`/`loadSystemFonts`, and returns configuration/font-coverage warnings with every output mode.
207
414
  - `describe` — narrow summary helper; pass `format: "facts"` for deterministic semantic fact lines.
208
415
 
209
- Use Code Mode for multi-step parse/narrow/mutate/verify/serialize loops. Use `render_png` or host/library code for binary PNG output. The default transport is stdio; `agentic-mermaid-mcp --transport http --host 127.0.0.1 --port 3000` starts the HTTP/SSE transport. HTTP mode serves managed artifacts from `/artifacts/<name>` with MIME type, byte count, and SHA-256 metadata in tool responses. Non-loopback HTTP binding requires `--auth-token`.
416
+ Use Code Mode for multi-step parse/narrow/mutate/verify/serialize loops. Use `render_png` or host/library code for binary PNG output. The default transport is stdio; `agentic-mermaid-mcp --transport http --host 127.0.0.1 --port 3000` starts the HTTP/SSE transport. HTTP mode serves managed artifacts from `/artifacts/<name>` with MIME type, byte count, and SHA-256 metadata in tool responses. Non-loopback HTTP binding requires `--auth-token`; that bearer token protects `/rpc`, `/sse`, `/message`, and `/artifacts/*`.
210
417
 
211
- A hosted Streamable HTTP endpoint also runs at `https://agentic-mermaid.dev/mcp`. It is MCP JSON-RPC only (not REST), stateless, public/unauthenticated, and capped at 64 KB inputs. Hosted tools are `execute`, `render_svg`, `render_ascii`, `render_png`, `verify`, `describe`, `mutate`, and `build`; hosted `execute` uses a Cloudflare Dynamic Worker isolate with no network, and hosted `render_png` returns base64 only. Prefer local CLI/library/MCP for sensitive diagrams, offline work, larger inputs, or file/URL PNG artifacts. See [`mcp-http-transport.md`](./mcp-http-transport.md) for JSON-RPC examples and option details.
418
+ A hosted Streamable HTTP endpoint also runs at `https://agentic-mermaid.dev/mcp`. It is MCP JSON-RPC only (not REST), stateless, public/unauthenticated, and capped at 64 KB inputs. Hosted tools are `execute`, `describe_sdk`, `render_svg`, `render_ascii`, `render_png`, `verify`, `describe`, `mutate`, and `build`; `describe_sdk` returns compact signatures or exact mutation fields for one family, hosted `execute` uses a Cloudflare Dynamic Worker isolate with no network, and hosted `render_png` returns base64 only while retaining portable `scale`/`background`/`fitTo`. Prefer local CLI/library/MCP for sensitive diagrams, offline work, larger inputs, native font controls, or file/URL PNG artifacts. See [`mcp-http-transport.md`](./mcp-http-transport.md) for JSON-RPC examples and option details.
package/docs/ascii.md CHANGED
@@ -22,6 +22,12 @@ am render diagram.mmd --format unicode
22
22
 
23
23
  ## Options
24
24
 
25
+ `AsciiRenderOptions` extends the canonical shared `RenderOptions` used by SVG
26
+ and PNG, so Style stacks, colors, font choice, security policy, and other
27
+ shared request fields enter through the same boundary. Call
28
+ `sharedRenderOptionsJsonSchema()` for the machine-readable shared field set.
29
+ The options below are terminal-specific.
30
+
25
31
  ```ts
26
32
  renderMermaidASCII(source, {
27
33
  useAscii: true,
@@ -29,6 +35,7 @@ renderMermaidASCII(source, {
29
35
  paddingY: 2,
30
36
  boxBorderPadding: 1,
31
37
  colorMode: 'none',
38
+ targetWidth: 80,
32
39
  })
33
40
  ```
34
41
 
@@ -40,7 +47,13 @@ renderMermaidASCII(source, {
40
47
  | `boxBorderPadding` | `number` | `1` | Padding inside node boxes. |
41
48
  | `colorMode` | `string` | `'auto'` | `'none'`, `'auto'`, `'ansi16'`, `'ansi256'`, `'truecolor'`, or `'html'`. |
42
49
  | `theme` | `Partial<AsciiTheme>` | — | Override terminal colors. |
43
- | `mermaidConfig` | `MermaidRuntimeConfig` | — | Mermaid-style runtime config. |
50
+ | `maxWidth` | `number` | — | Deprecated best-effort label wrapping; the canvas may exceed it. |
51
+ | `targetWidth` | `number` | — | Hard maximum in terminal display cells; impossible geometry throws `AsciiWidthError` with code `ASCII_TARGET_WIDTH_IMPOSSIBLE`. |
52
+
53
+ HTML is an escaped terminal projection, selected programmatically with
54
+ `renderMermaidASCII(source, { colorMode: 'html' })`. It is not a standalone
55
+ `am render --format` value; CLI discovery advertises only directly supported
56
+ artifact formats.
44
57
 
45
58
  ## ASCII with metadata
46
59
 
@@ -49,10 +62,10 @@ Agents and TUIs can use `renderMermaidASCIIWithMeta` to map terminal cells back
49
62
  ```ts
50
63
  import { renderMermaidASCIIWithMeta } from 'agentic-mermaid/agent'
51
64
 
52
- const { ascii, regions, warnings, routeParity } = renderMermaidASCIIWithMeta(source)
65
+ const { ascii, regions, actions, warnings, routeParity } = renderMermaidASCIIWithMeta(source)
53
66
  ```
54
67
 
55
- `regions` includes best-effort terminal spans for load-bearing node labels, edge labels where mapped, participant/task/chart labels, and subgraph label spans suitable for click mapping. It is not a full cell-by-cell box/edge hit-test tree yet. `routeParity` is an explicit V1 contract: ASCII/Unicode does not consume SVG route certificates directly; the converter seeds edges with shared `classifyRoutes()` route intent and the grid router maps that intent into terminal placement/routing. `warnings` reports structured degradation such as `ASCII_EDGE_REGION_UNMAPPED` when edge cell spans are not instrumented even though route drawing still follows the parity mapping.
68
+ `regions` includes best-effort terminal spans for load-bearing node labels, edge labels where mapped, participant/task/chart labels, and semantic containers such as clusters, sequence fragments, class compartments, chart plots, and radar rings. It is suitable for click mapping, but is not a full cell-by-cell box/edge hit-test tree. `actions` contains inert action metadata only; a host must decide whether and how to handle it. `routeParity` is an explicit V1 contract: ASCII/Unicode does not consume SVG route certificates directly; the converter seeds edges with shared `classifyRoutes()` route intent and the grid router maps that intent into terminal placement/routing. `warnings` reports structured degradation such as `ASCII_EDGE_REGION_UNMAPPED` when edge cell spans are not instrumented even though route drawing still follows the parity mapping.
56
69
 
57
70
  ## Reversing simple flowcharts
58
71
 
@@ -72,19 +85,16 @@ not for reconstructing arbitrary Mermaid source.
72
85
 
73
86
  ## Supported families
74
87
 
75
- ASCII/Unicode output is available from the public entrypoints for:
76
-
77
- - flowchart/state
78
- - sequence
79
- - class
80
- - ER
81
- - timeline
82
- - journey
83
- - XY chart
84
- - architecture
85
- - pie
86
- - quadrant
87
- - gantt
88
+ Family support is registry-driven rather than maintained as a second list in
89
+ this guide. Run `am capabilities --json` for live discovery; the generated
90
+ [Section A capability matrix](./project/section-a-capability-report.md) records
91
+ terminal projection support and named losses for every registered family.
92
+
93
+ Style appearance is projected to terminal colors and glyphs. Use a
94
+ receipt-bearing render API to compare its `appearanceDigest` with graphical
95
+ outputs, and inspect projection diagnostics when a graphical feature has no
96
+ terminal equivalent. `colorMode: 'auto'` disables color for non-TTY output,
97
+ `TERM=dumb`, and `NO_COLOR` before considering color-depth hints.
88
98
 
89
99
  PNG output is separate: use `renderMermaidPNG(source)` or `am render --format png --output file.png` when a raster artifact is required.
90
100