agentic-mermaid 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/CHANGELOG.md +149 -4
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/README.md +25 -32
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/assets/fonts/FONT-LICENSES.md +9 -5
  6. package/assets/fonts/Inter-Bold.ttf +0 -0
  7. package/assets/fonts/Inter-Medium.ttf +0 -0
  8. package/assets/fonts/Inter-Regular.ttf +0 -0
  9. package/assets/fonts/Inter-SemiBold.ttf +0 -0
  10. package/dist/agent-core.d.ts +463 -0
  11. package/dist/agent-core.js +397 -0
  12. package/dist/agent.d.ts +81 -1822
  13. package/dist/agent.js +336 -36839
  14. package/dist/agentic-mermaid-mcp.js +7 -37908
  15. package/dist/am.js +33638 -36261
  16. package/dist/chunk-4QECACIA.js +4702 -0
  17. package/dist/chunk-CDPKJ2BQ.js +37 -0
  18. package/dist/chunk-QKDLMOJJ.js +3487 -0
  19. package/dist/chunk-WI35L7IR.js +615 -0
  20. package/dist/chunk-WN3YDOBG.js +149 -0
  21. package/dist/chunk-ZYMMKQ3I.js +62637 -0
  22. package/dist/index-D54dqSdC.d.ts +6777 -0
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +310 -32836
  25. package/dist/mcp-cli-SBQSTJFC.js +17 -0
  26. package/docs/README.md +14 -6
  27. package/docs/schemas/style-spec.schema.json +1221 -30
  28. package/examples/styles/catalog.json +54 -0
  29. package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
  30. package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
  31. package/examples/styles/cupertino-prototype.mmd +10 -0
  32. package/examples/styles/cupertino-prototype.style.json +63 -0
  33. package/examples/styles/mid-century-report.style.json +2 -2
  34. package/examples/styles/star-chart-atlas.style.json +2 -1
  35. package/examples/styles/transit-route-map.style.json +2 -2
  36. package/examples/styles/vercel-inspired-prototype.mmd +6 -0
  37. package/examples/styles/vercel-inspired-prototype.style.json +87 -0
  38. package/package.json +70 -43
  39. package/server.json +41 -0
  40. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
  41. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
  42. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
  43. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
  44. package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
  45. package/AGENT_NATIVE.md +0 -602
  46. package/Instructions_for_agents.md +0 -83
  47. package/TODO.md +0 -662
  48. package/assets/hero.png +0 -0
  49. package/dist/index-x2Cj1dVv.d.ts +0 -1089
  50. package/docs/agent-api-cookbook.md +0 -308
  51. package/docs/agent-mutation-policy.md +0 -104
  52. package/docs/agent-workflow-examples.md +0 -46
  53. package/docs/api.md +0 -203
  54. package/docs/ascii.md +0 -103
  55. package/docs/assets/improvements/box-start-connector.png +0 -0
  56. package/docs/assets/improvements/comment-dropped-lint.png +0 -0
  57. package/docs/assets/improvements/er-content-loss.png +0 -0
  58. package/docs/assets/improvements/fan-in-trunks.png +0 -0
  59. package/docs/assets/improvements/gantt-family.png +0 -0
  60. package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
  61. package/docs/assets/improvements/gantt-verify-seam.png +0 -0
  62. package/docs/assets/improvements/subgraph-container-edges.png +0 -0
  63. package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
  64. package/docs/assets/improvements/wrapper-init-directive.png +0 -0
  65. package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
  66. package/docs/assets/style-cookbook/mid-century-report.png +0 -0
  67. package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
  68. package/docs/assets/style-cookbook/transit-route-map.png +0 -0
  69. package/docs/comparison.md +0 -94
  70. package/docs/config.md +0 -105
  71. package/docs/contributing/adding-diagram-types.md +0 -144
  72. package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
  73. package/docs/contributing/diagram-family-citizenship.md +0 -82
  74. package/docs/contributing/harvesting-upstream-tests.md +0 -126
  75. package/docs/contributing/lessons-learned.md +0 -276
  76. package/docs/contributing/releasing.md +0 -71
  77. package/docs/contributing/visual-review-evidence.md +0 -53
  78. package/docs/custom-style-cookbook.md +0 -154
  79. package/docs/design/families/README.md +0 -26
  80. package/docs/design/families/architecture-beta.md +0 -48
  81. package/docs/design/families/flowchart-parser-conformance.md +0 -22
  82. package/docs/design/families/gantt-research.md +0 -137
  83. package/docs/design/families/gantt.md +0 -329
  84. package/docs/design/families/journey-agentic-cards-before.png +0 -0
  85. package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
  86. package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
  87. package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
  88. package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
  89. package/docs/design/families/journey-migration-parity.md +0 -433
  90. package/docs/design/families/journey-usage-research.md +0 -423
  91. package/docs/design/families/journey.md +0 -125
  92. package/docs/design/families/xychart.md +0 -85
  93. package/docs/design/system/README.md +0 -45
  94. package/docs/design/system/abstraction-audit.md +0 -224
  95. package/docs/design/system/abstraction-recommendations.md +0 -655
  96. package/docs/design/system/architecture.mmd +0 -29
  97. package/docs/design/system/architecture.svg +0 -137
  98. package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
  99. package/docs/design/system/layout-rubric.md +0 -138
  100. package/docs/design/system/route-contracts.md +0 -848
  101. package/docs/design/system/source-preservation-ladder.md +0 -52
  102. package/docs/design/system/styles-rollout.md +0 -216
  103. package/docs/design/system/ugly-layouts.md +0 -119
  104. package/docs/diagram-families.md +0 -193
  105. package/docs/features.md +0 -147
  106. package/docs/fork-differences.md +0 -130
  107. package/docs/getting-started.md +0 -175
  108. package/docs/issue-derived-test-cases.md +0 -156
  109. package/docs/layout-characterization/README.md +0 -245
  110. package/docs/layout-characterization/contact-sheet-families.md +0 -496
  111. package/docs/layout-characterization/contact-sheet.md +0 -638
  112. package/docs/layout-characterization/properties.md +0 -281
  113. package/docs/layout-characterization/visual-quality.md +0 -160
  114. package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
  115. package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
  116. package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
  117. package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
  118. package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
  119. package/docs/layout-characterization/visual-snapshots/journey.svg +0 -118
  120. package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
  121. package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
  122. package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
  123. package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
  124. package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
  125. package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
  126. package/docs/mcp-code-mode-rationale.md +0 -101
  127. package/docs/mcp-http-transport.md +0 -223
  128. package/docs/mermaid-layout-complaints.md +0 -837
  129. package/docs/mutation-testing.md +0 -206
  130. package/docs/project/divergences.md +0 -98
  131. package/docs/project/dogfooding-docs-strategy.md +0 -66
  132. package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
  133. package/docs/project/lessons-learned.md +0 -1019
  134. package/docs/project/remove-role-styling-plan.md +0 -176
  135. package/docs/quality.md +0 -212
  136. package/docs/react.md +0 -97
  137. package/docs/style-authoring.md +0 -133
  138. package/docs/testing-strategy.md +0 -335
  139. package/docs/theming.md +0 -162
  140. package/examples/agent-improve-auth-flow.ts +0 -206
  141. package/examples/agent-loop.ts +0 -53
  142. package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
  143. package/llms.txt +0 -104
  144. package/skill-evals/README.md +0 -77
  145. package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
  146. package/skill-evals/fixtures/class-payment/input.mmd +0 -4
  147. package/skill-evals/fixtures/er-orders/input.mmd +0 -10
  148. package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
  149. package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
  150. package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
  151. package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
  152. package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
  153. package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
  154. package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
  155. package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
  156. package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
  157. package/skill-evals/shared-benchmark.json +0 -510
  158. package/src/agent/analyze.ts +0 -157
  159. package/src/agent/apply.ts +0 -146
  160. package/src/agent/architecture-body.ts +0 -458
  161. package/src/agent/certificates.ts +0 -110
  162. package/src/agent/class-body.ts +0 -319
  163. package/src/agent/core.ts +0 -207
  164. package/src/agent/create.ts +0 -106
  165. package/src/agent/describe.ts +0 -364
  166. package/src/agent/er-body.ts +0 -224
  167. package/src/agent/facts.ts +0 -337
  168. package/src/agent/families-builtin.ts +0 -934
  169. package/src/agent/families.ts +0 -232
  170. package/src/agent/family-layouts.ts +0 -826
  171. package/src/agent/flowchart-body.ts +0 -372
  172. package/src/agent/flowchart-unsupported.ts +0 -243
  173. package/src/agent/gantt-body.ts +0 -495
  174. package/src/agent/index.ts +0 -10
  175. package/src/agent/journey-body.ts +0 -414
  176. package/src/agent/label-metrics.ts +0 -28
  177. package/src/agent/layout-to-rendered.ts +0 -63
  178. package/src/agent/mutate.ts +0 -97
  179. package/src/agent/mutation-ops.ts +0 -51
  180. package/src/agent/op-schema.ts +0 -439
  181. package/src/agent/parse.ts +0 -223
  182. package/src/agent/pie-body.ts +0 -270
  183. package/src/agent/png.ts +0 -117
  184. package/src/agent/quadrant-body.ts +0 -336
  185. package/src/agent/quality.ts +0 -363
  186. package/src/agent/readability-audit.ts +0 -92
  187. package/src/agent/rendered-route-audit.ts +0 -61
  188. package/src/agent/sequence-body.ts +0 -345
  189. package/src/agent/serialize.ts +0 -214
  190. package/src/agent/state-body.ts +0 -589
  191. package/src/agent/structural-count.ts +0 -150
  192. package/src/agent/timeline-body.ts +0 -280
  193. package/src/agent/trace-log.ts +0 -43
  194. package/src/agent/types.ts +0 -979
  195. package/src/agent/verify.ts +0 -571
  196. package/src/agent/xychart-body.ts +0 -472
  197. package/src/architecture/config.ts +0 -282
  198. package/src/architecture/layout.ts +0 -496
  199. package/src/architecture/parser.ts +0 -375
  200. package/src/architecture/renderer.ts +0 -611
  201. package/src/architecture/types.ts +0 -113
  202. package/src/ascii/ansi.ts +0 -423
  203. package/src/ascii/architecture.ts +0 -210
  204. package/src/ascii/canvas.ts +0 -443
  205. package/src/ascii/class-diagram.ts +0 -697
  206. package/src/ascii/converter.ts +0 -475
  207. package/src/ascii/draw.ts +0 -1693
  208. package/src/ascii/edge-bundling.ts +0 -328
  209. package/src/ascii/edge-routing.ts +0 -330
  210. package/src/ascii/er-diagram.ts +0 -439
  211. package/src/ascii/gantt.ts +0 -276
  212. package/src/ascii/grid.ts +0 -747
  213. package/src/ascii/index.ts +0 -196
  214. package/src/ascii/journey.ts +0 -189
  215. package/src/ascii/meta.ts +0 -244
  216. package/src/ascii/multiline-utils.ts +0 -80
  217. package/src/ascii/pathfinder.ts +0 -301
  218. package/src/ascii/pie.ts +0 -67
  219. package/src/ascii/quadrant.ts +0 -158
  220. package/src/ascii/reverse.ts +0 -216
  221. package/src/ascii/sequence.ts +0 -499
  222. package/src/ascii/shapes/circle.ts +0 -27
  223. package/src/ascii/shapes/corners.ts +0 -143
  224. package/src/ascii/shapes/diamond.ts +0 -27
  225. package/src/ascii/shapes/hexagon.ts +0 -27
  226. package/src/ascii/shapes/index.ts +0 -106
  227. package/src/ascii/shapes/rectangle.ts +0 -168
  228. package/src/ascii/shapes/rounded.ts +0 -27
  229. package/src/ascii/shapes/special.ts +0 -332
  230. package/src/ascii/shapes/stadium.ts +0 -110
  231. package/src/ascii/shapes/state.ts +0 -192
  232. package/src/ascii/shapes/types.ts +0 -73
  233. package/src/ascii/timeline.ts +0 -128
  234. package/src/ascii/types.ts +0 -312
  235. package/src/ascii/validate.ts +0 -120
  236. package/src/ascii/width.ts +0 -81
  237. package/src/ascii/xychart.ts +0 -919
  238. package/src/browser.ts +0 -29
  239. package/src/class/layout.ts +0 -240
  240. package/src/class/parser.ts +0 -332
  241. package/src/class/renderer.ts +0 -638
  242. package/src/class/types.ts +0 -129
  243. package/src/cli/agent-instructions.ts +0 -1
  244. package/src/cli/am-bin.ts +0 -6
  245. package/src/cli/exit-codes.ts +0 -18
  246. package/src/cli/index.ts +0 -1117
  247. package/src/cli/init-agent.ts +0 -147
  248. package/src/color-resolver.ts +0 -152
  249. package/src/elk-instance.ts +0 -114
  250. package/src/er/layout.ts +0 -187
  251. package/src/er/parser.ts +0 -226
  252. package/src/er/renderer.ts +0 -792
  253. package/src/er/types.ts +0 -99
  254. package/src/font-manifest.ts +0 -27
  255. package/src/gantt/layout.ts +0 -365
  256. package/src/gantt/parser.ts +0 -282
  257. package/src/gantt/pipeline.ts +0 -27
  258. package/src/gantt/renderer.ts +0 -414
  259. package/src/gantt/schedule.ts +0 -513
  260. package/src/gantt/types.ts +0 -255
  261. package/src/index.ts +0 -368
  262. package/src/journey/layout.ts +0 -520
  263. package/src/journey/parser.ts +0 -218
  264. package/src/journey/renderer.ts +0 -811
  265. package/src/journey/types.ts +0 -144
  266. package/src/layout/geometry.ts +0 -182
  267. package/src/layout/pass.ts +0 -142
  268. package/src/layout/passes/index.ts +0 -3916
  269. package/src/layout-engine.ts +0 -1565
  270. package/src/layout-rubric.ts +0 -659
  271. package/src/mcp/artifacts.ts +0 -137
  272. package/src/mcp/dynamic-harness.ts +0 -31
  273. package/src/mcp/dynamic-modules.d.ts +0 -7
  274. package/src/mcp/facade.ts +0 -608
  275. package/src/mcp/harness-runtime.ts +0 -203
  276. package/src/mcp/hosted-server.ts +0 -468
  277. package/src/mcp/mcp-bin.ts +0 -3
  278. package/src/mcp/mcp-cli.ts +0 -82
  279. package/src/mcp/protocol.ts +0 -13
  280. package/src/mcp/sandbox.ts +0 -195
  281. package/src/mcp/sdk-decl.ts +0 -387
  282. package/src/mcp/server.ts +0 -362
  283. package/src/mcp/tool-surface.ts +0 -146
  284. package/src/mermaid-source.ts +0 -655
  285. package/src/multiline-utils.ts +0 -228
  286. package/src/parser.ts +0 -1031
  287. package/src/pie/layout.ts +0 -168
  288. package/src/pie/parser.ts +0 -136
  289. package/src/pie/renderer.ts +0 -234
  290. package/src/pie/types.ts +0 -82
  291. package/src/quadrant/layout.ts +0 -191
  292. package/src/quadrant/parser.ts +0 -183
  293. package/src/quadrant/renderer.ts +0 -322
  294. package/src/quadrant/types.ts +0 -113
  295. package/src/render-family-hooks.ts +0 -244
  296. package/src/renderer.ts +0 -1099
  297. package/src/route-contracts.ts +0 -2723
  298. package/src/scene/backend.ts +0 -76
  299. package/src/scene/fidelity.ts +0 -183
  300. package/src/scene/hybrid-backend.ts +0 -174
  301. package/src/scene/ir.ts +0 -181
  302. package/src/scene/marks.ts +0 -127
  303. package/src/scene/rough-backend.ts +0 -378
  304. package/src/scene/seed.ts +0 -46
  305. package/src/scene/style-registry.ts +0 -556
  306. package/src/sequence/layout.ts +0 -456
  307. package/src/sequence/parser.ts +0 -255
  308. package/src/sequence/renderer.ts +0 -604
  309. package/src/sequence/types.ts +0 -154
  310. package/src/shape-clipping.ts +0 -351
  311. package/src/shared/accessibility-directives.ts +0 -22
  312. package/src/shared/batched.ts +0 -61
  313. package/src/shared/color-math.ts +0 -72
  314. package/src/shared/svg-a11y.ts +0 -29
  315. package/src/shared/syntax-error.ts +0 -17
  316. package/src/shared/unicode-ranges.ts +0 -135
  317. package/src/styles.ts +0 -318
  318. package/src/svg-paths.ts +0 -28
  319. package/src/text-metrics.ts +0 -248
  320. package/src/theme.ts +0 -639
  321. package/src/timeline/layout.ts +0 -381
  322. package/src/timeline/parser.ts +0 -215
  323. package/src/timeline/renderer.ts +0 -538
  324. package/src/timeline/types.ts +0 -105
  325. package/src/types.ts +0 -454
  326. package/src/website-worker-modules.d.ts +0 -18
  327. package/src/xychart/axis-utils.ts +0 -109
  328. package/src/xychart/colors.ts +0 -124
  329. package/src/xychart/config.ts +0 -88
  330. package/src/xychart/layout.ts +0 -656
  331. package/src/xychart/parser.ts +0 -504
  332. package/src/xychart/renderer.ts +0 -640
  333. package/src/xychart/types.ts +0 -282
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agentic-mermaid-diagram-workflow
3
- description: Agent-agnostic skill for authoring and editing Mermaid diagrams with structured verification, typed mutation, round-trip serialization, and SVG, PNG, ASCII, Unicode, and JSON layout outputs. Structured mutation for all twelve renderable families (flowchart, state, sequence, timeline, class, ER, journey, architecture, xychart, pie, quadrant, gantt); source-level parse-and-render only for opaque fallbacks (unmodeled syntax).
3
+ description: Agent-agnostic skill for authoring and editing Mermaid diagrams with structured verification, typed mutation, round-trip serialization, and graphical, terminal, and layout outputs. The live capability registry identifies renderable and mutable families; unmodeled syntax remains source-preserved.
4
4
  ---
