agentic-mermaid 0.4.1 → 0.5.3
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 +94 -627
- package/CHANGELOG.md +651 -0
- package/Instructions_for_agents.md +44 -23
- package/LICENSES/Khroma-MIT.txt +21 -0
- package/LICENSES/Mermaid-MIT.txt +21 -0
- package/LICENSES/es-toolkit-MIT.txt +21 -0
- package/LICENSES/pele-MIT.txt +40 -0
- package/LICENSES/zenuml-core-MIT.txt +21 -0
- package/README.md +93 -50
- package/SECURITY.md +28 -12
- package/THIRD_PARTY_NOTICES.md +60 -0
- package/assets/hero.png +0 -0
- package/dist/agent-core.d.ts +478 -210
- package/dist/agent-core.js +1 -396
- package/dist/agent.d.ts +17 -8
- package/dist/agent.js +1 -408
- package/dist/agentic-mermaid-mcp.js +1 -11
- package/dist/am.js +1 -34562
- package/dist/browser-lazy/chunks/agentic-producer-core-CC6OOLDW.js +1 -0
- package/dist/browser-lazy/chunks/architecture-QUFVKYJR.js +13 -0
- package/dist/browser-lazy/chunks/block-6J3Q63BO.js +11 -0
- package/dist/browser-lazy/chunks/builtin-backends-7SOZZHPF.js +12 -0
- package/dist/browser-lazy/chunks/c4-SQVBZAKJ.js +10 -0
- package/dist/browser-lazy/chunks/chunk-2GPK4VFF.js +5 -0
- package/dist/browser-lazy/chunks/chunk-2I4UPL7Q.js +3 -0
- package/dist/browser-lazy/chunks/chunk-2SH76OTH.js +1 -0
- package/dist/browser-lazy/chunks/chunk-2UIA2IME.js +3 -0
- package/dist/browser-lazy/chunks/chunk-4LHYF3BS.js +1 -0
- package/dist/browser-lazy/chunks/chunk-5B2Z7575.js +1 -0
- package/dist/browser-lazy/chunks/chunk-5FQ534HP.js +1 -0
- package/dist/browser-lazy/chunks/chunk-5UVGUSD6.js +1 -0
- package/dist/browser-lazy/chunks/chunk-5X6MJX3H.js +1 -0
- package/dist/browser-lazy/chunks/chunk-AMJLVPUB.js +4 -0
- package/dist/browser-lazy/chunks/chunk-BU5LHXNJ.js +3 -0
- package/dist/browser-lazy/chunks/chunk-BY2CPG6B.js +1 -0
- package/dist/browser-lazy/chunks/chunk-CN7WTBWB.js +1 -0
- package/dist/browser-lazy/chunks/chunk-CQE4HQEW.js +1 -0
- package/dist/browser-lazy/chunks/chunk-CSFUKSU6.js +1 -0
- package/dist/browser-lazy/chunks/chunk-DF6765YX.js +17 -0
- package/dist/browser-lazy/chunks/chunk-E2WMJZNM.js +1 -0
- package/dist/browser-lazy/chunks/chunk-FAIMVOX5.js +6 -0
- package/dist/browser-lazy/chunks/chunk-GVOEAY52.js +1 -0
- package/dist/browser-lazy/chunks/chunk-HLWUNUCM.js +1 -0
- package/dist/browser-lazy/chunks/chunk-ICC7HBJX.js +1 -0
- package/dist/browser-lazy/chunks/chunk-J35HAQQF.js +20 -0
- package/dist/browser-lazy/chunks/chunk-J7FFAFQF.js +1 -0
- package/dist/browser-lazy/chunks/chunk-LH7HUDKW.js +1 -0
- package/dist/browser-lazy/chunks/chunk-N5ELX7LR.js +2 -0
- package/dist/browser-lazy/chunks/chunk-NMQQMRIR.js +1 -0
- package/dist/browser-lazy/chunks/chunk-NO7ZIVRU.js +1 -0
- package/dist/browser-lazy/chunks/chunk-OZ443IVJ.js +16 -0
- package/dist/browser-lazy/chunks/chunk-PQGPS2YV.js +7 -0
- package/dist/browser-lazy/chunks/chunk-QA6GJQ4X.js +1 -0
- package/dist/browser-lazy/chunks/chunk-RIVTHZAQ.js +1 -0
- package/dist/browser-lazy/chunks/chunk-SZELX2EJ.js +1 -0
- package/dist/browser-lazy/chunks/chunk-TYZOZXUJ.js +22 -0
- package/dist/browser-lazy/chunks/chunk-UL6NDWLL.js +1 -0
- package/dist/browser-lazy/chunks/chunk-VQYYGAXP.js +1 -0
- package/dist/browser-lazy/chunks/chunk-VWVZGQE2.js +1 -0
- package/dist/browser-lazy/chunks/chunk-X2UYKWKM.js +4 -0
- package/dist/browser-lazy/chunks/chunk-YCEICNM6.js +1 -0
- package/dist/browser-lazy/chunks/chunk-Z3FDIVLN.js +20 -0
- package/dist/browser-lazy/chunks/class-5QA4SCTS.js +13 -0
- package/dist/browser-lazy/chunks/decode-63UIZGD2.js +1 -0
- package/dist/browser-lazy/chunks/elk.bundled-L4CADV5W.js +24 -0
- package/dist/browser-lazy/chunks/er-7ZSKGN7Y.js +11 -0
- package/dist/browser-lazy/chunks/eventmodeling-2BPLHWRN.js +19 -0
- package/dist/browser-lazy/chunks/flowchart-NEIMZTB5.js +4 -0
- package/dist/browser-lazy/chunks/forest-implementation-AEP24AIP.js +1 -0
- package/dist/browser-lazy/chunks/gantt-RDPIFYAF.js +11 -0
- package/dist/browser-lazy/chunks/gitgraph-N4Y5RYB7.js +9 -0
- package/dist/browser-lazy/chunks/ishikawa-LD3YBDJN.js +6 -0
- package/dist/browser-lazy/chunks/journey-6YQR5DJX.js +16 -0
- package/dist/browser-lazy/chunks/kanban-PLMJ7NBW.js +20 -0
- package/dist/browser-lazy/chunks/mermaid-yaml-runtime-QVYX4EWK.js +136 -0
- package/dist/browser-lazy/chunks/mindmap-K2UBFO3Y.js +12 -0
- package/dist/browser-lazy/chunks/packet-CUW4QY6Y.js +7 -0
- package/dist/browser-lazy/chunks/pie-7F7UUCG3.js +15 -0
- package/dist/browser-lazy/chunks/quadrant-TOONO2WC.js +10 -0
- package/dist/browser-lazy/chunks/radar-J6JVWVAX.js +16 -0
- package/dist/browser-lazy/chunks/render-core-BZOM3K7D.js +3 -0
- package/dist/browser-lazy/chunks/requirement-CMAKDJPO.js +19 -0
- package/dist/browser-lazy/chunks/sankey-AWXQEP3F.js +13 -0
- package/dist/browser-lazy/chunks/sequence-Q2RJRB4L.js +5 -0
- package/dist/browser-lazy/chunks/state-WRBFQEDX.js +4 -0
- package/dist/browser-lazy/chunks/timeline-D2KILFXM.js +6 -0
- package/dist/browser-lazy/chunks/treemap-N3VYX5D4.js +6 -0
- package/dist/browser-lazy/chunks/xychart-G73OGK66.js +16 -0
- package/dist/browser-lazy/chunks/zenuml-H4BXNYXR.js +16 -0
- package/dist/browser-lazy/index.d.ts +544 -275
- package/dist/browser-lazy/index.js +1 -1
- package/dist/browser.global.js +802 -565
- package/dist/chunk-3LGLPG33.js +2 -0
- package/dist/chunk-7CRDX2QR.js +2 -0
- package/dist/chunk-7PPW2BMO.js +2 -0
- package/dist/chunk-DQDKA5ND.js +2 -0
- package/dist/chunk-EHCMJUMD.js +52 -0
- package/dist/chunk-GVCHLSHH.js +4 -0
- package/dist/chunk-H3NCS2XZ.js +19 -0
- package/dist/chunk-JZOJ4YGS.js +201 -0
- package/dist/chunk-MKE7GNYU.js +146 -0
- package/dist/chunk-NKNFOREZ.js +2 -0
- package/dist/chunk-O7H2UX5K.js +2 -0
- package/dist/chunk-OMY6NRQD.js +58 -0
- package/dist/chunk-UA234O4M.js +4 -0
- package/dist/chunk-VUFVLGTH.js +2 -0
- package/dist/chunk-XU5LPD2D.js +2 -0
- package/dist/cli-YGGTJZH7.js +226 -0
- package/dist/elk-constructor.js +2 -0
- package/dist/elk-constructor.node.js +11 -0
- package/dist/index-EeXqJXr5.d.ts +1223 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -334
- package/dist/jsonl-RPJY6YWO.js +2 -0
- package/dist/mcp-cli-63DYXTVD.js +2 -0
- package/dist/{index-BGA_-6LV.d.ts → paint-certification-6rwQjIv_.d.ts} +5283 -6173
- package/dist/server-5NEOHOFS.js +524 -0
- package/dist/svg-styles-BdnoM7AT.d.ts +724 -0
- package/dist/svg-styles.d.ts +1 -0
- package/dist/svg-styles.js +2 -0
- package/dist/svg.d.ts +13 -0
- package/dist/svg.js +2 -0
- package/dist/types-BcS52Mjt.d.ts +1360 -0
- package/dist/zenuml/chunks/appearance-UOQ5KA6O.js +1 -0
- package/dist/zenuml/chunks/builtin-backends-KDKE7YHO.js +12 -0
- package/dist/zenuml/chunks/chunk-42DXZ5C6.js +4 -0
- package/dist/zenuml/chunks/chunk-7TVYPTDW.js +1 -0
- package/dist/zenuml/chunks/chunk-EVPSMEKN.js +1 -0
- package/dist/zenuml/chunks/chunk-OXQWRSBM.js +20 -0
- package/dist/zenuml/chunks/chunk-QWX77U7G.js +2 -0
- package/dist/zenuml/chunks/chunk-RLJEI7YN.js +29 -0
- package/dist/zenuml/chunks/chunk-RZ6XK5CD.js +29 -0
- package/dist/zenuml/chunks/decode-BWERFDGK.js +1 -0
- package/dist/zenuml/chunks/mermaid-yaml-runtime-KZVU74WU.js +136 -0
- package/dist/zenuml/chunks/render-core-V5RQ737O.js +3 -0
- package/dist/zenuml/chunks/zenuml-EA2ZFRUX.js +20 -0
- package/dist/zenuml-frame.global.js +3626 -0
- package/dist/zenuml.d.ts +83 -0
- package/dist/zenuml.js +1 -0
- package/docs/MCP-DIRECTORY-LISTINGS.md +5 -1
- package/docs/README.md +59 -103
- package/docs/agent-api-cookbook.md +26 -16
- package/docs/agent-mutation-policy.md +86 -15
- package/docs/agent-workflow-examples.md +1 -1
- package/docs/api-advanced.md +385 -0
- package/docs/api.md +320 -366
- package/docs/ascii.md +40 -4
- package/docs/browser.md +46 -7
- package/docs/choosing-a-diagram.md +148 -0
- package/docs/code-mode-impact.md +1 -0
- package/docs/comparison.md +244 -28
- package/docs/computational-aesthetics-prototype-plan.md +10 -10
- package/docs/config.md +60 -2
- package/docs/custom-fonts.md +78 -21
- package/docs/diagram-families.md +160 -10
- package/docs/eventmodeling-and-zenuml.md +165 -0
- package/docs/features.md +21 -19
- package/docs/fork-differences.md +105 -32
- package/docs/getting-started.md +56 -51
- package/docs/layout-certification.md +126 -0
- package/docs/mcp-code-mode-rationale.md +20 -12
- package/docs/mcp-http-transport.md +14 -8
- package/docs/quality.md +145 -15
- package/docs/react.md +76 -31
- package/docs/style-authoring.md +23 -11
- package/docs/svg-semantic-contract.md +104 -4
- package/docs/testing-strategy.md +684 -126
- package/docs/theming.md +27 -8
- package/examples/styles/readme-hero.md +25 -0
- package/examples/styles/readme-hero.mmd +13 -0
- package/examples/styles/readme-hero.style.json +7 -0
- package/package.json +114 -57
- package/server.json +2 -2
- package/skills/agentic-mermaid-diagram-workflow/SKILL.md +26 -8
- package/skills/agentic-mermaid-diagram-workflow/references/cli.md +13 -3
- package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +2 -1
- package/skills/agentic-mermaid-diagram-workflow/references/flowchart.md +9 -6
- package/skills/agentic-mermaid-diagram-workflow/references/hosted-mcp.md +1 -0
- package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +4 -3
- package/skills/agentic-mermaid-diagram-workflow/references/timeline.md +7 -6
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/agentflow.md +574 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/architecture.md +10 -2
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/c4.md +18 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/classDiagram.md +123 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/cynefin.md +6 -1
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/entityRelationshipDiagram.md +129 -9
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/eventmodeling.md +22 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/flowchart.md +188 -60
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/gitgraph.md +13 -7
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/mindmap.md +110 -1
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/packet.md +38 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/requirementDiagram.md +115 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/sequenceDiagram.md +101 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/stateDiagram.md +87 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/swimlanes.md +105 -2
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/timeline.md +12 -6
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/usecase.md +953 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/venn.md +77 -0
- package/skills/agentic-mermaid-diagram-workflow/references/upstream/xyChart.md +1 -1
- package/dist/browser-lazy/chunks/architecture-KTHE2HX3.js +0 -31
- package/dist/browser-lazy/chunks/chunk-2XCPFAD5.js +0 -46
- package/dist/browser-lazy/chunks/chunk-3H4F7RBT.js +0 -1
- package/dist/browser-lazy/chunks/chunk-4EVLW2NJ.js +0 -1
- package/dist/browser-lazy/chunks/chunk-5Q4S74UO.js +0 -1
- package/dist/browser-lazy/chunks/chunk-6OAPWSDO.js +0 -1
- package/dist/browser-lazy/chunks/chunk-A7L4WWVW.js +0 -143
- package/dist/browser-lazy/chunks/chunk-C7FJO2I3.js +0 -4
- package/dist/browser-lazy/chunks/chunk-D3XXDKIO.js +0 -1
- package/dist/browser-lazy/chunks/chunk-DXA5WL7H.js +0 -4
- package/dist/browser-lazy/chunks/chunk-EPFMQPXX.js +0 -1
- package/dist/browser-lazy/chunks/chunk-FFOHLPDA.js +0 -2
- package/dist/browser-lazy/chunks/chunk-FLD63DXE.js +0 -2
- package/dist/browser-lazy/chunks/chunk-G6OLSHRG.js +0 -7
- package/dist/browser-lazy/chunks/chunk-GRXCKTHX.js +0 -0
- package/dist/browser-lazy/chunks/chunk-I6VE56S7.js +0 -1
- package/dist/browser-lazy/chunks/chunk-KJVNXJ5Y.js +0 -1
- package/dist/browser-lazy/chunks/chunk-L227EPFP.js +0 -11
- package/dist/browser-lazy/chunks/chunk-LNIHDJSF.js +0 -1
- package/dist/browser-lazy/chunks/chunk-M6BT2HIP.js +0 -1
- package/dist/browser-lazy/chunks/chunk-NZRUMODH.js +0 -1
- package/dist/browser-lazy/chunks/chunk-OFRMKQA6.js +0 -1
- package/dist/browser-lazy/chunks/chunk-P7HMSKHJ.js +0 -1
- package/dist/browser-lazy/chunks/chunk-PXKL3O6H.js +0 -1
- package/dist/browser-lazy/chunks/chunk-PZEWZT35.js +0 -1
- package/dist/browser-lazy/chunks/chunk-STQRDZ67.js +0 -1
- package/dist/browser-lazy/chunks/chunk-SUFMSWTX.js +0 -1
- package/dist/browser-lazy/chunks/chunk-T7IJ6V4B.js +0 -3
- package/dist/browser-lazy/chunks/chunk-UAEZO5VL.js +0 -1
- package/dist/browser-lazy/chunks/chunk-WEUWIFG3.js +0 -1
- package/dist/browser-lazy/chunks/chunk-X64T74C5.js +0 -24
- package/dist/browser-lazy/chunks/class-F7R6TJ73.js +0 -9
- package/dist/browser-lazy/chunks/er-BDK7CM5L.js +0 -9
- package/dist/browser-lazy/chunks/flowchart-KFU6XV7S.js +0 -4
- package/dist/browser-lazy/chunks/gantt-I64VVDSP.js +0 -28
- package/dist/browser-lazy/chunks/gitgraph-EDUVJ5IJ.js +0 -8
- package/dist/browser-lazy/chunks/journey-TLO2RNM3.js +0 -40
- package/dist/browser-lazy/chunks/mindmap-OJCNDYPM.js +0 -9
- package/dist/browser-lazy/chunks/pie-HVG6XO7K.js +0 -19
- package/dist/browser-lazy/chunks/quadrant-U6S2L4MJ.js +0 -24
- package/dist/browser-lazy/chunks/radar-ZDLOBTVG.js +0 -32
- package/dist/browser-lazy/chunks/render-core-Y2DFNMQG.js +0 -12
- package/dist/browser-lazy/chunks/sequence-Z4WFS3VB.js +0 -12
- package/dist/browser-lazy/chunks/state-2HV2YGN3.js +0 -4
- package/dist/browser-lazy/chunks/timeline-XM4UFPOC.js +0 -20
- package/dist/browser-lazy/chunks/xychart-7JDHWTQY.js +0 -36
- package/dist/chunk-GGXCNCNA.js +0 -4118
- package/dist/chunk-IVD4NXNE.js +0 -615
- package/dist/chunk-JDMRPUAG.js +0 -37
- package/dist/chunk-JWAAW3FH.js +0 -149
- package/dist/chunk-LCGBT32P.js +0 -62036
- package/dist/chunk-RWMZRUIC.js +0 -4715
- package/dist/mcp-cli-4MLKC3ZH.js +0 -17
- package/docs/mutation-testing.md +0 -285
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# Advanced library API
|
|
2
|
+
|
|
3
|
+
Configure host rendering, inspect receipts, and extend AM.
|
|
4
|
+
|
|
5
|
+
Start with the ordinary workflows in the [library reference](./api.md).
|
|
6
|
+
|
|
7
|
+
This page describes the same source checkout as the library reference. Check its
|
|
8
|
+
[version information](./api.md#versions) before using a feature from an installed package.
|
|
9
|
+
|
|
10
|
+
## Canonical requests and comparable receipts
|
|
11
|
+
|
|
12
|
+
Every first-party renderer enters through the same immutable internal request
|
|
13
|
+
boundary: source wrappers/config, the Style stack, colors, font, security, and
|
|
14
|
+
shared options are normalized once. Receipt-bearing variants make that boundary
|
|
15
|
+
observable without exporting its executable implementation types or changing
|
|
16
|
+
the existing convenience return types:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import {
|
|
20
|
+
renderMermaidASCIIWithReceipt,
|
|
21
|
+
renderMermaidPNGWithReceipt,
|
|
22
|
+
renderMermaidSVGWithReceipt,
|
|
23
|
+
} from 'agentic-mermaid/agent'
|
|
24
|
+
|
|
25
|
+
const options = { style: 'hand-drawn', seed: 7, embedFontImport: false }
|
|
26
|
+
const svg = renderMermaidSVGWithReceipt(source, options)
|
|
27
|
+
const png = renderMermaidPNGWithReceipt(source, options)
|
|
28
|
+
const text = renderMermaidASCIIWithReceipt(source, { ...options, colorMode: 'none' })
|
|
29
|
+
|
|
30
|
+
console.assert(svg.receipt.sharedRequestDigest === png.receipt.sharedRequestDigest)
|
|
31
|
+
console.assert(svg.receipt.appearanceDigest === text.receipt.appearanceDigest)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Each `RenderRequestReceipt` contains `version`, `output`,
|
|
35
|
+
`sharedRequestDigest`, output-specific `requestDigest`, and
|
|
36
|
+
`appearanceDigest`. Its `diagnostics` array records stable request-resolution,
|
|
37
|
+
compatibility, applicability, projection, and output-policy decisions. In
|
|
38
|
+
particular, `RENDER_OPTION_NOT_APPLICABLE` makes an authored family-scoped
|
|
39
|
+
option that the selected family does not consume observable instead of letting
|
|
40
|
+
it change request identity silently. CLI JSON results and local/hosted MCP
|
|
41
|
+
render results expose the same receipt. Use `validateSerializableRenderOptions(value)` and
|
|
42
|
+
`sharedRenderOptionsJsonSchema()` for untrusted advanced option objects, or
|
|
43
|
+
`styleInputJsonSchema()` for a standalone convenience `style` field; unknown
|
|
44
|
+
fields, `null`, functions, prototype keys, and non-finite values are rejected.
|
|
45
|
+
Graphical receipts name an explicitly selected pixel `textMeasurement` profile
|
|
46
|
+
(`id` and `version`). Trusted hosts can select custom metrics through the
|
|
47
|
+
renderer factories described below; their callback never enters a receipt.
|
|
48
|
+
|
|
49
|
+
## PNG fonts, portability and rasterization
|
|
50
|
+
|
|
51
|
+
PNG rasterization uses offline `@resvg/resvg-js` with bundled fonts for
|
|
52
|
+
deterministic same-machine output: Inter (the default face — the same family
|
|
53
|
+
the SVG requests and the family `src/text-metrics.ts` is calibrated for, so
|
|
54
|
+
rasterized labels match their measured boxes), DejaVu Sans as a per-glyph
|
|
55
|
+
fallback for symbols Inter lacks, plus the faces the built-in styles
|
|
56
|
+
reference (Caveat, EB Garamond, Architects Daughter, Share Tech Mono — see
|
|
57
|
+
`assets/fonts/FONT-LICENSES.md`). A style whose `font` is neither bundled
|
|
58
|
+
nor supplied via `fontDirs` rasterizes with Inter. Characters no loaded font
|
|
59
|
+
covers (CJK, most emoji) draw as tofu boxes and raise a `PNG_FONT_COVERAGE`
|
|
60
|
+
warning naming the script and the escape hatches (`fontDirs` /
|
|
61
|
+
`loadSystemFonts`).
|
|
62
|
+
|
|
63
|
+
The raster-legibility gate measures literal absolute-pixel `font-size`
|
|
64
|
+
attributes on `text`, `tspan`, and `textPath` elements in the secured SVG.
|
|
65
|
+
This is exact for first-party built-in emitters. Extension SVG text is measured
|
|
66
|
+
only when the extension emits those literal attributes. The gate abstains when
|
|
67
|
+
CSS can override size or transforms, or when an SVG transform can change glyph
|
|
68
|
+
scale; translation and rotation are admitted because they preserve size. It
|
|
69
|
+
does not resolve extension-specific visibility, such as text templates under
|
|
70
|
+
`defs` or `display:none`, so such markup can conservatively over-report. The effective scale is
|
|
71
|
+
computed from the finalized integer raster height divided by the SVG `viewBox`
|
|
72
|
+
height, after projection rounding, because font sizes are expressed in user
|
|
73
|
+
units and the root is pinned with `preserveAspectRatio="none"`. For an extension
|
|
74
|
+
with no measurable literal size, absence of a
|
|
75
|
+
`BELOW_READABLE_SIZE` warning is therefore not proof that its labels are
|
|
76
|
+
readable. Callers that know the task, viewing distance, or display conditions
|
|
77
|
+
should select a task-specific floor rather than relying on the default.
|
|
78
|
+
|
|
79
|
+
The bytes-only browser convenience call returns only PNG bytes. Use
|
|
80
|
+
`renderMermaidPNGWithReceipt` on a bound browser renderer, or
|
|
81
|
+
`renderMermaidPNGInBrowserWithReceipt`, when the caller must inspect browser
|
|
82
|
+
diagnostics.
|
|
83
|
+
|
|
84
|
+
Note for third-party rasterizers: the SVG declares fonts as
|
|
85
|
+
`font-family: var(--font, 'Face')`, and static rasterizers (resvg, librsvg)
|
|
86
|
+
do not resolve CSS custom properties — `renderMermaidPNG` inlines the
|
|
87
|
+
resolved family before rasterizing; do the same if you feed the raw SVG to
|
|
88
|
+
your own pipeline.
|
|
89
|
+
|
|
90
|
+
For complete custom-Style recipes using `font`, `fontDirs`, browser faces, and
|
|
91
|
+
SVG font declarations, see [Fonts in custom styles](./custom-fonts.md).
|
|
92
|
+
|
|
93
|
+
PNG output declares the shared sRGB policy with `sRGB` and `cICP` metadata,
|
|
94
|
+
places `cICP` before image data, and deliberately emits no conflicting ICC
|
|
95
|
+
profile. SVG and PNG consume the same resolved graphical colors before
|
|
96
|
+
rasterization.
|
|
97
|
+
|
|
98
|
+
### Trusted host-selected graphical backends
|
|
99
|
+
|
|
100
|
+
Executable Scene painting backends are bound by the host, never selected by `RenderOptions` or
|
|
101
|
+
serialized Style data. These factories apply the same canonical request,
|
|
102
|
+
Scene-admission, SVG-security, receipt, PNG-output-policy, and color-profile
|
|
103
|
+
contracts as their default counterparts:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import {
|
|
107
|
+
createMermaidBrowserPNGRenderer,
|
|
108
|
+
createMermaidRenderer,
|
|
109
|
+
} from 'agentic-mermaid'
|
|
110
|
+
import { createMermaidPNGRenderer } from 'agentic-mermaid/agent'
|
|
111
|
+
|
|
112
|
+
const backendPolicy = { selectBackend: () => 'backend:acme/renderer' }
|
|
113
|
+
const svgRenderer = createMermaidRenderer({ backendPolicy })
|
|
114
|
+
const nodePngRenderer = createMermaidPNGRenderer({ backendPolicy })
|
|
115
|
+
const browserPngRenderer = createMermaidBrowserPNGRenderer({
|
|
116
|
+
backendPolicy,
|
|
117
|
+
rasterize: async (securedSvg, context) => ({
|
|
118
|
+
png: await rasterizeWithCanvas(securedSvg, context.outputPolicy),
|
|
119
|
+
}),
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Register and conformance-check the named backend before constructing these
|
|
124
|
+
renderers. The Node/Bun factory reuses the built-in `@resvg/resvg-js` adapter;
|
|
125
|
+
the browser factory wraps a trusted injected rasterizer, which receives only
|
|
126
|
+
the admitted and secured SVG plus the complete resolved portable output policy.
|
|
127
|
+
Its rasterizer must apply `fitTo` and `background`, not only `scale`.
|
|
128
|
+
`renderMermaidSVG`, `renderMermaidPNG`, and
|
|
129
|
+
`renderMermaidPNGInBrowserWithReceipt` remain the compatible default-backend
|
|
130
|
+
entry points.
|
|
131
|
+
|
|
132
|
+
### Trusted host-selected pixel metrics
|
|
133
|
+
|
|
134
|
+
The same three factories accept `textMeasurement`, a named, versioned
|
|
135
|
+
`TextMeasurementProfile` with a synchronous `measure(input)` callback returning
|
|
136
|
+
the run's natural width in pixels. Inputs include displayed `text`,
|
|
137
|
+
`fontFamily`, `fontSize`, `fontWeight`, `fontStyle`, and `monospace`. Letter
|
|
138
|
+
spacing and wrapping remain the library's responsibility. The host supplies
|
|
139
|
+
the font measurement implementation and makes its fonts available to the
|
|
140
|
+
selected SVG/PNG consumer; no Canvas or system-font measurement is enabled
|
|
141
|
+
implicitly. See [custom fonts](./custom-fonts.md#trusted-font-measurement-profiles)
|
|
142
|
+
for an example and reproducibility requirements.
|
|
143
|
+
|
|
144
|
+
This is an in-process host option, separate from serializable `RenderOptions`,
|
|
145
|
+
Style data, Mermaid source, editor state, CLI, and MCP inputs. Bound renderers
|
|
146
|
+
capture the profile's name, version, and function once. Layout, prepared pixel
|
|
147
|
+
text, SVG advances, and both PNG adapters use those same metrics. Receipts
|
|
148
|
+
record its identity and include custom identity in request digests. Terminal
|
|
149
|
+
cell widths remain independent. Omitting the profile keeps the existing
|
|
150
|
+
deterministic Inter estimate, SVG output, and receipt shape unchanged.
|
|
151
|
+
|
|
152
|
+
## SVG semantic identity and accessibility
|
|
153
|
+
|
|
154
|
+
All built-in families expose the same inspectable element contract:
|
|
155
|
+
|
|
156
|
+
- every Scene part with source-facing semantics has a deterministic `data-id` and closed
|
|
157
|
+
`data-role`; identity is unique within one SVG (layout furniture retains typed
|
|
158
|
+
Scene identity without bloating the DOM);
|
|
159
|
+
- source relations use `data-from` and `data-to`; source `className` tokens stay
|
|
160
|
+
on the identified element's `class` attribute;
|
|
161
|
+
- typed relations expose `role="graphics-symbol"`,
|
|
162
|
+
`aria-roledescription="relation"`, and an `aria-label` derived from endpoints
|
|
163
|
+
plus the authored relation label;
|
|
164
|
+
- public Scene types expose `SvgSemanticIdentity`,
|
|
165
|
+
`SvgSemanticAccessibility`, and `SvgRelationSemantics`;
|
|
166
|
+
- `idPrefix` rewrites local DOM `id` references, not source-facing `data-id`.
|
|
167
|
+
|
|
168
|
+
Built-in concrete palettes are contrast-normalized at render time: normal text
|
|
169
|
+
roles meet WCAG AA 4.5:1 and meaningful relation lines/markers meet 3:1 against
|
|
170
|
+
the page background. Unresolved runtime CSS variables cannot be statically
|
|
171
|
+
certified and pass through unchanged. See
|
|
172
|
+
[`svg-semantic-contract.md`](./svg-semantic-contract.md) for the complete contract.
|
|
173
|
+
|
|
174
|
+
For JSON files, use
|
|
175
|
+
[`docs/schemas/style-spec.schema.json`](./schemas/style-spec.schema.json). The
|
|
176
|
+
same schema is exported from the npm package as
|
|
177
|
+
`agentic-mermaid/style-spec.schema.json`; see
|
|
178
|
+
[`custom-style-cookbook.md`](./custom-style-cookbook.md) for complete style
|
|
179
|
+
files and screenshots, and [`custom-fonts.md`](./custom-fonts.md) for font
|
|
180
|
+
resolution across output surfaces.
|
|
181
|
+
|
|
182
|
+
## Observe a native parser
|
|
183
|
+
|
|
184
|
+
The root library exports `withParserObservation(family, observer, parse)`. Wrap
|
|
185
|
+
one synchronous parser call to receive its actual consumed statements and
|
|
186
|
+
builder writes. Each event names its native kind, family and unit
|
|
187
|
+
(`statement`, `token` or `mutation`). Source coordinates explicitly distinguish
|
|
188
|
+
physical input from a parser's normalized view. Mutation operands are copied at
|
|
189
|
+
the call boundary, retaining identities, parent and membership fields.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { parseRegisteredMermaid, withParserObservation } from 'agentic-mermaid'
|
|
193
|
+
|
|
194
|
+
const observations: import('agentic-mermaid').ParserObservation[] = []
|
|
195
|
+
const result = withParserObservation(
|
|
196
|
+
'flowchart',
|
|
197
|
+
event => observations.push(event),
|
|
198
|
+
() => parseRegisteredMermaid('flowchart LR\nA --> B'),
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Nested scopes restore their caller, including after an exception. An observer
|
|
203
|
+
callback does not implicitly observe a parser it invokes itself. Promise-returning
|
|
204
|
+
callbacks are rejected because the scope is synchronous. Observation is a
|
|
205
|
+
trusted in-process diagnostic API, outside serializable render options.
|
|
206
|
+
|
|
207
|
+
Native statement kinds and builder operations describe our implementations;
|
|
208
|
+
they are not Mermaid terminal kinds or its `yy` method protocol. Flowchart also
|
|
209
|
+
exposes consumed compound node/link fragments. Other native parsers expose
|
|
210
|
+
classified statements rather than a homologous token stream. The modern
|
|
211
|
+
assessment compares explicitly scoped semantic fields using independent
|
|
212
|
+
reference adapters and records unavailable comparisons honestly.
|
|
213
|
+
|
|
214
|
+
Flowchart/State positioned graphs also carry a `certification` receipt after
|
|
215
|
+
bounded final geometry checking. At most four deterministic candidates are
|
|
216
|
+
considered. Exhaustion throws `LayoutCertificationError` with code
|
|
217
|
+
`LAYOUT_CERTIFICATION_FAILED` and per-candidate reasons. This certifies hard graph
|
|
218
|
+
invariants, not an optimal layout. The common positioning boundary also vetoes
|
|
219
|
+
hard family-rubric violations in every native family's final projection.
|
|
220
|
+
Specialized family layouters get one attempt and fail explicitly; their checks
|
|
221
|
+
do not imply graph route guarantees or certify soft aesthetic quality.
|
|
222
|
+
|
|
223
|
+
The family registry is the operation authority. Use `am capabilities --json`
|
|
224
|
+
for the current roster and field schemas, or call `describeOps(family)` and
|
|
225
|
+
`opSignatures(family)` at runtime. The generated SDK declaration projects the
|
|
226
|
+
same descriptors; this reference deliberately does not copy an exhaustive
|
|
227
|
+
family/operation table.
|
|
228
|
+
|
|
229
|
+
### Preserved Sequence and XY label facts
|
|
230
|
+
|
|
231
|
+
Sequence facts include recognized messages inside preserved segments as
|
|
232
|
+
`preserved-message#<segment>.<statement> ...` and their title directives.
|
|
233
|
+
These identifiers do not change the typed `message#<index>` mutation indexes.
|
|
234
|
+
XY facts include authored point labels as `series#<index> point#<index> : <label>`;
|
|
235
|
+
the point index stays aligned with the data even when labels are sparse.
|
|
236
|
+
Consumers using `exact: true` must add these facts to their reviewed expected
|
|
237
|
+
inventory. Subset checks can keep their existing required facts. Do not build
|
|
238
|
+
an expected inventory by copying the output being checked.
|
|
239
|
+
|
|
240
|
+
### Class relation facts and `exact: true`
|
|
241
|
+
|
|
242
|
+
Class facts retain their existing class/member/relation lines and add endpoint
|
|
243
|
+
marker ownership and shaft style. A caller with a hardcoded complete fact set
|
|
244
|
+
must include these additions when using `exact: true`. For example:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
const parsed = parseRegisteredMermaid('classDiagram\nPerson --|> Animal')
|
|
248
|
+
if (!parsed.ok) throw new Error('Invalid Class source')
|
|
249
|
+
|
|
250
|
+
const legacy = [
|
|
251
|
+
'class Animal',
|
|
252
|
+
'class Person',
|
|
253
|
+
'family class',
|
|
254
|
+
'relation Person inheritance Animal',
|
|
255
|
+
'relation#0 Person inheritance Animal',
|
|
256
|
+
]
|
|
257
|
+
const expected = [
|
|
258
|
+
...legacy,
|
|
259
|
+
'relation#0 Person inheritance Animal marker to',
|
|
260
|
+
'relation#0 Person inheritance Animal line solid',
|
|
261
|
+
]
|
|
262
|
+
checkMermaid(parsed.value, { include: expected, exact: true }) // ok: true
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Using `legacy` alone returns `ok: false` and lists the two new lines in
|
|
266
|
+
`unexpected`. The expanded expectation also rejects `Person <|-- Animal`,
|
|
267
|
+
because that relationship has `marker from`. Two-ended relationships add
|
|
268
|
+
`relation#0 from marker <kind>` and `relation#0 to marker <kind>` facts so
|
|
269
|
+
different marker kinds at the two ends remain distinguishable. Keep reviewed
|
|
270
|
+
expectations independent of the output being checked; deriving them from that
|
|
271
|
+
same output would accept its mistakes. Subset checks omit `exact: true` and
|
|
272
|
+
must still require the marker/shaft facts whose preservation matters.
|
|
273
|
+
|
|
274
|
+
### Authoring Class endpoint markers and shafts
|
|
275
|
+
|
|
276
|
+
Use `add_interface` to create a one-ended lollipop occurrence explicitly:
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
const op = {
|
|
280
|
+
kind: 'add_interface', class: 'Service', label: 'Protocol',
|
|
281
|
+
side: 'to', relationLabel: 'provides', lineStyle: 'solid',
|
|
282
|
+
} as const
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Each operation creates a separate interface occurrence. Its `label` names the
|
|
286
|
+
interface; `relationLabel` names the connection. Ordinary classes with the same
|
|
287
|
+
spelling remain distinct. `add_relation` rejects one-ended lollipops between
|
|
288
|
+
ordinary class IDs and points callers to `add_interface`, since canonical
|
|
289
|
+
Mermaid source would otherwise change endpoint identity.
|
|
290
|
+
|
|
291
|
+
Class `add_relation` accepts optional `markerAt`, `fromKind`, `toKind` and
|
|
292
|
+
`lineStyle` fields. Existing calls that omit them retain the relation kind's
|
|
293
|
+
defaults. For example, this operation writes `Port ()..o Service`:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
const op = {
|
|
297
|
+
kind: 'add_relation', from: 'Port', to: 'Service',
|
|
298
|
+
relKind: 'lollipop', markerAt: 'both', toKind: 'aggregation',
|
|
299
|
+
lineStyle: 'dashed',
|
|
300
|
+
} as const
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`markerAt` selects the active endpoints; endpoint kinds on inactive sides are
|
|
304
|
+
refused. The primary `relKind`, endpoint kinds and shaft must agree with the
|
|
305
|
+
relationship read back from the emitted source. Contradictory combinations
|
|
306
|
+
return `INVALID_OP` instead of silently changing kind on reload. Cardinalities,
|
|
307
|
+
labels and authored endpoint identities already present in parsed relationships
|
|
308
|
+
survive unrelated edits. Relationship label/cardinality line breaks export as
|
|
309
|
+
Mermaid `<br/>` markup so they remain on one source line. Direct `add_class`
|
|
310
|
+
copies initial members; member
|
|
311
|
+
authoring refuses blank/comment-form text, accessibility directives and physical
|
|
312
|
+
or entity-decoded line breaks rather than admitting text that disappears or
|
|
313
|
+
changes structure. The source reader still accepts diagram accessibility
|
|
314
|
+
directives; they cannot be authored through a member operation.
|
|
315
|
+
|
|
316
|
+
Opaque fallback bodies (any unmodeled syntax) are source-level-only: edit source deliberately, then parse and verify again.
|
|
317
|
+
|
|
318
|
+
## Capability and extension discovery
|
|
319
|
+
|
|
320
|
+
`am capabilities --json` reports the live family registry. (The Section A
|
|
321
|
+
capability report and its `createSectionACapabilityReport()` audit module are no
|
|
322
|
+
longer published.)
|
|
323
|
+
|
|
324
|
+
Canonical extension identities are kind-qualified (`look:`, `palette:`,
|
|
325
|
+
`backend:`, `family:`, `role:`, and `resource:`), versioned, provenance-bearing,
|
|
326
|
+
and collision-safe. New graphical backends declare feature/operation-level
|
|
327
|
+
Scene primitive capability claims; the registry rejects an empty, duplicate,
|
|
328
|
+
cross-target, or otherwise invalid claim set. Every external backend, and every
|
|
329
|
+
external family that supplies `lowerScene`, must also declare an explicit
|
|
330
|
+
compatible `identity.compatibility.scene` range (Scene v2: `^2.0.0`). The host
|
|
331
|
+
checks that range before running backend conformance or other executable
|
|
332
|
+
witnesses; only the internal built-in enrollment path receives compatibility
|
|
333
|
+
defaults.
|
|
334
|
+
|
|
335
|
+
### Current customization and extension inventory
|
|
336
|
+
|
|
337
|
+
This is the current authoritative inventory. See the
|
|
338
|
+
[render-options table](./api.md#render-options) and
|
|
339
|
+
[StyleSpec reference](./style-authoring.md) for field details.
|
|
340
|
+
|
|
341
|
+
| Level | Public seam | What it can change | Boundary and availability |
|
|
342
|
+
|---|---|---|---|
|
|
343
|
+
| Mermaid-authored appearance | frontmatter/init config, theme variables, family style statements such as classes and link styles | Syntax-defined colors, labels, family geometry, and interaction metadata where the family advertises support | Source-level and family-dependent. Raw `themeCSS` is recognized but diagnosed at the render boundary because its selectors and markup can escape an imported SVG; use `StyleSpec` instead. |
|
|
344
|
+
| One-off render overrides | `RenderOptions` | Palette channels, font family, spacing/geometry controls, deterministic seed, security, accessibility-related output options, and a Style stack | The generated field×surface matrix marks each serializable shared field `forwarded`, `host-enforced`, or `unavailable`. Hosted SVG and editor SVG enforce strict security with external font imports disabled; effective receipts reflect those constraints. Host callbacks are library-only and never enter receipts. |
|
|
345
|
+
| One-off declarative style | inline `StyleSpec` or a left-to-right `StyleInput[]` stack | Safe palette, font, stroke/fill treatment, backdrop, exact semantic-role defaults, named semantic slots, V1 `category` bindings, non-color cues, and inspect-only contrast/accent-area/mono-role constraints | JSON-safe and executable-code-free. Bindings supply defaults beneath authored family paint and semantics; constraints diagnose final effective paint without repainting or relayout. This is the lowest-complexity custom Style path. |
|
|
346
|
+
| Named Palette/Look | `registerStyle`, `getStyle`, `knownStyleDescriptors` | Installs a versioned `palette:` or `look:` name backed by exactly the same `StyleSpec` accepted inline | Descriptors expose one `kind` (`look` or `palette`), explicit `isDefault`, and one stable `inputName`. In-process host registry. A CLI/MCP/server sees a registration only when that host installs it at startup. |
|
|
347
|
+
| Theme conversion | `fromShikiTheme` | Converts a Shiki-compatible editor theme into diagram colors | Pure library helper; the result is ordinary declarative color input. |
|
|
348
|
+
| Live host retheming | CSS custom-property values in graphical color/font inputs | Lets a host page switch SVG palette and font values without re-rendering | SVG/browser-only and limited to safe property values; this is not a raw CSS rule or selector hook. Static outputs need values resolved under their rasterization environment to remain reproducible. |
|
|
349
|
+
| Terminal output projection | `AsciiRenderOptions` (`useAscii`, `paddingX`, `paddingY`, `boxBorderPadding`, `colorMode`, `theme`, `targetWidth`/`maxWidth`, `onProjectionDiagnostic`) | Selects Unicode/ASCII encoding, cell spacing, width policy, ANSI/HTML colors, terminal-only theme overrides, and projection-loss reporting | Output-adapter customization, not a second shared Style system. Serializable fields have transport-specific availability; the diagnostic callback is host-only and remains outside receipts. |
|
|
350
|
+
| Fonts and installed resources | `font`, Node PNG `fontDirs`/`loadSystemFonts`/`onWarning`, browser `BrowserPngRasterizer`, `ResourceManifest`, and repository host tooling via `NodeResourceResolver` | Selects a safe font stack, supplies host-dependent raster fonts, reports missing glyph coverage, or verifies bounded installed bytes | Font family names do not install fonts. Browser and warning callbacks remain outside serializable options and every digest. Node `fontDirs`/`loadSystemFonts` are trusted host inputs outside shared `RenderOptions` and the shared/appearance digests, but their resolved PNG output policy is included in the output-specific request digest; runtime provenance still marks host-dependent resources explicitly. Manifests require path, size, media-type, digest, and licence evidence and never fall back to network access. |
|
|
351
|
+
| Graphical backend | `registerBackend`, `runBackendConformance`, `createMermaidRenderer`, `createMermaidPNGRenderer`, `createMermaidBrowserPNGRenderer` (each with a host-only `backendPolicy`) | Serializes the typed Scene contract with a different drawing implementation for SVG, native Node/Bun PNG, and injected-rasterizer browser PNG | Trusted in-process host only. Host registrations must explicitly declare compatible core and Scene ranges; identity/compatibility admission precedes executable conformance. Registration then must pass bounded, deterministic, semantic, well-formed, secure SVG conformance plus an exact witness for every first-party core Scene primitive/feature/operation claim; namespaced extension claims without a core witness remain explicitly unverified. All listed factories use the same admitted and secured graphical request; PNG adapters do not reparse or rerender source. Serializable styles and `RenderOptions` cannot select arbitrary executable backends. |
|
|
352
|
+
| Diagram family | `registerFamily`, `getFamilyConformanceReport`, `parseRegisteredMermaid`, `projectPositionedView` | Adds a namespaced language with detection, parse/preservation, verification, layout, Scene/SVG, terminal, and discovery claims | Every versioned `family:<owner/name>` descriptor declares a compatible core range and supplies one bounded canonical `example`. It also lists consumed family-scoped shared fields in `applicableRenderOptions`; omission means none, unknown or duplicate fields fail registration, and the frozen declaration appears in the capability report. Registration stages the frozen candidate, runs native claims twice through canonical parse/serialize, non-empty positive-bounds layout, strict SVG, portable PNG pre-raster, terminal, Scene and verify paths, and rolls back on failure, reentrancy or nondeterminism. Discovery reports `native` only beside a passed per-capability witness. Native tuples still require layout + `projectPositioned`, Scene requires layout + `lowerScene`, and extension verification requires its hook plus executable SVG. An external Scene family additionally declares a compatible Scene range, and its example witnesses every positive role/primitive cell. Built-in-only unions stay closed; extension bodies use the open envelope. Remote transports gain the family only when their trusted host installs it. |
|
|
353
|
+
| Scene semantics | `SceneDoc`, typed connectors/markers/hit geometry, namespaced `SceneRole` | Lets a family/backend exchange identity, relationship, accessibility, geometry, and terminal-projection intent | This is a versioned typed contract, not a raw SVG hook. Unknown namespaced roles deliberately receive inert identity-only traits and cannot acquire core behavior by local-name collision. There is no public arbitrary Scene primitive/trait mutation registry. |
|
|
354
|
+
| Browser PNG host adapter | `renderMermaidPNGInBrowserWithReceipt(..., rasterize)` or reusable `createMermaidBrowserPNGRenderer({ rasterize, backendPolicy? })` | Supplies Canvas/OffscreenCanvas rasterization and reports font provenance | Trusted callback receives only the admitted, secured canonical SVG; the library re-applies the PNG color-profile gate and retains the same logical receipt as the native PNG path. |
|
|
355
|
+
| Identity plumbing | `canonicalExtensionId`, `parseExtensionId`, `createExtensionIdentity`, `registerExtension`, `ExtensionCollisionError` | Gives kind-specific registries stable names, parsing, versions, provenance, compatibility ranges, and collision rejection | Low-level plumbing, not a stand-alone extension registry or rendering hook. Stable short inputs belong to kind-specific descriptors. |
|
|
356
|
+
|
|
357
|
+
There is currently no BrandPack registry, public role-trait registration,
|
|
358
|
+
arbitrary SVG/CSS hook, or Treatment hook. Semantic slots and the closed V1
|
|
359
|
+
`category` binding API are ordinary `StyleSpec` fields; other Scene channels are
|
|
360
|
+
not publicly bindable without new executable family witnesses. B4 remains the
|
|
361
|
+
unpromoted, evidence-gated BrandPack distribution envelope only. A future
|
|
362
|
+
Treatment seam is a separate decision and is not implied by B4.
|
|
363
|
+
|
|
364
|
+
## Graph layout hints
|
|
365
|
+
|
|
366
|
+
Flowchart and State graphical renders accept explicit deterministic preferences:
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
const options = {
|
|
370
|
+
layoutHints: {
|
|
371
|
+
ranks: { UI: 0, API: 1, Cache: 2, DB: 3 },
|
|
372
|
+
adjacent: [['Cache', 'DB']],
|
|
373
|
+
shortEdges: ['API->Cache'],
|
|
374
|
+
},
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Ranks are ordered ELK partitions, with unlisted nodes in partition zero; they
|
|
379
|
+
are not absolute pixel positions. Adjacency prefers consecutive sibling model
|
|
380
|
+
order within one container. Short-edge preferences use authored IDs or
|
|
381
|
+
`from->to` / `from->to#k` occurrence IDs. All references are checked; unknown
|
|
382
|
+
identities and conflicting adjacency groups fail explicitly. These preferences
|
|
383
|
+
never delete relationships, remain subject to geometry certification, and do not
|
|
384
|
+
guarantee a shortest route or fixed positions. Retain render options beside the
|
|
385
|
+
Mermaid source; hints participate in request digests, editor config, and receipts.
|