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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Code Mode in Agentic Mermaid: impact, comparison, and costs
|
|
2
|
+
|
|
3
|
+
Agentic Mermaid uses Code Mode to keep a diagram edit inside one execution:
|
|
4
|
+
parse the source, narrow it to a mutable family, apply typed operations, verify
|
|
5
|
+
the result, and serialize only after verification passes. This changes both
|
|
6
|
+
the model-facing boundary and the execution boundary. The model writes a small
|
|
7
|
+
algorithm instead of relaying each intermediate diagram through another tool
|
|
8
|
+
call, while the server retains the trusted diagram lineage needed to reject
|
|
9
|
+
forged or invalid edits.
|
|
10
|
+
|
|
11
|
+
This document uses **local Code Mode** for the self-hosted MCP process running
|
|
12
|
+
on the agent's machine and **hosted Code Mode** for the public
|
|
13
|
+
`https://agentic-mermaid.dev/mcp` endpoint. Cloudflare calls the same split
|
|
14
|
+
client-side and server-side Code Mode. The names describe where the sandbox
|
|
15
|
+
runs, not where the model runs.
|
|
16
|
+
|
|
17
|
+
## Local Code Mode
|
|
18
|
+
|
|
19
|
+
The local `agentic-mermaid-mcp` exposes `execute(code)`, which runs synchronous
|
|
20
|
+
JavaScript against the typed `mermaid.*` SDK in a hardened `node:vm` context.
|
|
21
|
+
The execution can retain parsed diagrams between SDK calls, so the model does
|
|
22
|
+
not have to copy an intermediate representation into another JSON request.
|
|
23
|
+
That matters because Agentic Mermaid's mutation checks depend on provenance:
|
|
24
|
+
SDK results are read-only, and structured changes must pass through
|
|
25
|
+
`mermaid.mutate`.
|
|
26
|
+
|
|
27
|
+
Running beside the agent also keeps diagram source local and avoids hosted
|
|
28
|
+
compute charges. The local server can return managed PNG files or URLs through
|
|
29
|
+
its direct `render_png` helper, while multi-step editing remains in `execute`.
|
|
30
|
+
The [MCP Code Mode rationale](./mcp-code-mode-rationale.md) explains why those
|
|
31
|
+
helpers stay narrow rather than recreating the full SDK as individual tools.
|
|
32
|
+
|
|
33
|
+
Progressive SDK discovery removed the largest client-side cost. The initial
|
|
34
|
+
`execute` declaration now contains the core SDK, while
|
|
35
|
+
`describe_sdk({ family, detail })` returns the mutation schema for one diagram
|
|
36
|
+
family. An agent that already knows an operation can skip discovery; an agent
|
|
37
|
+
handling an unfamiliar family can request compact signatures or exact fields.
|
|
38
|
+
|
|
39
|
+
## Hosted Code Mode
|
|
40
|
+
|
|
41
|
+
The hosted endpoint puts the sandbox behind the MCP server, so an ordinary MCP
|
|
42
|
+
client gets Code Mode without shipping its own execution environment. Each
|
|
43
|
+
hosted `execute` runs in a Cloudflare Dynamic Worker configured with an empty
|
|
44
|
+
environment, `globalOutbound: null`, no subrequests, and a bounded CPU budget.
|
|
45
|
+
The isolate configuration is the security boundary. The hardened SDK facade is
|
|
46
|
+
kept for behavioural parity with the local server.
|
|
47
|
+
|
|
48
|
+
Hosted execution has a per-call cost, so common pure operations do not enter
|
|
49
|
+
the sandbox. `render_svg`, `render_ascii`, `render_png`, `verify`, `describe`,
|
|
50
|
+
and `describe_sdk` run as ordinary Worker calls whose successful deterministic
|
|
51
|
+
results can be reused by the private server-side Workers Cache. The JSON-RPC
|
|
52
|
+
HTTP responses remain `cache-control: no-store`.
|
|
53
|
+
Declarative `mutate` and `build` apply typed operation lists through the same
|
|
54
|
+
mutation core and verify before returning source. They give smaller models a
|
|
55
|
+
direct path for routine edits while reserving `execute` for control flow that
|
|
56
|
+
the operation list cannot express.
|
|
57
|
+
|
|
58
|
+
Local and hosted Code Mode share the same `mermaid.*` facade. Differential
|
|
59
|
+
tests compare result envelopes, errors, trace behaviour, read-only enforcement,
|
|
60
|
+
and serialization across both runtimes. The
|
|
61
|
+
[hosted MCP as-built record](./project/archive/hosted-mcp-cloudflare-plan.md) documents
|
|
62
|
+
the remaining runtime differences and abuse controls.
|
|
63
|
+
|
|
64
|
+
## Measured effect
|
|
65
|
+
|
|
66
|
+
[PR #157](https://github.com/adewale/agentic-mermaid/pull/157) measured the
|
|
67
|
+
serialized declarations and tool lists with `o200k_base`. These counts are a
|
|
68
|
+
stable before-and-after proxy, not a provider billing claim.
|
|
69
|
+
|
|
70
|
+
| Model-facing surface | Before | After | Tokens saved |
|
|
71
|
+
|---|---:|---:|---:|
|
|
72
|
+
| `execute` SDK declaration | 10,527 | 903 | 9,624 (91.4%) |
|
|
73
|
+
| Local `tools/list` | 11,781 | 1,840 | 9,941 (84.4%) |
|
|
74
|
+
| Hosted `tools/list` | 15,646 | 2,969 | 12,677 (81.0%) |
|
|
75
|
+
|
|
76
|
+
The median complete family schema is 495 tokens. A hosted client that loads the
|
|
77
|
+
initial tool list and then requests that schema consumes 3,464 tokens, 77.9%
|
|
78
|
+
less than the old hosted list. The largest family, flowchart, brings the total
|
|
79
|
+
to 4,928 tokens, which is still 68.5% lower. Compact signature responses have a
|
|
80
|
+
113-token median.
|
|
81
|
+
|
|
82
|
+
The same PR ran four schema-sensitive edits against the exact before and after
|
|
83
|
+
hosted tool lists. Each proposed mutation was replayed through the real
|
|
84
|
+
`applyOps` implementation and checked against semantic facts.
|
|
85
|
+
|
|
86
|
+
| Model | Before task-correct | After task-correct | After discovery |
|
|
87
|
+
|---|---:|---:|---:|
|
|
88
|
+
| `gpt-5.4-mini` | 3/4 | 4/4 | 4/4 |
|
|
89
|
+
| `gpt-5.3-codex-spark` | 4/4 | 4/4 | 4/4 |
|
|
90
|
+
| **Combined** | **7/8** | **8/8** | **8/8** |
|
|
91
|
+
|
|
92
|
+
All 16 mutations across both conditions applied successfully. The one incorrect
|
|
93
|
+
before-case omitted a requested Architecture edge label; the after-case kept
|
|
94
|
+
it. The combined four-case prompt fell from 16,048 to 5,833 tokens, a 63.7%
|
|
95
|
+
reduction even though the test prompt included all four family responses at
|
|
96
|
+
once. A normal request discloses one family.
|
|
97
|
+
|
|
98
|
+
This eval is evidence for the discovery change, not a broad model-quality
|
|
99
|
+
claim. It covers four tasks and two small models. Larger task sets, more model
|
|
100
|
+
families, and production latency measurements remain separate work.
|
|
101
|
+
|
|
102
|
+
## Comparison with Cloudflare and Anthropic
|
|
103
|
+
|
|
104
|
+
Agentic Mermaid applies Code Mode to a pure diagram library. Cloudflare and
|
|
105
|
+
Anthropic apply the same technique to general tool catalogs, where generated
|
|
106
|
+
code may call remote services and carry data between them. That scope
|
|
107
|
+
difference explains most of the implementation differences.
|
|
108
|
+
|
|
109
|
+
| Dimension | Agentic Mermaid | Cloudflare | Anthropic |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| Primary scope | One deterministic diagram SDK | MCP tools and large APIs | General tool catalogs |
|
|
112
|
+
| Discovery | `describe_sdk` for one diagram family | Typed connectors, or `search` over an OpenAPI document | Tool Search, or filesystem-shaped tool definitions |
|
|
113
|
+
| Model-written code | Synchronous JavaScript | Asynchronous JavaScript | Python in Programmatic Tool Calling |
|
|
114
|
+
| Execution | Local `node:vm` or hosted Dynamic Worker | Dynamic Worker isolate | Anthropic Code Execution sandbox |
|
|
115
|
+
| Calls made from code | Pure in-process SDK calls | MCP calls or an authenticated request callback | Developer-provided tools |
|
|
116
|
+
| External effects | None beyond returned diagram artifacts | Allowed through host-controlled bindings and authorization | Allowed for tools that opt into programmatic calling |
|
|
117
|
+
| Persistent state | None | Durable runtime options are available | Filesystem state and reusable skills are possible |
|
|
118
|
+
|
|
119
|
+
### Cloudflare
|
|
120
|
+
|
|
121
|
+
Cloudflare's first Code Mode implementation converted connected MCP tools into
|
|
122
|
+
a TypeScript API and ran the model's JavaScript in a Dynamic Worker. Its current
|
|
123
|
+
MCP patterns cover both a single `code` tool, where the complete generated API
|
|
124
|
+
fits in the tool description, and `search` plus `execute`, where a large
|
|
125
|
+
OpenAPI document stays inside the discovery sandbox. Authentication remains in
|
|
126
|
+
the host callback rather than entering generated code.
|
|
127
|
+
|
|
128
|
+
That general implementation supports asynchronous calls, remote APIs,
|
|
129
|
+
authorization and, in the durable runtime, pause-and-resume approval. Agentic
|
|
130
|
+
Mermaid does not need those facilities because its SDK calls are synchronous,
|
|
131
|
+
pure, and confined to one diagram transaction. It does use the same Dynamic
|
|
132
|
+
Worker substrate for hosted isolation, but it does not depend on
|
|
133
|
+
`@cloudflare/codemode`.
|
|
134
|
+
|
|
135
|
+
Cloudflare measured its server-side `search` and `execute` surface at roughly
|
|
136
|
+
1,000 tokens for more than 2,500 API endpoints, 99.9% fewer than direct MCP
|
|
137
|
+
definitions. Agentic Mermaid's percentage is not directly comparable because
|
|
138
|
+
its catalog is smaller and its hosted tool list retains more direct helpers.
|
|
139
|
+
|
|
140
|
+
Sources: [original Code Mode design](https://blog.cloudflare.com/code-mode/),
|
|
141
|
+
[server-side API implementation](https://blog.cloudflare.com/code-mode-mcp/),
|
|
142
|
+
and [current MCP server patterns](https://developers.cloudflare.com/agents/model-context-protocol/codemode/).
|
|
143
|
+
|
|
144
|
+
### Anthropic
|
|
145
|
+
|
|
146
|
+
Anthropic's November 2025 architecture generated a filesystem-like tree of MCP
|
|
147
|
+
tool definitions so an agent could inspect only the files it needed. It also
|
|
148
|
+
proposed a `search_tools` alternative with selectable detail levels. The code
|
|
149
|
+
execution environment could filter large results, retain intermediate state,
|
|
150
|
+
and pass data between tools without putting that data into the model context.
|
|
151
|
+
|
|
152
|
+
Anthropic later shipped the mechanism as Tool Search and Programmatic Tool
|
|
153
|
+
Calling. Deferred tools stay out of the initial prompt, while Python running in
|
|
154
|
+
the Code Execution sandbox can pause for an allowed tool, process the result,
|
|
155
|
+
and continue without sending that result through another model inference.
|
|
156
|
+
Anthropic reported an 85% token reduction for Tool Search in a large catalog,
|
|
157
|
+
along with accuracy gains on its MCP evaluations.
|
|
158
|
+
|
|
159
|
+
Agentic Mermaid's `describe_sdk` follows the same progressive-disclosure
|
|
160
|
+
principle but uses a family key instead of general search. Its execution model
|
|
161
|
+
is intentionally smaller: no filesystem, no persistence, no arbitrary tool
|
|
162
|
+
catalog, and no asynchronous callback loop.
|
|
163
|
+
|
|
164
|
+
Sources: [Code execution with MCP](https://www.anthropic.com/engineering/code-execution-with-mcp)
|
|
165
|
+
and [advanced tool use](https://www.anthropic.com/engineering/advanced-tool-use).
|
|
166
|
+
|
|
167
|
+
## Costs and limits
|
|
168
|
+
|
|
169
|
+
Progressive discovery moves schema tokens out of the initial prompt, but an
|
|
170
|
+
unfamiliar edit now needs a `describe_sdk` call before `mutate`, `build`, or
|
|
171
|
+
`execute`. That extra round trip is wasted on a small catalog whose definitions
|
|
172
|
+
are used in every session. It pays off here because most diagram tasks use one
|
|
173
|
+
registered family, and the old declarations devoted 93.1% of the hosted tool-list
|
|
174
|
+
tokens to the full SDK and repeated mutation menus.
|
|
175
|
+
|
|
176
|
+
Code execution also adds work that a direct tool does not need. A one-shot
|
|
177
|
+
render, verification, or straightforward operation list should use the hosted
|
|
178
|
+
direct tools. Models, especially smaller ones, can make JavaScript mistakes or
|
|
179
|
+
violate the SDK's provenance and serialization rules; `mutate` and `build`
|
|
180
|
+
exist because those failures were observed in practice.
|
|
181
|
+
|
|
182
|
+
The local and hosted sandboxes have deliberate constraints:
|
|
183
|
+
|
|
184
|
+
- Code Mode is synchronous. It rejects `async`/`await`, Promise jobs, dynamic
|
|
185
|
+
imports, finalizers, and queued microtasks.
|
|
186
|
+
- Sandbox code has no filesystem, external network, environment variables, or
|
|
187
|
+
persistent workspace.
|
|
188
|
+
- Local `node:vm` is hardened but is not an operating-system or container
|
|
189
|
+
security boundary. It is a local tool for trusted use.
|
|
190
|
+
- Hosted execution contacts a billable Dynamic Worker on every call. Worker
|
|
191
|
+
Loader IDs are content-addressed so identical code can reuse a warm isolate,
|
|
192
|
+
while direct tools and their private compute cache keep routine work off that
|
|
193
|
+
path.
|
|
194
|
+
- Hosted `execute` responses are never compute-cached: Code Mode exposes time
|
|
195
|
+
and randomness, so retaining the first result would violate its observable
|
|
196
|
+
contract.
|
|
197
|
+
- Local timeouts use wall-clock time, while hosted limits use CPU time. Warm
|
|
198
|
+
hosted isolates can retain module globals, hosted output is capped, and
|
|
199
|
+
hosted PNG bytes are not part of the cross-runtime byte-determinism contract.
|
|
200
|
+
|
|
201
|
+
Keeping intermediate results outside model context is useful only when code
|
|
202
|
+
can decide what to discard. If the model must inspect each intermediate result
|
|
203
|
+
to make a semantic judgment, direct calls may be more appropriate. Anthropic
|
|
204
|
+
makes the same distinction for simple lookups and tasks where Claude should see
|
|
205
|
+
all intermediate data.
|
|
206
|
+
|
|
207
|
+
## Decision
|
|
208
|
+
|
|
209
|
+
Because Agentic Mermaid's useful unit of work is a verified diagram
|
|
210
|
+
transaction rather than a general agent computer, its Code Mode surface can
|
|
211
|
+
stay narrow. The model receives the core SDK, requests one family schema when
|
|
212
|
+
needed, and returns reviewable Mermaid source only after the same verifier used
|
|
213
|
+
by the library and CLI has accepted it. That verified source is the outcome by
|
|
214
|
+
which the extra sandbox and discovery call should be judged.
|
package/docs/comparison.md
CHANGED
|
@@ -19,11 +19,11 @@ one does, and the final section tells you which to install for common jobs.
|
|
|
19
19
|
- **Agentic Mermaid** (`agentic-mermaid`, this repo) extends Beautiful
|
|
20
20
|
Mermaid for programs that edit diagrams — AI agents foremost. It adds a
|
|
21
21
|
typed parse → mutate → verify → serialize loop, byte-identical output
|
|
22
|
-
across runs, structured verification, and CLI/MCP surfaces. The trade is
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
across runs, structured verification, and CLI/MCP surfaces. The trade is explicit: the checked registry covers a focused subset of Mermaid's
|
|
23
|
+
broader catalogue in exchange for the guarantee that parsing and re-serializing
|
|
24
|
+
a diagram never drops syntax.
|
|
25
25
|
|
|
26
|
-
Facts below reflect Mermaid
|
|
26
|
+
Facts below reflect Mermaid 11.16.0 and the upstream `beautiful-mermaid`
|
|
27
27
|
repository as of mid-2026; both projects move quickly, so check their
|
|
28
28
|
changelogs for the current state.
|
|
29
29
|
|
|
@@ -33,16 +33,16 @@ changelogs for the current state.
|
|
|
33
33
|
|---|---|---|---|
|
|
34
34
|
| Primary job | Define and render the diagram language everywhere | Fast, beautiful, browserless rendering | Agent-safe diagram *editing* plus rendering |
|
|
35
35
|
| Runtime | Browser DOM (Node via Puppeteer/`mermaid-cli`) | Pure TypeScript, zero DOM, synchronous | Pure TypeScript, zero DOM, synchronous |
|
|
36
|
-
| Diagram types |
|
|
36
|
+
| Diagram types | Broad Mermaid catalogue, including newer experimental families | Flowchart, state, sequence, class, ER, and XY chart | Registry-backed subset listed by `am capabilities --json` |
|
|
37
37
|
| Output formats | SVG (PNG/PDF via CLI tooling) | SVG, ASCII/Unicode | SVG, PNG (offline resvg), ASCII/Unicode, JSON layout |
|
|
38
38
|
| Theming | Theme config + CSS | Two-color foundation, 15+ named themes, Shiki/VS Code compatibility, live CSS-variable switching | Style + Palette stacks: named looks, palette-only styles, custom JSON records, and deterministic seeds |
|
|
39
|
-
| Parse to a typed AST for editing | — (internal parser, not an editing API) | — (render-only API) | ✅ `
|
|
40
|
-
| Typed mutation
|
|
39
|
+
| Parse to a typed AST for editing | — (internal parser, not an editing API) | — (render-only API) | ✅ `parseRegisteredMermaid` → typed `ValidDiagram` |
|
|
40
|
+
| Typed mutation | — | — | ✅ every registered family, structured-or-opaque and never lossy |
|
|
41
41
|
| Structural verification | — | — | ✅ 3 warning tiers + perceptual quality metrics, all families |
|
|
42
42
|
| Deterministic output | Not a goal (browser/layout variance) | Mostly stable, not a tested guarantee | ✅ byte-identical across runs/processes, CI-gated |
|
|
43
43
|
| Round-trip guarantee (parse → serialize keeps your source) | — | — | ✅ verbatim for unmodeled syntax, canonical for structured bodies |
|
|
44
44
|
| CLI | `mermaid-cli` (`mmdc`, Puppeteer-based) | — | `am` (render/verify/mutate/batch/preview/…, single-binary build) |
|
|
45
|
-
| MCP / agent surface | Official hosted MCP (validation, PNG, Mermaid Chart integration) | — | Local Code Mode MCP (`execute`, `render_png`, `describe`) plus hosted `/mcp` (`execute`, render/verify/describe, `mutate`/`build`), `llms.txt`, agent skill |
|
|
45
|
+
| MCP / agent surface | Official hosted MCP (validation, PNG, Mermaid Chart integration) | — | Local Code Mode MCP (`execute`, `describe_sdk`, `render_png`, `describe`) plus hosted `/mcp` (`execute`, progressive schema discovery, render/verify/describe, `mutate`/`build`), `llms.txt`, agent skill |
|
|
46
46
|
| Interactivity (click handlers, animations) | ✅ | Partial (tooltips) | Inherited where upstream has it; not a focus |
|
|
47
47
|
| Ecosystem & docs | Vast — the de-facto standard, GitHub/GitLab/Notion render it natively | Growing, popular for terminal/AI use | Small; this repo |
|
|
48
48
|
|
|
@@ -61,7 +61,7 @@ enriched palettes and Shiki theme compatibility; ASCII/Unicode terminal
|
|
|
61
61
|
output. Agentic Mermaid inherits all of this — it is upstream's work, and
|
|
62
62
|
credit belongs there.
|
|
63
63
|
|
|
64
|
-
**Only Agentic Mermaid:** the typed editing loop. `
|
|
64
|
+
**Only Agentic Mermaid:** the typed editing loop. `parseRegisteredMermaid` returns a
|
|
65
65
|
sealed IR; family narrowers (`asFlowchart` … `asXyChart`) expose typed
|
|
66
66
|
mutation ops; `verifyMermaid` returns structured warnings instead of asking
|
|
67
67
|
an agent to eyeball pixels; `serializeMermaid` round-trips losslessly
|
|
@@ -73,10 +73,22 @@ for zero-install render/verify/describe and structured edits, and tested
|
|
|
73
73
|
byte-identical determinism. Neither upstream project needed any of this: both serve humans who write
|
|
74
74
|
diagrams once, while this surface serves programs that edit them repeatedly.
|
|
75
75
|
|
|
76
|
+
## Mindmap/GitGraph and the terminal ecosystem
|
|
77
|
+
|
|
78
|
+
The checked fixtures follow the official [Mindmap](https://mermaid.ai/open-source/syntax/mindmap.html) and [GitGraph](https://mermaid.ai/open-source/syntax/gitgraph.html) syntax pages and render from the same authored source in Mermaid 11.16.0 and Agentic Mermaid. See the captioned [Mindmap comparison](./design/families/mindmap.md#visual-evidence) and [GitGraph comparison](./design/families/gitgraph.md#visual-evidence). Compare semantic structure—labels, shapes, hierarchy, lanes, commits, parentage, tags, and bounds—not pixels, because the layout/style engines differ.
|
|
79
|
+
|
|
80
|
+
[AlexanderGrooff/mermaid-ascii](https://github.com/AlexanderGrooff/mermaid-ascii) 1.4.0 does not currently implement either family. Replaying the documented CLI against the same fixtures exits 1 with:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
unsupported graph type 'mindmap'. Supported types: graph TD, graph TB, graph LR, flowchart TD, flowchart TB, flowchart LR
|
|
84
|
+
unsupported graph type 'gitGraph'. Supported types: graph TD, graph TB, graph LR, flowchart TD, flowchart TB, flowchart LR
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Its [diagram coverage issue #74](https://github.com/AlexanderGrooff/mermaid-ascii/issues/74) tracks additional families. This is a capability difference, not a claim that an unsupported render is visually worse.
|
|
88
|
+
|
|
76
89
|
## Choosing
|
|
77
90
|
|
|
78
|
-
- Rendering inside a web app, or you need
|
|
79
|
-
beyond the 12 here → **Mermaid**.
|
|
91
|
+
- Rendering inside a web app, or you need a family absent from `am capabilities --json` → **Mermaid**.
|
|
80
92
|
- Fast, beautiful SVG/ASCII rendering of the core families in
|
|
81
93
|
Node/Bun/terminal, render-only → **Beautiful Mermaid**.
|
|
82
94
|
- An AI agent (or any program) needs to *edit* diagrams safely, verify them
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# Computational-aesthetics prototype plan
|
|
2
|
+
|
|
3
|
+
This is the revised plan for cheap, deterministic computational aesthetics in
|
|
4
|
+
Agentic Mermaid. It covers pure functions over geometry and concrete sRGB. It
|
|
5
|
+
does not turn a rubric into an optimizer, add learned scores, or introduce
|
|
6
|
+
stochastic search.
|
|
7
|
+
|
|
8
|
+
The governing rule is stricter than “the formula is deterministic”:
|
|
9
|
+
|
|
10
|
+
> An aesthetic mechanism is ready only when its domain, runtime, product
|
|
11
|
+
> reachability, and evidence are all explicit.
|
|
12
|
+
|
|
13
|
+
Agentic Mermaid already operationalizes graph-layout research in
|
|
14
|
+
`src/layout-rubric.ts` and `src/family-rubric.ts`. The work below extends that
|
|
15
|
+
discipline to categorical color and whole-canvas composition without pretending
|
|
16
|
+
that one scalar score certifies beauty.
|
|
17
|
+
|
|
18
|
+
## Status
|
|
19
|
+
|
|
20
|
+
- **shipped** — implemented on a product path with discriminating tests.
|
|
21
|
+
- **prototype** — report-only until the evaluation harness justifies a weight.
|
|
22
|
+
- **rejected** — considered, but redundant or insufficiently specified.
|
|
23
|
+
|
|
24
|
+
| # | Idea | Status | Contract / next question |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| 1 | OKLCH constant-lightness categorical ramps | **shipped** | deterministic concrete-sRGB generation |
|
|
27
|
+
| 2 | Minimum ΔE_OK collision floor | **shipped** | hard for 7–24 fills; best-effort and linear-time above 24 |
|
|
28
|
+
| 3 | APCA plus WCAG background-visibility floors | **shipped** | every derived fill clears both for valid concrete backgrounds |
|
|
29
|
+
| 10 | Common-region ownership purity | **shipped** | architecture, class, ER, and timeline ownership frames |
|
|
30
|
+
| 12 | Separate typographic CPL warning | **rejected** | duplicates public universal `LABEL_OVERFLOW`; no independent signal |
|
|
31
|
+
| 4 | Cohen-Or hue-harmony templates | **rejected as a default** | 4/360 cases retain {1,2,3}; experiment remains reproducible |
|
|
32
|
+
| 5 | Purchase-normalized crosslessness `m_c` | prototype | does normalization discriminate across graph sizes? |
|
|
33
|
+
| 6 | Consistent flow-direction metric | prototype | does it catch anything ELK does not already guarantee? |
|
|
34
|
+
| 7 | Whole-canvas composition | prototype | which Ngo terms correlate with preference on our diagrams? |
|
|
35
|
+
| 8 | Crossing-angle / RAC penalty | prototype | incremental value after crossing count |
|
|
36
|
+
| 9 | Spine-straightness continuity | prototype | incremental value after {5,8} |
|
|
37
|
+
| 11 | Proximity / MST purity | prototype | incremental value after common-region and composition metrics |
|
|
38
|
+
| 13 | Information-theoretic order | prototype | is a pinned gzip ratio more than a coarse alignment proxy? |
|
|
39
|
+
|
|
40
|
+
## What the first implementation taught us
|
|
41
|
+
|
|
42
|
+
The audit and controlled rollout changed the plan in twelve ways.
|
|
43
|
+
|
|
44
|
+
1. **Runtime is part of correctness.** A deterministic pairwise repair still
|
|
45
|
+
fails the product if an allowed 1,000-slice input takes seconds. The ΔE
|
|
46
|
+
guarantee is therefore bounded at 24 and the large-count path has expected
|
|
47
|
+
linear work. Portable CI asserts the real branch and its operation counts;
|
|
48
|
+
wall-clock observations live in `eval/palette-performance/report.json` with
|
|
49
|
+
their machine, protocol, input hashes, and limitations. Every prototype must
|
|
50
|
+
declare an input-size budget and a degraded-tail rule.
|
|
51
|
+
|
|
52
|
+
2. **A threshold needs a corpus, not one friendly example.** The 0.10 ΔE claim
|
|
53
|
+
initially failed on shipped themes and custom accent/background pairs. The
|
|
54
|
+
contract now runs across every built-in theme, every count from 7 through
|
|
55
|
+
24, and adversarial saturated backgrounds. Future thresholds need the same
|
|
56
|
+
domain matrix before they can be called guarantees.
|
|
57
|
+
|
|
58
|
+
3. **Use the perceptual quantity that controls the decision.** HSL lightness
|
|
59
|
+
misclassified a bright saturated yellow-green background as dark. Palette
|
|
60
|
+
polarity now uses OKLab lightness, and visibility repair searches both
|
|
61
|
+
lightness directions before falling back to a visible achromatic extreme.
|
|
62
|
+
|
|
63
|
+
4. **A shared waist multiplies risk as well as value.** `pieSliceColors` already
|
|
64
|
+
reaches pie and radar, so one defect reaches both. Migrating four more
|
|
65
|
+
families remains valuable, but only after the waist has an explicit range,
|
|
66
|
+
a hard runtime bound, adversarial tests, and per-family visual review.
|
|
67
|
+
|
|
68
|
+
5. **Reachability precedes novelty.** A test-only finding is not a product
|
|
69
|
+
capability. The proposed `LABEL_LINE_OVERLONG` finding was not surfaced by
|
|
70
|
+
verify, CLI, API, or MCP and overlapped the existing public
|
|
71
|
+
`LABEL_OVERFLOW` warning. It is removed rather than wired twice.
|
|
72
|
+
|
|
73
|
+
6. **Independence applies before implementation too.** A new metric must state
|
|
74
|
+
which existing defect it detects that current metrics miss. Idea #12 fails
|
|
75
|
+
that test. Ideas {7,11} and {5,8,9} must pass it through ablation.
|
|
76
|
+
|
|
77
|
+
7. **Semantic scope must follow every real model.** Common-region purity is not
|
|
78
|
+
architecture-only: class namespaces, ER groups, and timeline sections also
|
|
79
|
+
express ownership. Ancestor walks must be cycle-safe without arbitrary
|
|
80
|
+
depth cutoffs.
|
|
81
|
+
|
|
82
|
+
8. **Visual evidence needs its own reproducibility contract.** The rollout now
|
|
83
|
+
freezes pre-change SVGs, extracts the categorical colors actually serialized
|
|
84
|
+
by each renderer, writes a machine-readable comparison, and hashes every
|
|
85
|
+
source input plus the generated report/contact sheet. `--check` fails when
|
|
86
|
+
code, baseline, metrics, or images drift.
|
|
87
|
+
|
|
88
|
+
9. **A controlled rollout is a compatibility policy, not a global recolor.**
|
|
89
|
+
Counts up to six retain each family's existing derived colors byte-for-byte
|
|
90
|
+
(including Journey's established actor wheel). Authored
|
|
91
|
+
`plotColorPalette`, `actorColours`, `sectionFills`/`sectionColours`, and
|
|
92
|
+
`git0..7` remain authoritative. Only derived high-cardinality peer-category
|
|
93
|
+
colors change.
|
|
94
|
+
|
|
95
|
+
10. **Harmony and categorical distinctness compete at this density.** Across
|
|
96
|
+
20 built-in themes × counts 7..24, the Cohen-Or/Matsuda experiment reduced
|
|
97
|
+
mean harmony loss from 8.8303° to 0.0084°, but reduced mean minimum ΔE_OK
|
|
98
|
+
from 0.1107 to 0.0456. Only 4/360 palettes retained {1,2,3}; no count above
|
|
99
|
+
seven passed. That rejects #4 as a default layer over this palette.
|
|
100
|
+
|
|
101
|
+
11. **A measurement must not claim more than it measures.** The performance
|
|
102
|
+
corpus measures one palette-generation call, not a complete diagram render.
|
|
103
|
+
Most controlled families have one peer-category channel; Journey has two
|
|
104
|
+
independent channels (sections and actors). Following the
|
|
105
|
+
[testing-best-practices guidance](https://github.com/adewale/testing-best-practices/tree/e50479920006aa010850a2c37f9bee1e02b5badf),
|
|
106
|
+
CI gates deterministic complexity and evidence freshness, never a portable
|
|
107
|
+
millisecond threshold.
|
|
108
|
+
|
|
109
|
+
12. **Normalize at the algorithm boundary without erasing compatibility.**
|
|
110
|
+
StyleSpec accepts concrete `#RGB`, named, `rgb()`, and `hsl()` colors, while
|
|
111
|
+
the perceptual math requires six-digit sRGB. The high-count path now
|
|
112
|
+
normalizes every parser-resolvable concrete color before repair. The ≤6
|
|
113
|
+
path deliberately preserves each family's historical spelling or fallback
|
|
114
|
+
policy byte-for-byte; a global normalizer at that boundary would be a
|
|
115
|
+
compatibility regression disguised as cleanup.
|
|
116
|
+
|
|
117
|
+
## Shipped color contract and family reach
|
|
118
|
+
|
|
119
|
+
The color work is a generation constraint, not evidence that the quality
|
|
120
|
+
rubric predicts human preference. The neutral shared waist now reaches pie,
|
|
121
|
+
radar, xychart, journey, mindmap, and gitgraph. SVG and terminal xychart/gitgraph
|
|
122
|
+
use the same derived palette; the other terminal families do not currently
|
|
123
|
+
encode peer categories with color.
|
|
124
|
+
|
|
125
|
+
The scope rule for this rollout, and for any future shared-palette expansion,
|
|
126
|
+
is explicit:
|
|
127
|
+
|
|
128
|
+
> The scope is intentionally limited to families where color identifies peer
|
|
129
|
+
> categories. Semantic colors—status, hierarchy, role, or user-authored
|
|
130
|
+
> meaning—should not be automatically redistributed.
|
|
131
|
+
|
|
132
|
+
| Property | 7–24 fills | More than 24 fills |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| deterministic | hard | hard |
|
|
135
|
+
| valid concrete hex output | hard | hard |
|
|
136
|
+
| WCAG ≥ 1.25 and APCA ≥ 15 vs concrete background | hard | hard |
|
|
137
|
+
| unique fills | hard | best-effort |
|
|
138
|
+
| minimum pairwise ΔE_OK ≥ 0.10 | hard | not claimed |
|
|
139
|
+
| asymptotic repair cost | bounded `O(M·n²)`, with `n ≤ 24` and fixed corpus `M` | expected `O(n)` with average `O(1)` set membership |
|
|
140
|
+
|
|
141
|
+
The established local palette is preserved when it meets the contract. If it
|
|
142
|
+
does not, a deterministic farthest-point packing pass selects background-visible
|
|
143
|
+
concrete sRGB candidates. Above 24, pairwise enforcement is skipped.
|
|
144
|
+
|
|
145
|
+
## Prototype protocol
|
|
146
|
+
|
|
147
|
+
Reuse the existing evaluator; do not create a second quality system.
|
|
148
|
+
|
|
149
|
+
1. **Define the contract first.** State applicable families, input-size range,
|
|
150
|
+
asymptotic and wall-clock budgets, degraded-tail behavior, and exclusions.
|
|
151
|
+
2. **Prove product reachability.** Identify the public result, warning, or
|
|
152
|
+
report that exposes the metric. A private helper plus unit test is not done.
|
|
153
|
+
3. **Report before weighting.** Add the metric to the per-metric tracker with
|
|
154
|
+
zero score weight. A weight is a separate scoring-contract change.
|
|
155
|
+
4. **Add trip fixtures.** Include healthy and deliberately bad examples that
|
|
156
|
+
make the metric move. Zero on every committed fixture is a guard, not a
|
|
157
|
+
demonstrated discriminator.
|
|
158
|
+
5. **Measure the full domain.** Use the Mermaid docs corpus, heuristic tracker,
|
|
159
|
+
deterministic family fuzzers, all built-in themes where color is involved,
|
|
160
|
+
and adversarial boundary inputs.
|
|
161
|
+
6. **Keep visual evidence.** Any generation or geometry change needs
|
|
162
|
+
before/after renders and snapshot review in every affected family. The
|
|
163
|
+
palette rollout operationalizes this rule in
|
|
164
|
+
`scripts/pr-assets/palette-rollout-evidence.ts`.
|
|
165
|
+
7. **Gate determinism and cost.** Preserve byte identity and deterministically
|
|
166
|
+
assert that the intended bounded algorithmic path engaged. Keep p50/p95
|
|
167
|
+
observations over a fixed corpus in a separate, provenance-bound report;
|
|
168
|
+
do not use cross-machine wall time as a CI threshold. Idea #13 must also pin
|
|
169
|
+
codec and level.
|
|
170
|
+
|
|
171
|
+
## Evaluation and graduation
|
|
172
|
+
|
|
173
|
+
For a candidate metric M, record:
|
|
174
|
+
|
|
175
|
+
- **coverage** — fraction of diagrams on which M varies;
|
|
176
|
+
- **discrimination** — LCC/SROCC against a small blinded human A/B set;
|
|
177
|
+
- **independence** — partial correlation after controlling for current metrics;
|
|
178
|
+
- **stability** — sensitivity to harmless translation, scale, and equivalent
|
|
179
|
+
source ordering where those transforms should not matter;
|
|
180
|
+
- **cost** — deterministic operation growth at the declared size boundary,
|
|
181
|
+
plus environment-qualified p50/p95 observations where useful;
|
|
182
|
+
- **reach** — public surfaces and diagram families that consume the result.
|
|
183
|
+
|
|
184
|
+
Graduate a metric from report-only only when it fires on trip fixtures, varies
|
|
185
|
+
on the corpus, adds preference signal after current metrics, and stays inside
|
|
186
|
+
its cost budget. Otherwise remove it or retain it explicitly as a correctness
|
|
187
|
+
guard with no aesthetic weight.
|
|
188
|
+
|
|
189
|
+
For combinations, run small ablations rather than blending everything. Treat
|
|
190
|
+
each combination as a gated ladder: validate the cheaper base term, add one
|
|
191
|
+
term, and stop when independence disappears.
|
|
192
|
+
|
|
193
|
+
- **{1,2,3}:** lightness structure, categorical distance, and background
|
|
194
|
+
visibility are complementary and already ship as one generation contract.
|
|
195
|
+
- **{1,2,3,4}:** the completed experiment found no useful Pareto front at
|
|
196
|
+
8–24 categories: hue-sector contraction almost eliminates harmony loss but
|
|
197
|
+
breaks minimum categorical distance. Do not ship this bundle as a default.
|
|
198
|
+
- **{5,8}:** crossing prevalence and crossing quality should be complementary.
|
|
199
|
+
- **{5,6,8}:** add direction only if #6 catches defects not explained by the
|
|
200
|
+
crossing pair or by ELK's existing directional constraints.
|
|
201
|
+
- **{5,8,9}:** likely redundant; add #9 only if partial correlation survives.
|
|
202
|
+
- **{7,10,11}:** composition, common region, and proximity span figure,
|
|
203
|
+
ownership, and local grouping scales, but need ablation because the signals
|
|
204
|
+
can collapse onto the same cluster structure.
|
|
205
|
+
|
|
206
|
+
## Revised stack rank
|
|
207
|
+
|
|
208
|
+
The rank uses five axes: user-visible value, independence from existing
|
|
209
|
+
signals, product reach, bounded runtime, and validation burden. “Foundation” is
|
|
210
|
+
not optional feature work. An arrow means “validate the new idea alone, then
|
|
211
|
+
admit it to the combination”; it is not permission to ship an opaque aggregate.
|
|
212
|
+
|
|
213
|
+
| Rank | Work package | Form | Why it is here | Stop / go gate |
|
|
214
|
+
|---|---|---|---|---|
|
|
215
|
+
| Foundation | **Keep {1,2,3,10}; reject #12** | shipped contract | Color and ownership have bounded, reachable contracts; the extra label warning is redundant. | keep the regression matrix green |
|
|
216
|
+
| Delivered | **Controlled {1,2,3} family rollout** | shipped combination | 14/14 fixture violations corrected; 8/8 family/theme cases pass; ≤6 colors and authored overrides remain compatible; six rich website examples expose the peer mapping at inspectable size. | palette evidence, complexity, website, and family gates |
|
|
217
|
+
| Rejected | **#4 → {1,2,3,4} color-harmony default** | completed experiment | 4/360 pass rate; mean minimum ΔE_OK falls 0.1107 → 0.0456. | reconsider only with a new constraint-preserving algorithm and blinded preference evidence |
|
|
218
|
+
| Paused 1 | **#5 normalized crosslessness `m_c`** | telemetry, postponed | Still the cheapest next metric experiment, but telemetry work is intentionally deferred. | resume only on explicit telemetry restart |
|
|
219
|
+
| Paused 2 | **#8 → {5,8} crossing-quality bundle** | telemetry, postponed | Clear ablation after #5. | #8 must add signal after #5 |
|
|
220
|
+
| Paused 3 | **#6 → {5,6,8} directional-legibility bundle** | telemetry, postponed | Likely overlaps ELK behavior. | independent trip case first |
|
|
221
|
+
| Paused 4 | **#7 whole-canvas composition** | telemetry, postponed | Potential figure-level value, high calibration burden. | stable, nonzero corpus coverage |
|
|
222
|
+
| Paused 5 | **#11 → {7,10,11} multiscale grouping** | telemetry, postponed | Plausible value with high redundancy risk. | term-by-term ablation |
|
|
223
|
+
| Paused 6 | **#9 → {5,8,9} edge-path bundle** | telemetry, postponed | Costlier and likely redundant. | partial-correlation survival |
|
|
224
|
+
| Paused 7 | **#13 pinned-gzip order** | telemetry, postponed | Codec-sensitive and coarse. | beat simpler direct features |
|
|
225
|
+
|
|
226
|
+
This supersedes the earlier ordering. The highest-ranked product change is now
|
|
227
|
+
delivered and its evidence gate is permanent. The harmony experiment has also
|
|
228
|
+
resolved its decision: it is not merely lower priority; this formulation is a
|
|
229
|
+
bad default. With telemetry postponed, there is no authorized next aesthetic
|
|
230
|
+
metric package. If telemetry resumes, it still starts with #5 and every later
|
|
231
|
+
bundle remains conditional on ablation.
|
|
232
|
+
|
|
233
|
+
## Scope boundaries
|
|
234
|
+
|
|
235
|
+
- This plan covers measurement and closed-form generation, not optimization.
|
|
236
|
+
- Flowchart/state subgraph purity remains in `layout-rubric.ts`; the generic
|
|
237
|
+
#10 implementation covers ownership frames projected by architecture, class,
|
|
238
|
+
ER, and timeline.
|
|
239
|
+
- `LABEL_OVERFLOW` remains the public label-length signal. It applies the
|
|
240
|
+
caller-configurable cap to the longest rendered line after entity decoding,
|
|
241
|
+
line-break normalization, and formatting-tag removal. A second fixed CPL
|
|
242
|
+
warning would be redundant and less reachable.
|
|
243
|
+
- The shared perceptual palette reaches only families where color denotes peer
|
|
244
|
+
categories: pie slices, radar curves, xychart series, journey actors/sections,
|
|
245
|
+
mindmap top-level branches, and gitgraph branches. Structural families use
|
|
246
|
+
color for roles, status, hierarchy, or authored semantics; automatic hue
|
|
247
|
+
spreading there would invent category meaning and can weaken brand/status
|
|
248
|
+
cues. Timeline/gantt/quadrant have family-specific categorical contracts and
|
|
249
|
+
are not silently swept into this rollout.
|
|
250
|
+
- A score of 100 proves only that a renderer clears the measured hygiene floor;
|
|
251
|
+
it does not certify beauty. Each family still needs an aesthetic thesis and
|
|
252
|
+
human visual review.
|
package/docs/config.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Agentic Mermaid accepts Mermaid-style runtime config through explicit render options, YAML frontmatter, and `%%{init: ...}%%` / `%%{initialize: ...}%%` directives.
|
|
4
4
|
|
|
5
5
|
Round-trip behavior: the agent surface preserves these source wrappers
|
|
6
|
-
byte-verbatim — `
|
|
6
|
+
byte-verbatim — `parseRegisteredMermaid → serializeMermaid` and every `mutate` re-emit
|
|
7
7
|
the original frontmatter/directives/leading comments untouched, so a
|
|
8
8
|
`config.layout`/`config.look` request written for Mermaid survives an
|
|
9
9
|
Agentic Mermaid edit loop. Canonical wrapper synthesis (config-nested
|
|
@@ -29,7 +29,7 @@ const svg = renderMermaidSVG(source, {
|
|
|
29
29
|
})
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Explicit options win over source-level config when both specify the same supported field.
|
|
32
|
+
Explicit options win over source-level config when both specify the same supported field. `RenderOptions.onConfigDiagnostic` can collect warnings for explicit config that is unknown, invalid, or has no faithful effect; without a collector, explicit ineffective State config warns through `console.warn` rather than disappearing silently.
|
|
33
33
|
|
|
34
34
|
## YAML frontmatter
|
|
35
35
|
|
|
@@ -70,14 +70,30 @@ Top-level:
|
|
|
70
70
|
`themeVariables` and explicit color options still win over a style's
|
|
71
71
|
palette, preserving Mermaid compatibility.)
|
|
72
72
|
|
|
73
|
-
Family-specific
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
Family-specific config is **wire-or-warn**: every accepted key either changes
|
|
74
|
+
output or produces `INEFFECTIVE_CONFIG` naming the field. Unknown keys also
|
|
75
|
+
warn, so spelling mistakes cannot disappear silently. This contract covers all
|
|
76
|
+
every registered family and both frontmatter and init directives.
|
|
77
|
+
|
|
78
|
+
Notable wired sections include:
|
|
79
|
+
|
|
80
|
+
- `flowchart`: spacing and measured wrapping;
|
|
81
|
+
- `sequence`: actor/message/note spacing, dimensions, activations, and numbering;
|
|
82
|
+
- `timeline`, `journey`, `class`, `er`, `architecture`, `xyChart`, `pie`,
|
|
83
|
+
`quadrantChart`, `mindmap`, and `gitGraph`: the fields documented in their
|
|
84
|
+
family design notes;
|
|
85
|
+
- `gantt.displayMode` (`compact` packs non-overlapping tasks in a section into
|
|
86
|
+
shared rows).
|
|
87
|
+
|
|
88
|
+
`state` has a typed `StateRuntimeConfig`. `nodeSpacing`, `rankSpacing`,
|
|
89
|
+
`padding`, `radius`, `fontSize`, `compositTitleSize` (upstream spelling),
|
|
90
|
+
`forkWidth`, `forkHeight`, `noteMargin`, and `dividerMargin` are wired to
|
|
91
|
+
State-specific geometry/paint. `defaultRenderer: 'elk'` is satisfied;
|
|
92
|
+
alternate renderer requests, invalid values, and legacy Dagre/fixed-metric
|
|
93
|
+
calibration fields emit qualified `state.*` diagnostics. Unsupported fields
|
|
94
|
+
and wrappers remain source-preserved. The executable all-family audit is
|
|
95
|
+
`src/__tests__/unknown-config-wire-or-warn.test.ts`; the independent State key
|
|
96
|
+
inventory and discriminating geometry probes are in `state-config.test.ts`.
|
|
81
97
|
|
|
82
98
|
## Security
|
|
83
99
|
|