5
5
 
6
6
  # Agentic Mermaid — diagram workflow
@@ -12,40 +12,20 @@ An agent-agnostic typed editing surface for Mermaid. New diagrams can be authore
12
12
  - `agentic-mermaid-mcp` connected → **Code Mode** (`references/code-mode.md`). Multi-step edits in one round-trip.
13
13
  - Can run JS/TS with imports → **library** (`agentic-mermaid/agent`). Same SDK.
14
14
  - Shell only → **CLI** (`references/cli.md`).
15
- - No local install, network only → **hosted MCP** at `https://agentic-mermaid.dev/mcp` (stateless streamable HTTP JSON-RPC; the `execute` Code Mode tool plus `render_svg`/`render_ascii`/`render_png`/`verify`/`describe` and the declarative `mutate` (edit a `source`) / `build` (author from a `family`) tools — prefer `mutate`/`build` for structured edits; 64KB input caps).
16
-
17
- ## Capability matrix
18
-
19
- | Family | parse | verify | render | mutate | serialize |
20
- |---|---|---|---|---|---|
21
- | Flowchart | ✓ | full (Tier 1+2) | ✓ | 6 ops | structured |
22
- | **State (modeled subset)** | ✓ | full (Tier 1+2) | ✓ | **8 ops** | structured |
23
- | State (`<<fork>>`/`<<choice>>`/notes/`--`/`classDef`, unmodeled) | ✓ | structural | ✓ | — (opaque) | verbatim |
24
- | Sequence (simple) | ✓ | structural | ✓ | 5 ops | structured |
25
- | Sequence (notes/alt/loop/…) | ✓ | structural | ✓ | **5 ops** | structured-with-segments |
26
- | Sequence (un-segmentable, e.g. unbalanced `end`) | ✓ | structural | ✓ | — (opaque) | verbatim |
27
- | Timeline (simple) | ✓ | structural | ✓ | 10 ops | structured |
28
- | Timeline (unmodeled syntax) | ✓ | structural | ✓ | — (opaque) | verbatim |
29
- | **Class (simple)** | ✓ | structural | ✓ | **10 ops** | structured |
30
- | Class (unmodeled syntax) | ✓ | structural | ✓ | — (opaque) | verbatim |
31
- | **ER (simple)** | ✓ | structural | ✓ | **7 ops** | structured |
32
- | ER (unmodeled syntax) | ✓ | structural | ✓ | — (opaque) | verbatim |
33
- | **Journey (simple)** | ✓ | structural | ✓ | **10 ops** | structured |
34
- | Journey (accTitle/accDescr, unmodeled) | ✓ | structural | ✓ | — (opaque) | verbatim |
35
- | **Architecture (modeled subset)** | ✓ | structural | ✓ | **10 ops** | structured |
36
- | Architecture (`{group}` boundary, accTitle/accDescr) | ✓ | structural | ✓ | — (opaque) | verbatim |
37
- | **XY chart (modeled subset)** | ✓ | structural | ✓ | **8 ops** | structured |
38
- | XY chart (quoted text, `;` lines, accTitle/accDescr) | ✓ | structural | ✓ | — (opaque) | verbatim |
39
- | **Pie (simple)** | ✓ | structural | ✓ | **7 ops** | structured |
40
- | Pie (accTitle/accDescr, malformed entries) | ✓ | structural | ✓ | — (opaque) | verbatim |
41
- | **Quadrant (modeled subset)** | ✓ | structural | ✓ | **7 ops** | structured |
42
- | Quadrant (styling `classDef`/`:::`, out-of-range coords) | ✓ | structural | ✓ | — (opaque) | verbatim |
43
- | **Gantt (modeled subset)** | ✓ | structural + schedule | ✓ | **9 ops** | structured-with-segments |
44
- | Gantt (duplicate ids / unclosed `accDescr`) | ✓ | structural | ✓ | — (opaque) | verbatim |
15
+ - No local install, network only → **hosted MCP** at `https://agentic-mermaid.dev/mcp` (stateless streamable HTTP JSON-RPC; `execute` Code Mode, `describe_sdk` for one family's mutation schema on demand, `render_svg`/`render_ascii`/`render_png`/`verify`/`describe`, and the declarative `mutate` (edit a `source`) / `build` (author from a `family`) tools — prefer `mutate`/`build` for structured edits; 64KB input caps).
16
+
17
+ ## Capability discovery
18
+
19
+ Run `am capabilities --json` (or call the equivalent SDK capability API) before
20
+ choosing a family or mutation. Its registry-derived family entries expose the
21
+ current narrower, operation schema, edit policy, output support, and minimal
22
+ source example; the generated Section A matrix supplies explicit native,
23
+ source-preserved, diagnosed, and absent states. This skill intentionally does
24
+ not maintain a second family or operation table.
45
25
 
46
26
  Any diagram with constructs we don't model falls back to an **opaque** body: it still parses, renders, verifies, and round-trips losslessly — it just isn't offered for structured mutation (the narrower returns null). The parser never silently drops anything.
47
27
 
48
- State diagrams own a dedicated body (BUILD-19): narrow them with `asState` and apply state-shaped ops (`add_state`, `remove_state`, `rename_state`, `set_state_label`, `add_transition`, `remove_transition`, `set_transition_label`, `make_composite`). `asFlowchart` returns null on a state diagram. The modeled subset is simple states, transitions, `[*]` start/end pseudostates, composite blocks, and `direction`; anything else (`<<fork>>`/`<<choice>>`/`<<join>>`, history states, concurrency `--`, notes, `classDef`/`class`/`:::` styling) keeps the whole body opaque and round-trips verbatim.
28
+ State diagrams own a dedicated body: `asState` models states/transitions, `[*]`, composites, stereotypes/history, concurrency regions, notes, bare declarations, and class/inline paint. `asFlowchart` returns null on a state diagram.
49
29
 
50
30
  Gantt diagrams are segment-preserving: `asGantt` keeps title/section/task ops live while calendar directives (`dateFormat`, `axisFormat`, `excludes`, `includes`, `weekend`, `weekday`, `todayMarker`, `tickInterval`, `inclusiveEndDates`, `topAxis`), `click` lines, comments, and accessibility lines ride along verbatim. Gantt rendering is deterministic and never reads the wall clock; pass `ganttToday` when rendering if a `todayMarker` should be visible.
51
31
 
@@ -53,10 +33,11 @@ Gantt diagrams are segment-preserving: `asGantt` keeps title/section/task ops li
53
33
 
54
34
  ## Workflow
55
35
 
56
- For new diagrams, author Mermaid source directly, then `parseMermaid` / `verifyMermaid` / render. For existing modeled diagrams:
36
+ For new diagrams, author Mermaid source directly, then `parseRegisteredMermaid` / `verifyMermaid` / render. For existing modeled diagrams:
57
37
 
58
- 1. `parseMermaid(source)` → `ValidDiagram`.
59
- 2. `asFlowchart(d)` / `asState(d)` / `asSequence(d)` / `asTimeline(d)` / `asClass(d)` / `asEr(d)` / `asJourney(d)` / `asArchitecture(d)` / `asXyChart(d)` / `asPie(d)` / `asQuadrant(d)` / `asGantt(d)` to narrow before mutating.
38
+ 1. `parseRegisteredMermaid(source)` → `ValidDiagram`.
39
+ 2. Use the family entry's advertised narrower (for example `asFlowchart(d)` or
40
+ `asState(d)`) before mutating.
60
41
  3. `mutate(d, op)` (typed per family).
