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.
- package/AGENT_NATIVE.md +155 -91
- package/CHANGELOG.md +163 -4
- package/Instructions_for_agents.md +10 -10
- package/LICENSES/Apache-2.0.txt +202 -0
- package/README.md +31 -38
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/assets/hero.png +0 -0
- package/dist/agent-core.d.ts +463 -0
- package/dist/agent-core.js +397 -0
- package/dist/agent.d.ts +73 -1868
- package/dist/agent.js +336 -37325
- package/dist/agentic-mermaid-mcp.js +7 -38399
- package/dist/am.js +33626 -40446
- package/dist/chunk-2P5FKUQC.js +3485 -0
- package/dist/chunk-2S3VSS6I.js +149 -0
- package/dist/chunk-2SILJDW2.js +37 -0
- package/dist/chunk-BJYMBT4I.js +61963 -0
- package/dist/chunk-FDM43XU7.js +615 -0
- package/dist/chunk-MYPDVZCO.js +4702 -0
- package/dist/index-DWPa2MJs.d.ts +6780 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +310 -33014
- package/dist/mcp-cli-5J47WEY3.js +17 -0
- package/docs/README.md +39 -31
- package/docs/agent-api-cookbook.md +44 -35
- package/docs/agent-mutation-policy.md +1 -1
- package/docs/agent-workflow-examples.md +2 -2
- package/docs/api.md +284 -77
- package/docs/ascii.md +26 -16
- package/docs/code-mode-impact.md +214 -0
- package/docs/comparison.md +23 -11
- package/docs/computational-aesthetics-prototype-plan.md +252 -0
- package/docs/config.md +26 -10
- package/docs/custom-fonts.md +265 -0
- package/docs/custom-style-cookbook.md +130 -9
- package/docs/diagram-families.md +48 -23
- package/docs/features.md +59 -52
- package/docs/fork-differences.md +6 -3
- package/docs/getting-started.md +23 -16
- package/docs/issue-derived-test-cases.md +29 -22
- package/docs/mcp-code-mode-rationale.md +13 -6
- package/docs/mcp-http-transport.md +20 -13
- package/docs/mermaid-layout-complaints.md +66 -52
- package/docs/mutation-testing.md +145 -66
- package/docs/quality.md +23 -14
- package/docs/react.md +2 -2
- package/docs/schemas/style-spec.schema.json +1221 -30
- package/docs/style-authoring.md +241 -38
- package/docs/svg-semantic-contract.md +49 -0
- package/docs/testing-strategy.md +166 -58
- package/docs/theming.md +19 -32
- package/examples/styles/catalog.json +54 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
- package/examples/styles/cupertino-prototype.mmd +10 -0
- package/examples/styles/cupertino-prototype.style.json +63 -0
- package/examples/styles/mid-century-report.style.json +2 -2
- package/examples/styles/star-chart-atlas.style.json +2 -1
- package/examples/styles/transit-route-map.style.json +2 -2
- package/examples/styles/vercel-inspired-prototype.mmd +6 -0
- package/examples/styles/vercel-inspired-prototype.style.json +87 -0
- package/package.json +85 -45
- package/server.json +2 -2
- package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
- package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
- package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
- package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
- package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
- package/TODO.md +0 -684
- package/dist/index-wjRjbsP-.d.ts +0 -1102
- package/docs/assets/improvements/box-start-connector.png +0 -0
- package/docs/assets/improvements/comment-dropped-lint.png +0 -0
- package/docs/assets/improvements/er-content-loss.png +0 -0
- package/docs/assets/improvements/fan-in-trunks.png +0 -0
- package/docs/assets/improvements/gantt-family.png +0 -0
- package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
- package/docs/assets/improvements/gantt-verify-seam.png +0 -0
- package/docs/assets/improvements/subgraph-container-edges.png +0 -0
- package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
- package/docs/assets/improvements/wrapper-init-directive.png +0 -0
- package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
- package/docs/assets/style-cookbook/mid-century-report.png +0 -0
- package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
- package/docs/assets/style-cookbook/transit-route-map.png +0 -0
- package/docs/contributing/adding-diagram-types.md +0 -144
- package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
- package/docs/contributing/diagram-family-citizenship.md +0 -82
- package/docs/contributing/harvesting-upstream-tests.md +0 -126
- package/docs/contributing/lessons-learned.md +0 -276
- package/docs/contributing/releasing.md +0 -82
- package/docs/contributing/visual-review-evidence.md +0 -53
- package/docs/design/families/README.md +0 -26
- package/docs/design/families/architecture-beta.md +0 -48
- package/docs/design/families/flowchart-parser-conformance.md +0 -22
- package/docs/design/families/gantt-research.md +0 -137
- package/docs/design/families/gantt.md +0 -329
- package/docs/design/families/journey-agentic-cards-before.png +0 -0
- package/docs/design/families/journey-experience-curve-implementation.png +0 -0
- package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
- package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
- package/docs/design/families/journey-migration-parity.md +0 -439
- package/docs/design/families/journey-section-overlap-after.png +0 -0
- package/docs/design/families/journey-section-overlap-before.png +0 -0
- package/docs/design/families/journey-usage-research.md +0 -423
- package/docs/design/families/journey.md +0 -153
- package/docs/design/families/xychart.md +0 -85
- package/docs/design/system/README.md +0 -45
- package/docs/design/system/abstraction-audit.md +0 -224
- package/docs/design/system/abstraction-recommendations.md +0 -655
- package/docs/design/system/architecture.mmd +0 -29
- package/docs/design/system/architecture.svg +0 -137
- package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
- package/docs/design/system/layout-rubric.md +0 -138
- package/docs/design/system/route-contracts.md +0 -848
- package/docs/design/system/source-preservation-ladder.md +0 -52
- package/docs/design/system/styles-rollout.md +0 -216
- package/docs/design/system/ugly-layouts.md +0 -119
- package/docs/layout-characterization/README.md +0 -245
- package/docs/layout-characterization/contact-sheet-families.md +0 -498
- package/docs/layout-characterization/contact-sheet.md +0 -638
- package/docs/layout-characterization/properties.md +0 -281
- package/docs/layout-characterization/visual-quality.md +0 -160
- package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
- package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
- package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
- package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
- package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/journey.svg +0 -98
- package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
- package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
- package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
- package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
- package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
- package/docs/project/divergences.md +0 -98
- package/docs/project/dogfooding-docs-strategy.md +0 -66
- package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
- package/docs/project/lessons-learned.md +0 -1019
- package/docs/project/remove-role-styling-plan.md +0 -176
- package/examples/agent-improve-auth-flow.ts +0 -206
- package/examples/agent-loop.ts +0 -53
- package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
- package/llms.txt +0 -104
- package/skill-evals/README.md +0 -77
- package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
- package/skill-evals/fixtures/class-payment/input.mmd +0 -4
- package/skill-evals/fixtures/er-orders/input.mmd +0 -10
- package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
- package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
- package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
- package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
- package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
- package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
- package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
- package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
- package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
- package/skill-evals/shared-benchmark.json +0 -510
- package/src/agent/analyze.ts +0 -157
- package/src/agent/apply.ts +0 -146
- package/src/agent/architecture-body.ts +0 -458
- package/src/agent/certificates.ts +0 -110
- package/src/agent/class-body.ts +0 -319
- package/src/agent/core.ts +0 -207
- package/src/agent/create.ts +0 -106
- package/src/agent/describe.ts +0 -368
- package/src/agent/er-body.ts +0 -224
- package/src/agent/facts.ts +0 -360
- package/src/agent/families-builtin.ts +0 -920
- package/src/agent/families.ts +0 -232
- package/src/agent/family-layouts.ts +0 -832
- package/src/agent/flowchart-body.ts +0 -372
- package/src/agent/flowchart-unsupported.ts +0 -243
- package/src/agent/font-coverage.ts +0 -288
- package/src/agent/gantt-body.ts +0 -495
- package/src/agent/index.ts +0 -10
- package/src/agent/journey-body.ts +0 -374
- package/src/agent/label-metrics.ts +0 -28
- package/src/agent/layout-to-rendered.ts +0 -63
- package/src/agent/mutate.ts +0 -97
- package/src/agent/mutation-ops.ts +0 -51
- package/src/agent/op-schema.ts +0 -443
- package/src/agent/parse.ts +0 -223
- package/src/agent/pie-body.ts +0 -270
- package/src/agent/png.ts +0 -171
- package/src/agent/quadrant-body.ts +0 -336
- package/src/agent/quality.ts +0 -363
- package/src/agent/readability-audit.ts +0 -92
- package/src/agent/rendered-route-audit.ts +0 -61
- package/src/agent/sequence-body.ts +0 -345
- package/src/agent/serialize.ts +0 -214
- package/src/agent/state-body.ts +0 -589
- package/src/agent/structural-count.ts +0 -150
- package/src/agent/timeline-body.ts +0 -280
- package/src/agent/trace-log.ts +0 -43
- package/src/agent/types.ts +0 -995
- package/src/agent/verify.ts +0 -603
- package/src/agent/xychart-body.ts +0 -472
- package/src/architecture/config.ts +0 -282
- package/src/architecture/layout.ts +0 -496
- package/src/architecture/parser.ts +0 -375
- package/src/architecture/renderer.ts +0 -611
- package/src/architecture/types.ts +0 -113
- package/src/ascii/ansi.ts +0 -423
- package/src/ascii/architecture.ts +0 -210
- package/src/ascii/canvas.ts +0 -443
- package/src/ascii/class-diagram.ts +0 -697
- package/src/ascii/converter.ts +0 -475
- package/src/ascii/draw.ts +0 -1693
- package/src/ascii/edge-bundling.ts +0 -328
- package/src/ascii/edge-routing.ts +0 -330
- package/src/ascii/er-diagram.ts +0 -439
- package/src/ascii/gantt.ts +0 -276
- package/src/ascii/grid.ts +0 -747
- package/src/ascii/index.ts +0 -196
- package/src/ascii/journey.ts +0 -169
- package/src/ascii/meta.ts +0 -244
- package/src/ascii/multiline-utils.ts +0 -80
- package/src/ascii/pathfinder.ts +0 -301
- package/src/ascii/pie.ts +0 -67
- package/src/ascii/quadrant.ts +0 -158
- package/src/ascii/reverse.ts +0 -216
- package/src/ascii/sequence.ts +0 -499
- package/src/ascii/shapes/circle.ts +0 -27
- package/src/ascii/shapes/corners.ts +0 -143
- package/src/ascii/shapes/diamond.ts +0 -27
- package/src/ascii/shapes/hexagon.ts +0 -27
- package/src/ascii/shapes/index.ts +0 -106
- package/src/ascii/shapes/rectangle.ts +0 -168
- package/src/ascii/shapes/rounded.ts +0 -27
- package/src/ascii/shapes/special.ts +0 -332
- package/src/ascii/shapes/stadium.ts +0 -110
- package/src/ascii/shapes/state.ts +0 -192
- package/src/ascii/shapes/types.ts +0 -73
- package/src/ascii/timeline.ts +0 -141
- package/src/ascii/types.ts +0 -312
- package/src/ascii/validate.ts +0 -120
- package/src/ascii/width.ts +0 -81
- package/src/ascii/wrap.ts +0 -131
- package/src/ascii/xychart.ts +0 -919
- package/src/browser.ts +0 -29
- package/src/class/layout.ts +0 -240
- package/src/class/parser.ts +0 -332
- package/src/class/renderer.ts +0 -638
- package/src/class/types.ts +0 -129
- package/src/cli/agent-instructions.ts +0 -1
- package/src/cli/am-bin.ts +0 -6
- package/src/cli/exit-codes.ts +0 -18
- package/src/cli/index.ts +0 -1132
- package/src/cli/init-agent.ts +0 -147
- package/src/cli/run-entrypoint.ts +0 -10
- package/src/color-resolver.ts +0 -152
- package/src/elk-instance.ts +0 -114
- package/src/er/layout.ts +0 -187
- package/src/er/parser.ts +0 -226
- package/src/er/renderer.ts +0 -792
- package/src/er/types.ts +0 -99
- package/src/family-rubric.ts +0 -425
- package/src/font-manifest.ts +0 -31
- package/src/gantt/layout.ts +0 -365
- package/src/gantt/parser.ts +0 -282
- package/src/gantt/pipeline.ts +0 -27
- package/src/gantt/renderer.ts +0 -414
- package/src/gantt/schedule.ts +0 -513
- package/src/gantt/types.ts +0 -255
- package/src/index.ts +0 -368
- package/src/journey/layout.ts +0 -554
- package/src/journey/parse-core.ts +0 -251
- package/src/journey/parser.ts +0 -101
- package/src/journey/renderer.ts +0 -917
- package/src/journey/types.ts +0 -144
- package/src/layout/geometry.ts +0 -182
- package/src/layout/pass.ts +0 -142
- package/src/layout/passes/index.ts +0 -3916
- package/src/layout-engine.ts +0 -1565
- package/src/layout-rubric.ts +0 -659
- package/src/mcp/artifacts.ts +0 -137
- package/src/mcp/dynamic-harness.ts +0 -31
- package/src/mcp/dynamic-modules.d.ts +0 -7
- package/src/mcp/facade.ts +0 -608
- package/src/mcp/harness-runtime.ts +0 -203
- package/src/mcp/hosted-server.ts +0 -468
- package/src/mcp/mcp-bin.ts +0 -3
- package/src/mcp/mcp-cli.ts +0 -82
- package/src/mcp/protocol.ts +0 -13
- package/src/mcp/sandbox.ts +0 -195
- package/src/mcp/sdk-decl.ts +0 -391
- package/src/mcp/server.ts +0 -362
- package/src/mcp/tool-surface.ts +0 -146
- package/src/mermaid-source.ts +0 -655
- package/src/multiline-utils.ts +0 -228
- package/src/parser.ts +0 -1031
- package/src/pie/layout.ts +0 -168
- package/src/pie/parser.ts +0 -136
- package/src/pie/renderer.ts +0 -234
- package/src/pie/types.ts +0 -82
- package/src/quadrant/layout.ts +0 -191
- package/src/quadrant/parser.ts +0 -183
- package/src/quadrant/renderer.ts +0 -322
- package/src/quadrant/types.ts +0 -113
- package/src/render-family-hooks.ts +0 -244
- package/src/renderer.ts +0 -1099
- package/src/route-contracts.ts +0 -2723
- package/src/scene/backend.ts +0 -76
- package/src/scene/fidelity.ts +0 -183
- package/src/scene/hybrid-backend.ts +0 -174
- package/src/scene/ir.ts +0 -181
- package/src/scene/marks.ts +0 -127
- package/src/scene/rough-backend.ts +0 -378
- package/src/scene/seed.ts +0 -46
- package/src/scene/style-registry.ts +0 -556
- package/src/sequence/layout.ts +0 -456
- package/src/sequence/parser.ts +0 -255
- package/src/sequence/renderer.ts +0 -604
- package/src/sequence/types.ts +0 -154
- package/src/shape-clipping.ts +0 -351
- package/src/shared/accessibility-directives.ts +0 -22
- package/src/shared/batched.ts +0 -61
- package/src/shared/color-math.ts +0 -93
- package/src/shared/svg-a11y.ts +0 -29
- package/src/shared/syntax-error.ts +0 -17
- package/src/shared/unicode-ranges.ts +0 -135
- package/src/styles.ts +0 -318
- package/src/svg-paths.ts +0 -28
- package/src/text-metrics.ts +0 -248
- package/src/theme.ts +0 -710
- package/src/timeline/layout.ts +0 -381
- package/src/timeline/parser.ts +0 -215
- package/src/timeline/renderer.ts +0 -538
- package/src/timeline/types.ts +0 -105
- package/src/types.ts +0 -462
- package/src/website-worker-modules.d.ts +0 -18
- package/src/xychart/axis-utils.ts +0 -109
- package/src/xychart/colors.ts +0 -124
- package/src/xychart/config.ts +0 -88
- package/src/xychart/layout.ts +0 -656
- package/src/xychart/parser.ts +0 -504
- package/src/xychart/renderer.ts +0 -640
- 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
|
|
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.
|
|
16
|
-
mermaid.asFlowchart(d): FlowchartValidDiagram | null
|
|
17
|
-
mermaid.
|
|
18
|
-
|
|
19
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
ride along VERBATIM as opaque-block segments
|
|
25
|
-
|
|
26
|
-
`
|
|
27
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
9
|
+
# Agentic Mermaid live editor development
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
Edit the modular editor sources and preserve the contracts shared by the standalone editor and the deployed website.
|
|
13
12
|
|
|
14
|
-
##
|
|
13
|
+
## Source map
|
|
15
14
|
|
|
16
|
-
|
|
|
17
|
-
|
|
18
|
-
| `
|
|
19
|
-
| `editor
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `scripts/site/
|
|
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
|
-
|
|
26
|
+
Do not edit generated `editor.html` or `website/public/` files directly.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
|
36
|
-
bun run website
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
- `
|
|
111
|
-
-
|
|
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
|
-
|
|
61
|
+
When adding state, update serialization, sanitization, restoration, control hydration, and tests together.
|
|
114
62
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
---
|
|
63
|
+
## Render and verification boundary
|
|
118
64
|
|
|
119
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
83
|
+
## URL sharing contract
|
|
169
84
|
|
|
170
|
-
|
|
85
|
+
Treat the URL payload as a versioned producer/consumer boundary. The canonical state is:
|
|
171
86
|
|
|
172
87
|
```ts
|
|
173
88
|
{
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## Theme ↔ dark mode sync
|
|
97
|
+
The hash codec is:
|
|
202
98
|
|
|
203
|
-
```
|
|
204
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
116
|
+
## Configuration controls
|
|
226
117
|
|
|
227
|
-
|
|
118
|
+
For an existing render option:
|
|
228
119
|
|
|
229
|
-
|
|
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
|
-
|
|
126
|
+
For new public options, update the library contract first, then the editor. Do not create an editor-only alias.
|
|
232
127
|
|
|
233
|
-
|
|
234
|
-
// Encode
|
|
235
|
-
btoa(unescape(encodeURIComponent(JSON.stringify({ source, theme }))))
|
|
128
|
+
## Examples
|
|
236
129
|
|
|
237
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
136
|
+
## Regression gates
|
|
246
137
|
|
|
247
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
-
|
|
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.
|