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
@@ -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 # clean in-memory website + Worker artifact contracts
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.