61
42
  4. `verifyMermaid(d)` — structured warnings; inspect `ok` / `warnings` / `layout`.
62
43
  5. On `!ok`, revert to the previous `ValidDiagram`, try another op.
@@ -67,7 +48,7 @@ Do not regenerate or concatenate source to edit an existing structured diagram w
67
48
  Minimal existing-flowchart pattern:
68
49
 
69
50
  ```ts
70
- const parsed = parseMermaid(source)
51
+ const parsed = parseRegisteredMermaid(source)
71
52
  if (!parsed.ok) return { phase: 'parse', errors: parsed.error }
72
53
  let cur = asFlowchart(parsed.value)
73
54
  if (!cur) return { phase: 'narrow', family: parsed.value.kind }
@@ -3,7 +3,7 @@
3
3
  Agentic Mermaid outputs SVG, PNG, ASCII, Unicode, and JSON layout through the CLI.
4
4
 
5
5
  ```text
6
- am render <file|-> --format svg|ascii|unicode|json
6
+ am render <file|-> --format svg|ascii|unicode|layout
7
7
  am render <file> --format png --output file.png # one-shot only; no watch/multi-input
8
8
  am preview <file|-> [--output preview.html] [--open] [--json] [--security strict] # strict standalone HTML
9
9
  am verify <file|-> structured JSON warnings (exit 3 if not ok)
@@ -22,10 +22,9 @@ am --agent-instructions canonical agent guide
22
22
  am <cmd> --help per-command help
23
23
  ```
24
24
 
25
- `am verify` always emits JSON. `am mutate` dispatches by family across
26
- flowchart, state, sequence, timeline, class, ER, journey, architecture,
27
- xychart, pie, quadrant, and gantt; opaque fallback bodies return a structured
28
- `UNSUPPORTED_FAMILY` error. `am mutate` verifies before emitting source; verify
25
+ `am verify` always emits JSON. `am mutate` dispatches across the live mutable
26
+ family roster reported by `am capabilities --json`; opaque fallback bodies
27
+ return a structured `UNSUPPORTED_FAMILY` error. `am mutate` verifies before emitting source; verify
29
28
  failure exits 3 and omits `source`. Use direct Mermaid source authoring plus
30
29
  `am verify`/`am render` for brand-new diagrams; reserve `am mutate` for
31
30
  existing structured diagrams. `am parse | am serialize` round-trips through JSON.
@@ -1,7 +1,11 @@
1
1
  # Code Mode (structured edit channel)
2
2
 
3
3
  `agentic-mermaid-mcp` exposes a primary Code Mode tool, `execute(code)`, plus
4
- narrow `render_png` and `describe` helpers. The server runs JavaScript in a
4
+ narrow `describe_sdk`, `render_png`, and `describe` helpers. The initial
5
+ `execute` declaration contains only the core SDK. Call
6
+ `describe_sdk({ family, detail: 'fields' })` before an unfamiliar mutation to
7
+ load that family's exact schema; use `detail: 'signatures'` for a compact menu.
8
+ The server runs JavaScript in a
5
9
  `node:vm` sandbox with `mermaid.*` as a global; the TypeScript declaration in
6
10
  the MCP prompt is for guidance, not transpilation. SDK-returned diagrams are
7
11
  read-only in Code Mode; use `mermaid.mutate(...)` for structured edits instead
@@ -12,31 +16,11 @@ verify-before-commit loop is one round-trip.
12
16
  ## SDK shape
13
17
 
14
18
  ```text
15
- mermaid.parseMermaid(source): Result<ValidDiagram, ParseError[]>
16
- mermaid.asFlowchart(d): FlowchartValidDiagram | null
17
- mermaid.asState(d): StateValidDiagram | null
18
- mermaid.asSequence(d): SequenceValidDiagram | null
19
- mermaid.asTimeline(d): TimelineValidDiagram | null
20
- mermaid.asClass(d): ClassValidDiagram | null
21
- mermaid.asEr(d): ErValidDiagram | null
22
- mermaid.asJourney(d): JourneyValidDiagram | null
23
- mermaid.asArchitecture(d): ArchitectureValidDiagram | null
24
- mermaid.asXyChart(d): XyChartValidDiagram | null
25
- mermaid.asPie(d): PieValidDiagram | null
26
- mermaid.asQuadrant(d): QuadrantValidDiagram | null
27
- mermaid.asGantt(d): GanttValidDiagram | null
28
- mermaid.mutate(flow, FlowchartMutationOp): Result<FlowchartValidDiagram, MutationError>
29
- mermaid.mutate(state, StateMutationOp): Result<StateValidDiagram, MutationError>
30
- mermaid.mutate(seq, SequenceMutationOp): Result<SequenceValidDiagram, MutationError>
31
- mermaid.mutate(timeline, TimelineMutationOp): Result<TimelineValidDiagram, MutationError>
32
- mermaid.mutate(klass, ClassMutationOp): Result<ClassValidDiagram, MutationError>
33
- mermaid.mutate(er, ErMutationOp): Result<ErValidDiagram, MutationError>
34
- mermaid.mutate(journey, JourneyMutationOp): Result<JourneyValidDiagram, MutationError>
35
- mermaid.mutate(arch, ArchitectureMutationOp): Result<ArchitectureValidDiagram, MutationError>
36
- mermaid.mutate(xy, XyChartMutationOp): Result<XyChartValidDiagram, MutationError>
37
- mermaid.mutate(pie, PieMutationOp): Result<PieValidDiagram, MutationError>
38
- mermaid.mutate(quad, QuadrantMutationOp): Result<QuadrantValidDiagram, MutationError>
39
- mermaid.mutate(gantt, GanttMutationOp): Result<GanttValidDiagram, MutationError>
19
+ mermaid.parseRegisteredMermaid(source): Result<ValidDiagram, ParseError[]>
20
+ mermaid.asFlowchart(d): FlowchartValidDiagram | null // example narrower
21
+ mermaid.mutate(narrowed, op): Result<ValidDiagram, MutationError> // concrete overload preserves the family
22
+ // Call describe_sdk({ family, detail: 'fields' }) for the registry-derived
23
+ // narrower and exact family operation overloads.
40
24
  mermaid.verifyMermaid(input, { suppress?, labelCharCap? }): VerifyResult
41
25
  mermaid.describeMermaidFacts(d): string[]
42
26
  mermaid.checkMermaid(d, spec): { ok: boolean; missing: string[]; unexpected: string[]; facts: string[] }
@@ -45,7 +29,7 @@ mermaid.renderMermaidASCII(input, { useAscii?: boolean, ganttToday?: string, mer
45
29
  mermaid.renderMermaidSVG(input, { security?: 'default'|'strict', idPrefix?, ganttToday?: string, mermaidConfig?: MermaidRuntimeConfig }): string
46
30
  ```
47
31
 
48
- Agentic Mermaid outputs SVG, PNG, ASCII, Unicode, and JSON layout. In Code Mode, render SVG and text through `mermaid.*`: `renderMermaidASCII(input, { useAscii: true })` returns ASCII and `useAscii: false` returns Unicode box-drawing text. Use the narrow MCP `render_png` helper or host/library code for PNG binary output; JSON layout is available on `verifyMermaid(...).layout` and through the CLI/library layout APIs. `MermaidRuntimeConfig` matches the runtime config surface: arbitrary Mermaid config keys plus `theme`, `fontFamily`, `themeVariables`, `timeline`, `xyChart`, `gantt`, `useMaxWidth`, `useWidth`, and `themeCSS`. `ganttToday` is a render option, not a clock read; pass it when a Gantt `todayMarker` should render.
32
+ Agentic Mermaid outputs SVG, PNG, ASCII, Unicode, and JSON layout. In Code Mode, render SVG and text through `mermaid.*`: `renderMermaidASCII(input, { useAscii: true })` returns ASCII and `useAscii: false` returns Unicode box-drawing text. Use the narrow MCP `render_png` helper or host/library code for PNG binary output; JSON layout is available on `verifyMermaid(...).layout` and through the CLI/library layout APIs. `MermaidRuntimeConfig` matches the runtime config surface: arbitrary Mermaid config keys plus `theme`, `fontFamily`, `themeVariables`, `timeline`, `xyChart`, `gantt`, `mindmap`, `gitGraph`, `useMaxWidth`, `useWidth`, and `themeCSS`. `ganttToday` is a render option, not a clock read; pass it when a Gantt `todayMarker` should render.
49
33
 
50
34
  All SDK methods are synchronous and pure. Code Mode does not support `async`/`await`, Promise jobs, or dynamic import. Layout is deterministic; there is no layout seed (the render option `seed` only re-rolls ink of styled looks — `style: name | record | stack` — and never moves geometry).
51
35
 
@@ -53,7 +37,7 @@ All SDK methods are synchronous and pure. Code Mode does not support `async`/`aw
53
37
 
54
38
  ```ts
55
39
  const source = 'flowchart LR\n User --> Login\n Login --> Dashboard'
56
- const parsed = mermaid.parseMermaid(source)
40
+ const parsed = mermaid.parseRegisteredMermaid(source)
57
41
  if (!parsed.ok) return { phase: 'parse', errors: parsed.error }
58
42
  const v = mermaid.verifyMermaid(parsed.value)
59
43
  if (!v.ok) return { phase: 'verify', warnings: v.warnings }
@@ -68,7 +52,7 @@ const ops = [
68
52
  { kind: 'add_node', id: 'Cache', label: 'Cache' },
69
53
  { kind: 'add_edge', from: 'API', to: 'Cache' },
70
54
  ]
71
- const r0 = mermaid.parseMermaid(source)
55
+ const r0 = mermaid.parseRegisteredMermaid(source)
72
56
  if (!r0.ok) return { phase: 'parse', errors: r0.error }
73
57
  const flow = mermaid.asFlowchart(r0.value)
74
58
  if (!flow) return { phase: 'narrow', kind: r0.value.kind }
@@ -86,7 +70,7 @@ return { source: mermaid.serializeMermaid(cur) }
86
70
  ## Sequence pattern
87
71
 
88
72
  ```ts
89
- const r0 = mermaid.parseMermaid('sequenceDiagram\n Alice->>Bob: Hi')
73
+ const r0 = mermaid.parseRegisteredMermaid('sequenceDiagram\n Alice->>Bob: Hi')
90
74
  if (!r0.ok) return { errors: r0.error }
91
75
  const seq = mermaid.asSequence(r0.value)
92
76
  if (!seq) return { kind: r0.value.kind, note: 'opaque — no structured sequence mutation' }
@@ -102,7 +86,7 @@ return { source: mermaid.serializeMermaid(r1.value) }
102
86
  ```ts
103
87
  const sources = ['flowchart TD\n A --> C', 'timeline\n 2024 : A ships']
104
88
  return sources.map(src => {
105
- const r = mermaid.parseMermaid(src)
89
+ const r = mermaid.parseRegisteredMermaid(src)
106
90
  if (!r.ok) return { err: r.error }
107
91
  const flow = mermaid.asFlowchart(r.value)
108
92
  if (!flow) return { skipped: true, family: r.value.kind, reason: 'no matching structured op' }
@@ -14,21 +14,17 @@ implicitly by first message reference.
14
14
  Arrows → style: `->>` sync, `-->>` reply, `->` async, `-->` async-dashed,
15
15
  `-x` lost, `--x` lost-dashed.
16
16
 
17
- MutationOps (5): add_participant, remove_participant (cascades to messages),
18
- add_message (implicit participants), remove_message (by index),
19
- set_message_text (by index).
17
+ MutationOps include participant/top-level message edits plus `add_fragment`,
18
+ `remove_fragment`, fragment/branch label edits, and fragment-message add/remove/
19
+ text edits.
20
20
 
21
- IMPORTANT — segment-preserving fidelity (BUILD-18): a sequence diagram that uses
22
- Note/alt/opt/par/loop/critical/break/rect/activate/autonumber/title parses to a
23
- STRUCTURED body that keeps your participant/message ops live. The unmodeled lines
24
- ride along VERBATIM as opaque-block segments, so `asSequence` is non-null and you
25
- can add_message / set_message_text / remove_message as usual. Two rules: (1)
26
- `remove_message`/`set_message_text` indexes address only TOP-LEVEL messages —
27
- messages inside an alt/loop block are part of the verbatim segment and are never
28
- touched; (2) only an un-segmentable diagram (a stray `end`, an unclosed block)
29
- falls back to a whole-body OPAQUE body where `asSequence` returns null — for those,
30
- edit the preserved `body.source` intentionally, then re-parse and verify. Either
31
- way the round-trip is lossless and the parser never silently drops constructs.
21
+ IMPORTANT — segment-preserving fidelity: `alt`, `opt`, `loop`, and `par` are
22
+ typed fragments. Their messages appear in describe/facts/verify and fragment
23
+ ops can author or edit them. Other constructs (Note/critical/break/rect/box/
24
+ activate/autonumber/title) ride along VERBATIM as opaque-block segments while
25
+ participant and top-level message ops remain live. Only an un-segmentable
26
+ diagram (a stray `end`, an unclosed block) falls back to a whole-body OPAQUE
27
+ body. Either way the parser never silently drops constructs.
32
28
 
33
29
  Verify Tier 1 only (no layout engine): EMPTY_DIAGRAM, EDGE_MISANCHORED
34
30
  (message references missing participant), LABEL_OVERFLOW (participant label or
@@ -1,264 +1,158 @@
1
1
  ---
2
2
  name: agentic-mermaid-live-editor-development
3
3
  description: >-
4
- Agent-agnostic development skill for the Agentic Mermaid live editor.
5
- Use when modifying scripts/site/editor.ts, adding Config options, changing the UI, adding
6
- ASCII, PNG, or SVG export behavior, wiring new diagram options, or debugging
7
- the editor page.
4
+ Develop and debug the Agentic Mermaid browser editor, including its modular UI,
5
+ render/verify pipeline, examples, configuration, exports, URL sharing, website
6
+ integration, and browser regression tests.
8
7
  ---
9
8
 
10
- # Agentic Mermaid — live editor development
9
+ # Agentic Mermaid live editor development
11
10
 
12
- This skill is for coding agents modifying the repository. It is not tied to Claude, Cursor, Pi, or any other single coding agent. The editor renders diagrams through Agentic Mermaid and exposes SVG and PNG export actions; the renderer also supports ASCII output in the library/CLI surface.
11
+ Edit the modular editor sources and preserve the contracts shared by the standalone editor and the deployed website.
13
12
 
14
- ## Key files
13
+ ## Source map
15
14
 
16
- | File | Role |
17
- |------|------|
18
- | `scripts/site/editor.ts` | **Source of truth** — generates `editor.html` at build time (also used by `website/build.ts` for the Cloudflare `/editor`) |
19
- | `editor.html` | Generated output — never edit directly |
20
- | `src/browser.ts` | Bundles the renderer for the browser as `window.__mermaid` |
21
- | `src/types.ts` | `RenderOptions` — all supported render options |
22
- | `src/theme.ts` | `THEMES`, `buildStyleBlock`, `svgOpenTag` — CSS variable system |
23
- | `src/styles.ts` | `STROKE_WIDTHS`, `FONT_SIZES` — hardcoded constants |
24
- | `scripts/site/samples-data.ts` | Sample presets used by eval tooling; the editor uses its own inline `SAMPLES` array |
15
+ | Path | Role |
16
+ |---|---|
17
+ | `editor/js/` | Editor behavior. Treat `sharing.js`, `rendering.js`, and `state.js` as contract sources. |
18
+ | `editor/css/` | Editor styling. |
19
+ | `editor/html/` | Top bar and workspace partials. |
20
+ | `editor/examples.ts` | Canonical editor examples. |
21
+ | `scripts/site/editor.ts` | Assemble the standalone `editor.html`. |
22
+ | `website/build.ts` | Assemble the deployed `/editor/` and all public pages that link to it. |
23
+ | `scripts/site/editor-state-url.ts` | Canonical build-time encoder and validator for editor-state URLs. |
24
+ | `src/browser.ts` | Browser renderer API exposed as `window.__mermaid`. |
25
25
 
26
- ## Build cycle
26
+ Do not edit generated `editor.html` or `website/public/` files directly.
27
27
 
28
- ```
29
- scripts/site/editor.ts ──Bun.build──► src/browser.ts bundle (inline JS)
30
- ──template──► editor.html (self-contained, ~1.7 MB)
31
- ```
28
+ ## Build and test cycle
29
+
30
+ Run the target that owns the changed surface:
32
31
 
33
- Run manually:
34
32
  ```bash
35
- bun run editor # generates editor.html once
36
- bun run website:dev # wrangler dev server for the Cloudflare site (serves /editor and the rest)
33
+ bun run editor # standalone editor.html
34
+ bun run website # production website/public, including /editor/
35
+ bun run website:check # committed generated inputs are current
36
+ bun run typecheck
37
37
  ```
38
38
 
39
- **Always rebuild after editing `scripts/site/editor.ts`.** The HTML file is the deployed artifact.
40
-
41
- ---
42
-
43
- ## Architecture overview
39
+ For behavior changes, also run the focused editor unit tests and the browser lane. The browser lane requires Playwright Chromium and `AM_BROWSER_TESTS=1`.
44
40
 
45
- `scripts/site/editor.ts` is a TypeScript generator that:
46
- 1. Calls `Bun.build()` to bundle `src/browser.ts` → inline JS string
47
- 2. Constructs the full HTML page as a template literal
48
- 3. Writes `editor.html`
41
+ ## State contract
49
42
 
50
- The page has **no runtime build step** — everything (renderer, UI logic, CSS) is inlined.
51
-
52
- ### State model (in the client JS)
43
+ Keep editor state in the canonical shape from `editor/js/state.js`:
53
44
 
54
45
  ```js
55
46
  state = {
56
- theme: '', // active diagram theme key ('' = Default)
57
- zoom: 1, // current preview zoom level
58
- config: {}, // active RenderOptions overrides (from Config panel)
47
+ palette: 'paper',
48
+ style: 'crisp',
49
+ seed: 0,
50
+ zoom: 1,
51
+ config: {},
59
52
  }
60
-
61
- cfgColors = { bg, fg, accent, line, muted, surface } // color overrides
62
- cfgFont = '' // font name (bare, e.g. 'Inter')
63
- cfgPadding = 24 // padding px
64
- cfgEdgeStroke = 1 // edge line stroke width
65
- cfgNodeStroke = 1 // node border stroke width
66
- ```
67
-
68
- ### Render pipeline
69
-
70
- ```
71
- editor input
72
- → scheduleRender(debounce ms)
73
- → doRender()
74
- → buildOptions() // merges theme (base) + config (overrides)
75
- → renderMermaid(source, opts) // window.__mermaid.renderMermaidSVGAsync
76
- → previewInner.innerHTML = svg
77
- → applyStrokeOverrides(svgEl) // injects <style> for stroke widths
78
- → applyZoom(state.zoom) // sets SVG width/height from viewBox × zoom
79
- ```
80
-
81
- **Important**: `buildOptions()` layers options as `Object.assign(themeBase, state.config)` — config always wins over theme.
82
-
83
- ---
84
-
85
- ## How to add a Config option
86
-
87
- ### Case A: RenderOptions already supports it (colors, font, padding)
88
-
89
- 1. Add UI in the relevant `config-section` in the HTML template inside `scripts/site/editor.ts`
90
- 2. Add a JS state variable (e.g. `var cfgFoo = defaultVal`)
91
- 3. Update `readConfig()` to include it in `state.config`
92
- 4. Wire input events
93
- 5. Rebuild
94
-
95
- ### Case B: Post-process SVG (stroke widths, opacity, etc.)
96
-
97
- Use CSS injection via `applyStrokeOverrides` pattern — no renderer changes needed:
98
-
99
- ```js
100
- // After render:
101
- var style = document.createElementNS('http://www.w3.org/2000/svg', 'style');
102
- style.id = '__bm-my-override';
103
- style.textContent = 'rect { opacity: 0.8; }';
104
- svgEl.insertBefore(style, svgEl.firstChild);
105
53
  ```
106
54
 
107
- CSS rules override SVG presentation attributes (lower specificity). No `!important` needed.
108
-
109
- Call your override function in:
110
- - `doRender()` — after `previewInner.innerHTML = svg`
111
- - Any slider/input `change` handler directly (instant, no re-render)
55
+ - `palette` stores the registered palette input name.
56
+ - `style` stores the registered Look input name or `crisp`.
57
+ - `seed` affects styled ink without changing layout.
58
+ - `config` contains admitted serializable render options.
59
+ - Browser chrome dark/light mode is separate from diagram appearance and must not rewrite `state.palette`.
112
60
 
113
- ### Case C: Requires renderer support
61
+ When adding state, update serialization, sanitization, restoration, control hydration, and tests together.
114
62
 
115
- Add to `RenderOptions` in `src/types.ts`, normalize through `resolveDiagramColors` in `src/color-resolver.ts` when it affects the semantic palette, then expose it through `svgOpenTag`/`buildStyleBlock` in `src/theme.ts` when the live editor needs a CSS-variable override.
116
-
117
- ---
63
+ ## Render and verification boundary
118
64
 
119
- ## Adding a color field
120
-
121
- 1. Add to `cfgColors` object: `cfgColors.myColor = ''`
122
- 2. Add `THEME_COLOR_MAP` entry if the theme has a matching property
123
- 3. Add HTML in the Colors section:
124
- ```html
125
- <div class="color-field">
126
- <span class="color-field-label">My Color</span>
127
- <button class="color-edit-btn" data-cfg="myColor">
128
- <span class="cfg-hex-label" id="cfg-myColor-label">—</span>
129
- <span class="color-swatch" id="cfg-myColor-swatch"></span>
130
- </button>
131
- </div>
132
- ```
133
- 4. Update `readConfig()`: `if (cfgColors.myColor) cfg.myColor = cfgColors.myColor`
134
- 5. Ensure `refreshAllColorUIs()` covers it (it uses `Object.keys(cfgColors)` so automatic)
135
-
136
- ---
65
+ Follow the pipeline in `editor/js/rendering.js`:
137
66
 
138
- ## Adding a slider (Layout section)
139
-
140
- ```html
141
- <div class="padding-field">
142
- <div class="padding-row">
143
- <label>My Setting</label>
144
- <input class="padding-num" id="cfg-my-val" type="number" min="0" max="100" value="10" />
145
- </div>
146
- <input class="padding-slider" id="cfg-my-val-slider" type="range" min="0" max="100" value="10" />
147
- </div>
67
+ ```text
68
+ editor input
69
+ -> scheduleRender()
70
+ -> doRender()
71
+ -> buildOptions()
72
+ -> renderMermaidSVGWithReceipt()
73
+ -> verifyNoExternalRefs()
74
+ -> insertStrictRenderedSvg()
75
+ -> verifyMermaid()
76
+ -> retain the receipt-bearing artifact only when verification succeeds
148
77
  ```
149
78
 
150
- ```js
151
- var cfgMyVal = 10;
152
- var myNum = document.getElementById('cfg-my-val');
153
- var mySlider = document.getElementById('cfg-my-val-slider');
154
-
155
- function setMyVal(v) {
156
- v = Math.max(0, Math.min(100, parseFloat(v) || 10));
157
- cfgMyVal = v;
158
- myNum.value = v;
159
- mySlider.value = v;
160
- // apply effect...
161
- }
162
- myNum.addEventListener('input', function() { setMyVal(myNum.value); });
163
- mySlider.addEventListener('input', function() { setMyVal(mySlider.value); });
164
- ```
79
+ Keep `security: "strict"` and `embedFontImport: false` host-owned. Admit restored configuration through `SHARED_RENDER_OPTION_FIELDS` and `validateSerializableRenderOptions`; never trust hash or storage data directly. Insert one parsed SVG node with `replaceChildren`, not arbitrary shared HTML.
165
80
 
166
- ---
81
+ Do not enable share or export actions from stale DOM. Require the current source, receipt digests, verified artifact, and preview SVG to agree.
167
82
 
168
- ## Adding a sample preset
83
+ ## URL sharing contract
169
84
 
170
- Edit the `SAMPLES` array near the top of `scripts/site/editor.ts`:
85
+ Treat the URL payload as a versioned producer/consumer boundary. The canonical state is:
171
86
 
172
87
  ```ts
173
88
  {
174
- category: 'Flowchart', // must match an existing cat or add a new button
175
- title: 'My Sample',
176
- source: `graph TD\n A --> B`,
177
- },
178
- ```
179
-
180
- If adding a new category, the category button is generated automatically from unique categories in `SAMPLES`.
181
-
182
- ---
183
-
184
- ## Zoom system
185
-
186
- Zoom sets the SVG's **actual `width`/`height`** attributes (not CSS `transform: scale`), so the scroll container expands correctly.
187
-
188
- ```js
189
- function applyZoom(z) {
190
- state.zoom = clamp(z, 0.1, 8);
191
- var nat = getSvgNaturalSize(svgEl); // reads viewBox
192
- svgEl.style.width = nat.w * z + 'px';
193
- svgEl.style.height = nat.h * z + 'px';
89
+ source: string
90
+ palette?: string
91
+ style?: string
92
+ seed?: number
93
+ config?: Record<string, unknown>
194
94
  }
195
95
  ```
196
96
 
197
- Always call `applyZoom(state.zoom)` after inserting a new SVG. Zoom is preserved across re-renders.
198
-
199
- ---
200
-
201
- ## Theme ↔ dark mode sync
97
+ The hash codec is:
202
98
 
203
- ```
204
- applyColorMode(dark)
205
- → sets :root.light / removes it (editor UI)
206
- → if diagramThemeIsAuto: sets state.theme = 'zinc-dark' or ''
207
- → refreshAllColorUIs()
208
- → scheduleRender(0)
99
+ ```text
100
+ deflate:<base64url(deflate-raw(UTF-8(JSON(state))))>
209
101
  ```
210
102
 
211
- `diagramThemeIsAuto = false` once the user manually picks a theme from the dropdown — their choice is then preserved across dark/light toggles.
103
+ Use `editor/js/sharing.js` as the browser source of truth. For Node/build-time links, import `editorStateHref()` or `hostedEditorStateHref()` from `scripts/site/editor-state-url.ts`. Never hand-roll base64, compression, field names, or `/editor/` URL assembly in another producer.
212
104
 
213
- ---
105
+ Keep these behaviors:
214
106
 
215
- ## CSS variable system (diagram SVG)
107
+ - Reject unknown fields such as the removed `theme` alias.
108
+ - Bound encoded and decoded bytes.
109
+ - Fail closed on corrupt, unsupported, or oversized hashes.
110
+ - Do not restore a draft, query example, or plausible default after hash decode failure.
111
+ - Use `?example=<id>` only for canonical editor examples; use a state hash for source/config/style snapshots.
112
+ - Update the hash only after a current render verifies successfully.
216
113
 
217
- The renderer injects a `<style>` block into every SVG with derived vars:
218
-
219
- ```
220
- --bg, --fg → user-provided or defaults
221
- --line, --accent, --muted, --surface, --border → optional overrides
222
- --_line, --_arrow, --_node-fill, --_node-stroke → internal derived (color-mix)
223
- ```
114
+ When changing this contract, update the browser codec, build-time codec, every producer, checked-in deep links, and both unit and real-navigation tests in the same change.
224
115
 
225
- Config overrides work by setting `--bg`, `--fg` etc. on the SVG's inline `style` attribute via `svgOpenTag()`. Theme colors are the base; config values override them in `buildOptions()`.
116
+ ## Configuration controls
226
117
 
227
- ---
118
+ For an existing render option:
228
119
 
229
- ## URL sharing
120
+ 1. Add accessible controls in `editor/html/left-panel.html` or the relevant partial.
121
+ 2. Store UI state in `editor/js/config-panel.js`.
122
+ 3. Include the value in `readConfig()` and restore it in `hydrateConfigControls()`.
123
+ 4. Keep `state.config` serializable and admitted by the shared render-options schema.
124
+ 5. Render through `buildOptions()`; do not patch the preview into a state the renderer cannot reproduce.
230
125
 
231
- Source + theme are encoded in the URL hash:
126
+ For new public options, update the library contract first, then the editor. Do not create an editor-only alias.
232
127
 
233
- ```js
234
- // Encode
235
- btoa(unescape(encodeURIComponent(JSON.stringify({ source, theme }))))
128
+ ## Examples
236
129
 
237
- // Decode
238
- JSON.parse(decodeURIComponent(escape(atob(hash))))
239
- ```
130
+ Add or edit examples in `editor/examples.ts`. Preserve stable IDs because `/editor/?example=<id>`, the sidebar, website examples, and tests depend on them. Examples may supply source and admitted config; loading one must preserve the user-selected Palette unless the URL snapshot explicitly carries a palette.
240
131
 
241
- `updateHash()` is called after every successful render and on Copy URL.
132
+ ## Export behavior
242
133
 
243
- ---
134
+ Keep SVG, PNG, ASCII, and Unicode exports derived from current receipt-bearing artifacts. Preserve strict SVG verification and self-hosted font handling. PNG scale changes output dimensions; it must not change diagram semantics or silently fall back after an error.
244
135
 
245
- ## Export formats
136
+ ## Regression gates
246
137
 
247
- | Action | Implementation |
248
- |--------|----------------|
249
- | Save PNG | SVG → `<img>` → `<canvas>` → `toBlob('image/png')` → download |
250
- | Save SVG | `XMLSerializer.serializeToString(svgEl)` → Blob → download |
251
- | Copy Image | Same as PNG but `navigator.clipboard.write([new ClipboardItem(...)])` |
252
- | Copy URL | `updateHash()` then `navigator.clipboard.writeText(location.href)` |
138
+ Use these tests when touching editor links or state:
253
139
 
254
- Scale (1x/2x/4x) multiplies canvas dimensions for PNG export.
140
+ ```bash
141
+ bun test src/__tests__/editor-link-contract.test.ts
142
+ bun test src/__tests__/editor-security-closures.test.ts
143
+ bun test src/__tests__/website-build.test.ts
144
+ AM_BROWSER_TESTS=1 bun test src/__tests__/website-browser-a11y.test.ts --timeout 600000
145
+ ```
255
146
 
256
- ---
147
+ The repository-wide link contract must decode every checked-in hosted editor deep link. The website build contract must decode every generated HTML/JSON editor-state link and reject legacy hashes or unknown fields. The browser test must navigate from a real public page into the editor and verify that initialization preserves the hash and source.
257
148
 
258
149
  ## Common pitfalls
259
150
 
260
- - **Never edit `editor.html` directly** — it's overwritten on every build
261
- - **Avoid `\'` inside template literals** — use DOM API (`createElement`, `.textContent`) instead of `innerHTML` with quotes
262
- - **Stroke overrides via CSS injection must re-run after every render** — the SVG is replaced in `doRender()`
263
- - **`transform: scale()` breaks scrolling** — always use explicit `width`/`height` for zoom
264
- - **Font option is the bare name** (`Inter`, not `"Inter", sans-serif`) — the renderer wraps it internally
151
+ - Updating a decoder without migrating every producer.
152
+ - Updating unit fixtures to the new codec while leaving public links untouched.
153
+ - Reintroducing `theme` where the editor state contract requires `palette`.
154
+ - Testing the editor only with hashes manufactured inside the editor test suite.
155
+ - Editing generated outputs instead of modular sources.
156
+ - Letting dark/light chrome mutate diagram appearance.
157
+ - Restoring drafts after a broken share URL, which can make unrelated local content look shared.
158
+ - Enabling copy/export from a stale or unverified preview.