zombie-mermaid 2.2.1 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +7 -2
  3. package/dist/ascii.cjs +9 -9
  4. package/dist/ascii.cjs.map +1 -1
  5. package/dist/ascii.js +4069 -3969
  6. package/dist/ascii.js.map +1 -1
  7. package/dist/cli.js +7605 -7381
  8. package/dist/index.cjs +52 -52
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.js +7613 -7459
  11. package/dist/index.js.map +1 -1
  12. package/dist/mcp.cjs +14142 -13717
  13. package/dist/mcp.cjs.map +1 -1
  14. package/dist/mcp.js +14142 -13717
  15. package/dist/mcp.js.map +1 -1
  16. package/package.json +27 -5
  17. package/packages/ascii-renderer/LICENSE +22 -0
  18. package/{src/ascii → packages/ascii-renderer/src}/class-diagram.ts +277 -57
  19. package/{src/ascii → packages/ascii-renderer/src}/er-diagram.ts +2 -2
  20. package/packages/ascii-renderer/src/flowchart.ts +94 -0
  21. package/{src/ascii → packages/ascii-renderer/src}/grid.ts +23 -0
  22. package/{src/ascii → packages/ascii-renderer/src}/index.ts +13 -84
  23. package/{src/ascii → packages/ascii-renderer/src}/registry.ts +23 -12
  24. package/{src/ascii → packages/ascii-renderer/src}/sequence.ts +55 -8
  25. package/{src/ascii → packages/ascii-renderer/src}/xychart.ts +6 -3
  26. package/packages/core/LICENSE +22 -0
  27. package/packages/core/src/click-directive.ts +106 -0
  28. package/packages/core/src/color-utils.ts +205 -0
  29. package/packages/core/src/diagram-type.ts +35 -0
  30. package/packages/core/src/direction-override.ts +46 -0
  31. package/packages/core/src/direction.ts +56 -0
  32. package/packages/core/src/index.ts +34 -0
  33. package/packages/core/src/init-directive.ts +248 -0
  34. package/packages/core/src/multiline-utils.ts +275 -0
  35. package/packages/core/src/statements.ts +197 -0
  36. package/packages/core/src/style-directives.ts +214 -0
  37. package/packages/core/src/text-metrics.ts +498 -0
  38. package/packages/core/src/theme.ts +696 -0
  39. package/packages/core/src/types.ts +670 -0
  40. package/packages/mcp/LICENSE +22 -0
  41. package/{src/mcp → packages/mcp/src}/server.ts +34 -2
  42. package/{src/mcp → packages/mcp/src}/tools/check-sequence-activations.ts +8 -5
  43. package/packages/mcp/src/tools/fix-sequence-activations.ts +77 -0
  44. package/{src/mcp → packages/mcp/src}/tools/render-ascii.ts +2 -2
  45. package/{src/mcp → packages/mcp/src}/tools/render-svg.ts +1 -1
  46. package/packages/mermaid-parser/LICENSE +22 -0
  47. package/{src → packages/mermaid-parser/src}/class/parser.ts +86 -8
  48. package/{src → packages/mermaid-parser/src}/er/parser.ts +59 -26
  49. package/packages/mermaid-parser/src/index.ts +48 -0
  50. package/{src → packages/mermaid-parser/src}/sequence/activation-check.ts +4 -3
  51. package/packages/mermaid-parser/src/sequence/activation-fix.ts +112 -0
  52. package/{src → packages/mermaid-parser/src}/sequence/parser.ts +74 -16
  53. package/{src → packages/mermaid-parser/src}/xychart/parser.ts +84 -6
  54. package/packages/svg-renderer/LICENSE +22 -0
  55. package/{src → packages/svg-renderer/src}/class/layout.ts +8 -4
  56. package/{src → packages/svg-renderer/src}/class/renderer.ts +7 -6
  57. package/packages/svg-renderer/src/edge-curves.ts +204 -0
  58. package/packages/svg-renderer/src/elk-instance.ts +292 -0
  59. package/{src → packages/svg-renderer/src}/er/layout.ts +6 -4
  60. package/{src → packages/svg-renderer/src}/er/renderer.ts +4 -4
  61. package/packages/svg-renderer/src/index.ts +58 -0
  62. package/packages/svg-renderer/src/layout-engine/constants.ts +19 -0
  63. package/packages/svg-renderer/src/layout-engine/edge-bundling.ts +379 -0
  64. package/packages/svg-renderer/src/layout-engine/elk-adapter-utils.ts +81 -0
  65. package/packages/svg-renderer/src/layout-engine/elk-graph-builder.ts +240 -0
  66. package/packages/svg-renderer/src/layout-engine/from-elk.ts +685 -0
  67. package/packages/svg-renderer/src/layout-engine/layer-alignment.ts +174 -0
  68. package/packages/svg-renderer/src/layout-engine/to-elk.ts +695 -0
  69. package/packages/svg-renderer/src/layout-engine.ts +74 -0
  70. package/packages/svg-renderer/src/layout.ts +8 -0
  71. package/packages/svg-renderer/src/renderer.ts +1485 -0
  72. package/packages/svg-renderer/src/resolve-colors.ts +339 -0
  73. package/{src → packages/svg-renderer/src}/sequence/layout.ts +2 -6
  74. package/{src → packages/svg-renderer/src}/sequence/renderer.ts +4 -4
  75. package/packages/svg-renderer/src/shape-clipping.ts +197 -0
  76. package/packages/svg-renderer/src/styles.ts +118 -0
  77. package/{src → packages/svg-renderer/src}/xychart/layout.ts +2 -2
  78. package/{src → packages/svg-renderer/src}/xychart/renderer.ts +6 -6
  79. package/src/__tests__/ascii-ansi.test.ts +6 -2
  80. package/src/__tests__/ascii-canvas-write.test.ts +2 -2
  81. package/src/__tests__/ascii-charset-border-junctions.test.ts +1 -1
  82. package/src/__tests__/ascii-cjk-width.test.ts +1 -1
  83. package/src/__tests__/ascii-class-box-occupancy.test.ts +147 -45
  84. package/src/__tests__/ascii-class-column-width-488-489.test.ts +1 -1
  85. package/src/__tests__/ascii-class-cross-level-jog-corruption.test.ts +187 -0
  86. package/src/__tests__/ascii-class-detour-label-routing-487.test.ts +1 -1
  87. package/src/__tests__/ascii-class-diagram-compartments.test.ts +1 -1
  88. package/src/__tests__/ascii-class-label-box-collision.test.ts +1 -1
  89. package/src/__tests__/ascii-class-label-row-collision-531.test.ts +1 -1
  90. package/src/__tests__/ascii-class-label-territory-row-awareness.test.ts +1 -1
  91. package/src/__tests__/ascii-class-padding.test.ts +1 -1
  92. package/src/__tests__/ascii-class-reciprocal-relationships-448.test.ts +86 -1
  93. package/src/__tests__/ascii-combining-mark-width.test.ts +2 -2
  94. package/src/__tests__/ascii-coords-overlay.test.ts +2 -2
  95. package/src/__tests__/ascii-decision-lr-box-start.test.ts +2 -2
  96. package/src/__tests__/ascii-display-width-unit.test.ts +1 -1
  97. package/src/__tests__/ascii-draw-arrows-coverage.test.ts +1 -1
  98. package/src/__tests__/ascii-draw-arrows-single-point-path.test.ts +12 -5
  99. package/src/__tests__/ascii-draw-bundles.test.ts +5 -5
  100. package/src/__tests__/ascii-edge-bundling-rank-violation-454.test.ts +1 -1
  101. package/src/__tests__/ascii-edge-bundling-routing.test.ts +9 -5
  102. package/src/__tests__/ascii-edge-cross-style-overlap.test.ts +10 -6
  103. package/src/__tests__/ascii-edge-ending-glyphs.test.ts +1 -1
  104. package/src/__tests__/ascii-edge-label-diagonal-fallback-418.test.ts +2 -2
  105. package/src/__tests__/ascii-edge-routing-fixes.test.ts +1 -1
  106. package/src/__tests__/ascii-edge-routing-single-point-path.test.ts +8 -4
  107. package/src/__tests__/ascii-edge-styles.test.ts +1 -1
  108. package/src/__tests__/ascii-emoji-cluster-width.test.ts +2 -2
  109. package/src/__tests__/ascii-er-box-occupancy.test.ts +1 -1
  110. package/src/__tests__/ascii-er-cardinality.test.ts +1 -1
  111. package/src/__tests__/ascii-er-corner-glyphs.test.ts +1 -1
  112. package/src/__tests__/ascii-er-jog-stray-line.test.ts +1 -1
  113. package/src/__tests__/ascii-er-label-padding.test.ts +1 -1
  114. package/src/__tests__/ascii-er-padding.test.ts +1 -1
  115. package/src/__tests__/ascii-er-relationship-label-corruption-350.test.ts +1 -1
  116. package/src/__tests__/ascii-er-relationship-overwrite.test.ts +1 -1
  117. package/src/__tests__/ascii-er-stray-connectors.test.ts +7 -4
  118. package/src/__tests__/ascii-er-unrelated-stem-separation-411.test.ts +1 -1
  119. package/src/__tests__/ascii-er-vertical-one-marker.test.ts +1 -1
  120. package/src/__tests__/ascii-grid-deep-chain.test.ts +4 -4
  121. package/src/__tests__/ascii-hyperlinks.test.ts +9 -6
  122. package/src/__tests__/ascii-label-line-terminal-fallback.test.ts +8 -4
  123. package/src/__tests__/ascii-lane-search.test.ts +1 -1
  124. package/src/__tests__/ascii-multibox-cjk-width.test.ts +1 -1
  125. package/src/__tests__/ascii-multiline.test.ts +6 -3
  126. package/src/__tests__/ascii-nested-subgraph-sibling-order-444.test.ts +8 -5
  127. package/src/__tests__/ascii-package-boundary.test.ts +47 -37
  128. package/src/__tests__/ascii-padding-edge-cases.test.ts +1 -1
  129. package/src/__tests__/ascii-parallel-edges-329.test.ts +8 -5
  130. package/src/__tests__/ascii-pathfinder-route-edge.test.ts +14 -4
  131. package/src/__tests__/ascii-reverse-direction-edges-629.test.ts +9 -5
  132. package/src/__tests__/ascii-sequence-alt-else-label.test.ts +1 -1
  133. package/src/__tests__/ascii-sequence-block-wall-clearance.test.ts +1 -1
  134. package/src/__tests__/ascii-sequence-box-group.test.ts +1 -1
  135. package/src/__tests__/ascii-sequence-cjk-width.test.ts +1 -1
  136. package/src/__tests__/ascii-sequence-create-destroy.test.ts +1 -1
  137. package/src/__tests__/ascii-sequence-form-invariants.test.ts +48 -50
  138. package/src/__tests__/ascii-sequence-mermaid-parity.test.ts +1 -1
  139. package/src/__tests__/ascii-sequence-notes.test.ts +1 -1
  140. package/src/__tests__/ascii-sequence-padding.test.ts +1 -1
  141. package/src/__tests__/ascii-sequence-self-arrow.test.ts +1 -1
  142. package/src/__tests__/ascii-shape-diamond.test.ts +3 -3
  143. package/src/__tests__/ascii-shape-rectangle.test.ts +5 -5
  144. package/src/__tests__/ascii-shape-rounded.test.ts +3 -3
  145. package/src/__tests__/ascii-shapes-circle.test.ts +3 -3
  146. package/src/__tests__/ascii-shapes-hexagon.test.ts +3 -3
  147. package/src/__tests__/ascii-shapes-special.test.ts +10 -5
  148. package/src/__tests__/ascii-shapes-stadium.test.ts +3 -3
  149. package/src/__tests__/ascii-shapes-state.test.ts +15 -5
  150. package/src/__tests__/ascii-state-bidirectional-label-swap-530.test.ts +1 -1
  151. package/src/__tests__/ascii-subgraph-bbox.test.ts +8 -4
  152. package/src/__tests__/ascii-subgraph-direction-honored-445.test.ts +1 -1
  153. package/src/__tests__/ascii-subgraph-label-border-clip.test.ts +88 -25
  154. package/src/__tests__/ascii-subgraph-later-edgeless-301.test.ts +8 -4
  155. package/src/__tests__/ascii-subgraph-title-padding.test.ts +1 -1
  156. package/src/__tests__/ascii-territory-unit.test.ts +2 -2
  157. package/src/__tests__/ascii-validate.test.ts +1 -1
  158. package/src/__tests__/ascii.test.ts +5 -2
  159. package/src/__tests__/box-color.test.ts +1 -1
  160. package/src/__tests__/class-arrow-directions.test.ts +1 -1
  161. package/src/__tests__/class-click-interactions.test.ts +3 -6
  162. package/src/__tests__/class-integration.test.ts +1 -1
  163. package/src/__tests__/class-notes.test.ts +3 -3
  164. package/src/__tests__/class-parser-error-messages.test.ts +162 -0
  165. package/src/__tests__/class-parser.test.ts +6 -6
  166. package/src/__tests__/class-styling.test.ts +2 -2
  167. package/src/__tests__/cli-render.test.ts +16 -1
  168. package/src/__tests__/direction-override.test.ts +1 -1
  169. package/src/__tests__/draw-lines.test.ts +2 -2
  170. package/src/__tests__/edge-cell-styles.test.ts +5 -2
  171. package/src/__tests__/elk-layout-cache.test.ts +6 -4
  172. package/src/__tests__/er-click-unsupported.test.ts +5 -8
  173. package/src/__tests__/er-parser-error-messages.test.ts +82 -0
  174. package/src/__tests__/er-parser.test.ts +3 -6
  175. package/src/__tests__/expanded-shapes.test.ts +1 -1
  176. package/src/__tests__/grid-occupancy.test.ts +1 -1
  177. package/src/__tests__/mcp-check-sequence-activations-tool.test.ts +1 -1
  178. package/src/__tests__/mcp-fix-sequence-activations-tool.test.ts +134 -0
  179. package/src/__tests__/mcp-render-ascii-tool.test.ts +5 -4
  180. package/src/__tests__/mcp-render-svg-theme-guard.test.ts +3 -3
  181. package/src/__tests__/mcp-render-svg-tool.test.ts +1 -1
  182. package/src/__tests__/mcp-server.test.ts +30 -1
  183. package/src/__tests__/multiline-labels.test.ts +29 -18
  184. package/src/__tests__/parser.test.ts +117 -5
  185. package/src/__tests__/pathfinder.test.ts +11 -4
  186. package/src/__tests__/render-options-overrides.test.ts +28 -21
  187. package/src/__tests__/render-options-per-type.test.ts +13 -9
  188. package/src/__tests__/resolve-colors.test.ts +1 -1
  189. package/src/__tests__/self-loop-edges.test.ts +112 -0
  190. package/src/__tests__/sequence-activation-check.test.ts +7 -8
  191. package/src/__tests__/sequence-activation-fix.test.ts +91 -0
  192. package/src/__tests__/sequence-layout.test.ts +4 -7
  193. package/src/__tests__/sequence-parser-syntax-errors.test.ts +179 -0
  194. package/src/__tests__/sequence-parser.test.ts +3 -6
  195. package/src/__tests__/statements.test.ts +53 -35
  196. package/src/__tests__/testdata/ascii/subgraph_direction_override.txt +21 -21
  197. package/src/__tests__/theme-palette-contrast.test.ts +84 -0
  198. package/src/__tests__/workspace-package-boundaries.test.ts +199 -25
  199. package/src/__tests__/xychart-ascii.test.ts +1 -1
  200. package/src/__tests__/xychart-colors.test.ts +3 -2
  201. package/src/__tests__/xychart-layout.test.ts +1 -1
  202. package/src/__tests__/xychart-parser-errors.test.ts +95 -0
  203. package/src/browser.ts +8 -2
  204. package/src/cli/mcp.ts +1 -1
  205. package/src/cli/render.ts +59 -25
  206. package/src/cli/web.ts +1 -1
  207. package/src/diagram-registry.ts +190 -25
  208. package/src/index.ts +34 -131
  209. package/src/parser.ts +102 -40
  210. /package/{src/ascii → packages/ascii-renderer/src}/ansi.ts +0 -0
  211. /package/{src/ascii → packages/ascii-renderer/src}/canvas.ts +0 -0
  212. /package/{src/ascii → packages/ascii-renderer/src}/converter.ts +0 -0
  213. /package/{src/ascii → packages/ascii-renderer/src}/coords.ts +0 -0
  214. /package/{src/ascii → packages/ascii-renderer/src}/display-width.ts +0 -0
  215. /package/{src/ascii → packages/ascii-renderer/src}/draw-arrows.ts +0 -0
  216. /package/{src/ascii → packages/ascii-renderer/src}/draw-boxes.ts +0 -0
  217. /package/{src/ascii → packages/ascii-renderer/src}/draw-bundles.ts +0 -0
  218. /package/{src/ascii → packages/ascii-renderer/src}/draw-lines.ts +0 -0
  219. /package/{src/ascii → packages/ascii-renderer/src}/draw-subgraphs.ts +0 -0
  220. /package/{src/ascii → packages/ascii-renderer/src}/draw.ts +0 -0
  221. /package/{src/ascii → packages/ascii-renderer/src}/edge-bundling.ts +0 -0
  222. /package/{src/ascii → packages/ascii-renderer/src}/edge-cell-styles.ts +0 -0
  223. /package/{src/ascii → packages/ascii-renderer/src}/edge-routing.ts +0 -0
  224. /package/{src/ascii → packages/ascii-renderer/src}/grid-occupancy.ts +0 -0
  225. /package/{src/ascii → packages/ascii-renderer/src}/hyperlinks.ts +0 -0
  226. /package/{src/ascii → packages/ascii-renderer/src}/lane-search.ts +0 -0
  227. /package/{src/ascii → packages/ascii-renderer/src}/multiline-utils.ts +0 -0
  228. /package/{src/ascii → packages/ascii-renderer/src}/pathfinder.ts +0 -0
  229. /package/{src/ascii → packages/ascii-renderer/src}/shapes/circle.ts +0 -0
  230. /package/{src/ascii → packages/ascii-renderer/src}/shapes/corners.ts +0 -0
  231. /package/{src/ascii → packages/ascii-renderer/src}/shapes/diamond.ts +0 -0
  232. /package/{src/ascii → packages/ascii-renderer/src}/shapes/hexagon.ts +0 -0
  233. /package/{src/ascii → packages/ascii-renderer/src}/shapes/index.ts +0 -0
  234. /package/{src/ascii → packages/ascii-renderer/src}/shapes/rectangle.ts +0 -0
  235. /package/{src/ascii → packages/ascii-renderer/src}/shapes/rounded.ts +0 -0
  236. /package/{src/ascii → packages/ascii-renderer/src}/shapes/special.ts +0 -0
  237. /package/{src/ascii → packages/ascii-renderer/src}/shapes/stadium.ts +0 -0
  238. /package/{src/ascii → packages/ascii-renderer/src}/shapes/state.ts +0 -0
  239. /package/{src/ascii → packages/ascii-renderer/src}/shapes/types.ts +0 -0
  240. /package/{src/ascii → packages/ascii-renderer/src}/territory.ts +0 -0
  241. /package/{src/ascii → packages/ascii-renderer/src}/types.ts +0 -0
  242. /package/{src/ascii → packages/ascii-renderer/src}/validate.ts +0 -0
  243. /package/{src/mcp → packages/mcp/src}/index.ts +0 -0
  244. /package/{src → packages/mermaid-parser/src}/class/format.ts +0 -0
  245. /package/{src → packages/mermaid-parser/src}/class/types.ts +0 -0
  246. /package/{src → packages/mermaid-parser/src}/er/types.ts +0 -0
  247. /package/{src → packages/mermaid-parser/src}/expanded-shapes.ts +0 -0
  248. /package/{src → packages/mermaid-parser/src}/sequence/box-color.ts +0 -0
  249. /package/{src → packages/mermaid-parser/src}/sequence/types.ts +0 -0
  250. /package/{src → packages/mermaid-parser/src}/xychart/colors.ts +0 -0
  251. /package/{src → packages/mermaid-parser/src}/xychart/types.ts +0 -0
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Craft Docs
4
+ Copyright (c) 2026 Dustin Fadler
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -5,11 +5,12 @@
5
5
  // mechanical sequence-diagram semantic check, up as Model Context Protocol
6
6
  // tools. No rendering or checking logic lives here — see src/mcp/tools/*.ts
7
7
  // for the thin per-tool adapters, src/index.ts / src/ascii/index.ts for the
8
- // actual renderers, and src/sequence/activation-check.ts for the check.
8
+ // actual renderers, and packages/mermaid-parser/src/sequence/activation-check.ts
9
+ // for the check.
9
10
  // ============================================================================
10
11
 
11
12
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
12
- import { getPackageVersion } from '../package-info.ts'
13
+ import { getPackageVersion } from '../../../src/package-info.ts'
13
14
  import { renderSvgInputShape, renderSvgHandler } from './tools/render-svg.ts'
14
15
  import {
15
16
  renderAsciiInputShape,
@@ -19,6 +20,10 @@ import {
19
20
  checkSequenceActivationsInputShape,
20
21
  checkSequenceActivationsHandler,
21
22
  } from './tools/check-sequence-activations.ts'
23
+ import {
24
+ fixSequenceActivationsInputShape,
25
+ fixSequenceActivationsHandler,
26
+ } from './tools/fix-sequence-activations.ts'
22
27
 
23
28
  /**
24
29
  * Build a zombie-mermaid MCP server exposing `render_mermaid_svg`,
@@ -99,5 +104,32 @@ export function createMcpServer(): McpServer {
99
104
  checkSequenceActivationsHandler,
100
105
  )
101
106
 
107
+ server.registerTool(
108
+ 'fix_mermaid_sequence_activations',
109
+ {
110
+ title: 'Fix Mermaid sequence diagram activation balance',
111
+ description:
112
+ 'Check a Mermaid sequence diagram for activation/deactivation ' +
113
+ 'imbalance and, where mechanically safe, return a corrected ' +
114
+ 'version: a dangling "activate X" (or "+" shorthand) with no ' +
115
+ 'matching "deactivate X" gets one appended. An unmatched ' +
116
+ '"deactivate X" with nothing open is reported but not auto-fixed ' +
117
+ '(no safe, unambiguous edit exists without source-position ' +
118
+ 'tracking). Returns a JSON report ({ ok, fixedDiagram, ' +
119
+ 'fixesApplied, remainingIssues }) rather than rendering anything. ' +
120
+ 'Mechanical and deterministic — no LLM judgment involved. Only ' +
121
+ 'sequence diagrams are supported.',
122
+ inputSchema: fixSequenceActivationsInputShape,
123
+ annotations: {
124
+ title: 'Fix Mermaid sequence diagram activation balance',
125
+ readOnlyHint: true,
126
+ destructiveHint: false,
127
+ idempotentHint: true,
128
+ openWorldHint: false,
129
+ },
130
+ },
131
+ fixSequenceActivationsHandler,
132
+ )
133
+
102
134
  return server
103
135
  }
@@ -5,9 +5,10 @@
5
5
  // render tools: every "activate X" (or "+" arrow shorthand) in a Mermaid
6
6
  // sequence diagram must be closed by a matching "deactivate X" ("-"
7
7
  // shorthand) before the diagram ends. No LLM judge involved — see
8
- // src/sequence/activation-check.ts for the actual check, which reuses the
9
- // same activation-stack bookkeeping src/sequence/layout.ts already runs to
10
- // *draw* activation bars.
8
+ // packages/mermaid-parser/src/sequence/activation-check.ts for the actual
9
+ // check, which reuses the same activation-stack bookkeeping
10
+ // packages/svg-renderer/src/sequence/layout.ts already runs to *draw*
11
+ // activation bars.
11
12
  //
12
13
  // Why this tool, and why it isn't duplicating agentic-mermaid's `verify`
13
14
  // tool (github.com/adewale/agentic-mermaid): that tool's own docs describe
@@ -22,8 +23,10 @@
22
23
  import { z } from 'zod'
23
24
  import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'
24
25
  import { detectDiagramType, splitStatements } from '@zombie-mermaid/core'
25
- import { parseSequenceDiagram } from '../../sequence/parser.ts'
26
- import { checkActivationBalance } from '../../sequence/activation-check.ts'
26
+ import {
27
+ parseSequenceDiagram,
28
+ checkActivationBalance,
29
+ } from '@zombie-mermaid/mermaid-parser'
27
30
 
28
31
  export const checkSequenceActivationsInputShape = {
29
32
  diagram: z
@@ -0,0 +1,77 @@
1
+ // ============================================================================
2
+ // zombie-mermaid MCP server — `fix_mermaid_sequence_activations` tool
3
+ //
4
+ // The "optionally proposes a fix" half of issue #539, complementing
5
+ // `check_mermaid_sequence_activations` (which only reports issues). Reuses
6
+ // packages/mermaid-parser/src/sequence/activation-fix.ts, which — see that
7
+ // file's header — only auto-fixes DANGLING_ACTIVATION (a mechanically safe,
8
+ // unambiguous append); UNMATCHED_DEACTIVATION comes back as a remaining
9
+ // issue for a human (or a future LLM-based layer) to resolve rather than
10
+ // risk an incorrect text edit.
11
+ // ============================================================================
12
+
13
+ import { z } from 'zod'
14
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'
15
+ import { detectDiagramType } from '@zombie-mermaid/core'
16
+ import { fixActivationBalance } from '@zombie-mermaid/mermaid-parser'
17
+
18
+ export const fixSequenceActivationsInputShape = {
19
+ diagram: z
20
+ .string()
21
+ .min(1, 'diagram must not be empty')
22
+ .describe(
23
+ 'Mermaid sequence diagram source text, e.g. "sequenceDiagram\\n ' +
24
+ 'activate A\\n A->>B: hi". Must start with "sequenceDiagram" — ' +
25
+ 'this tool does not check other diagram types.',
26
+ ),
27
+ }
28
+
29
+ export interface FixSequenceActivationsToolArgs {
30
+ diagram: string
31
+ }
32
+
33
+ /**
34
+ * MCP tool handler for `fix_mermaid_sequence_activations`. Parses the given
35
+ * source as a Mermaid sequence diagram, checks activation/deactivation
36
+ * balance, and returns a structured JSON result: `ok`, the (possibly
37
+ * unchanged) `fixedDiagram`, `fixesApplied` (human-readable descriptions),
38
+ * and any `remainingIssues` that couldn't be auto-fixed.
39
+ *
40
+ * Returns an MCP tool error (`isError: true`, not a thrown exception) both
41
+ * for invalid Mermaid syntax and for a non-sequence diagram, matching
42
+ * `check-sequence-activations.ts`'s error handling.
43
+ */
44
+ export function fixSequenceActivationsHandler(
45
+ input: FixSequenceActivationsToolArgs,
46
+ ): CallToolResult {
47
+ try {
48
+ const diagramType = detectDiagramType(input.diagram)
49
+ if (diagramType !== 'sequence') {
50
+ return {
51
+ isError: true,
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text:
56
+ 'This tool only fixes sequence diagrams (source must start ' +
57
+ `with "sequenceDiagram"); detected diagram type: "${diagramType}".`,
58
+ },
59
+ ],
60
+ }
61
+ }
62
+ const result = fixActivationBalance(input.diagram)
63
+ return {
64
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
65
+ }
66
+ } catch (err) {
67
+ return {
68
+ isError: true,
69
+ content: [
70
+ {
71
+ type: 'text',
72
+ text: `Failed to fix diagram activations: ${err instanceof Error ? err.message : String(err)}`,
73
+ },
74
+ ],
75
+ }
76
+ }
77
+ }
@@ -8,8 +8,8 @@
8
8
 
9
9
  import { z } from 'zod'
10
10
  import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'
11
- import { renderMermaidASCII } from '../../ascii/index.ts'
12
- import type { AsciiRenderOptions } from '../../ascii/index.ts'
11
+ import { renderMermaidASCII } from '@zombie-mermaid/ascii-renderer'
12
+ import type { AsciiRenderOptions } from '@zombie-mermaid/ascii-renderer'
13
13
 
14
14
  export const renderAsciiInputShape = {
15
15
  diagram: z
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { z } from 'zod'
10
10
  import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'
11
- import { renderMermaidSVG } from '../../index.ts'
11
+ import { renderMermaidSVG } from '../../../../src/index.ts'
12
12
  import { THEMES } from '@zombie-mermaid/core'
13
13
  import type { DiagramColors } from '@zombie-mermaid/core'
14
14
 
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Craft Docs
4
+ Copyright (c) 2026 Dustin Fadler
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -14,6 +14,7 @@ import {
14
14
  tryApplyClassDef,
15
15
  tryApplyCssClass,
16
16
  tryApplyStyleStatement,
17
+ type Statement,
17
18
  } from '@zombie-mermaid/core'
18
19
 
19
20
  // ============================================================================
@@ -39,6 +40,27 @@ import {
39
40
  // note "text" / note for Animal "line1\nline2"
40
41
  // ============================================================================
41
42
 
43
+ /**
44
+ * The set of relationship-arrow tokens `parseRelationship` recognizes,
45
+ * shared with the "does this line even look like a relationship attempt"
46
+ * check below so the two can't drift apart. Order matters for regex
47
+ * alternation (longer/more-specific tokens like `--|>` must be tried before
48
+ * the bare `--` fallback).
49
+ */
50
+ const RELATIONSHIP_ARROW_SOURCE =
51
+ '<\\|--|<\\|\\.\\.|\\*--|o--|-->|--\\*|--o|--\\|>|\\.\\.>|\\.\\.\\|>|<--|<\\.\\.?|--'
52
+
53
+ /**
54
+ * Matches a line that *contains* a relationship-arrow token somewhere, even
55
+ * if the overall shape (FROM/TO, cardinalities) doesn't parse. Used to
56
+ * scope the "malformed relationship" error (issue #761) to lines that
57
+ * already look like an attempt at this construct — mirroring the same
58
+ * "attempt, then validate" pattern #722 used for the ER and xychart-beta
59
+ * parsers, so a genuinely unrelated line (no arrow at all) still falls
60
+ * through silently rather than throwing on totally unrecognized syntax.
61
+ */
62
+ const RELATIONSHIP_ARROW_MARKER = new RegExp(RELATIONSHIP_ARROW_SOURCE)
63
+
42
64
  /**
43
65
  * Parse a Mermaid class diagram.
44
66
  * Expects the first line to be "classDiagram".
@@ -55,7 +77,7 @@ import {
55
77
  // `noUncheckedIndexedAccess` can't see either guarantee, but removing the
56
78
  // `!` would only replace a proven-safe assertion with an unreachable guard.
57
79
  // Left as-is; no behavior change.
58
- export function parseClassDiagram(lines: string[]): ClassDiagram {
80
+ export function parseClassDiagram(lines: Statement[]): ClassDiagram {
59
81
  const diagram: ClassDiagram = {
60
82
  classes: [],
61
83
  relationships: [],
@@ -74,9 +96,14 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
74
96
  // Track class body parsing
75
97
  let currentClass: ClassNode | null = null
76
98
  let braceDepth = 0
99
+ // Line the currently-open class body started on, for the unclosed-body
100
+ // error below (issue #761) — `currentClass`/`braceDepth` alone don't
101
+ // carry position.
102
+ let openClassLine: number | undefined
77
103
 
78
104
  for (let i = 1; i < lines.length; i++) {
79
- const line = lines[i]!
105
+ const stmt = lines[i]!
106
+ const line = stmt.text
80
107
 
81
108
  // --- Inside a class body block ---
82
109
  if (currentClass && braceDepth > 0) {
@@ -84,6 +111,7 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
84
111
  braceDepth--
85
112
  if (braceDepth === 0) {
86
113
  currentClass = null
114
+ openClassLine = undefined
87
115
  }
88
116
  continue
89
117
  }
@@ -95,8 +123,18 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
95
123
  continue
96
124
  }
97
125
 
126
+ // A line that starts with `<<` but doesn't match the full
127
+ // `<<name>>` shape is an attempted annotation with broken syntax
128
+ // (e.g. a missing closing `>>`) rather than a member — surface that
129
+ // instead of silently mis-parsing it as a member named "<<foo" (#761).
130
+ if (line.startsWith('<<')) {
131
+ throw new Error(
132
+ `Line ${stmt.line}: Malformed class annotation "${line}" — expected "<<name>>" (e.g. "<<interface>>").`,
133
+ )
134
+ }
135
+
98
136
  // Parse member: visibility, name, type, optional parens for method
99
- addMember(currentClass, line)
137
+ addMember(currentClass, line, stmt.line)
100
138
  continue
101
139
  }
102
140
 
@@ -155,6 +193,7 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
155
193
  const id = declareClass(classBlockMatch[1]!, classBlockMatch[2])
156
194
  currentClass = classMap.get(id) ?? null
157
195
  braceDepth = 1
196
+ openClassLine = stmt.line
158
197
  continue
159
198
  }
160
199
 
@@ -177,8 +216,14 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
177
216
  const annotMatch = body.match(/^<<(\w+)>>$/)
178
217
  if (cls && annotMatch) {
179
218
  cls.annotation = annotMatch[1]!
219
+ } else if (cls && body.startsWith('<<')) {
220
+ // Same broken-annotation-attempt case as the multi-line body
221
+ // branch above, just on the single-line form (#761).
222
+ throw new Error(
223
+ `Line ${stmt.line}: Malformed class annotation "${body}" — expected "<<name>>" (e.g. "<<interface>>").`,
224
+ )
180
225
  } else if (cls && body) {
181
- addMember(cls, body)
226
+ addMember(cls, body, stmt.line)
182
227
  }
183
228
  continue
184
229
  }
@@ -189,7 +234,7 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
189
234
  // Make sure this isn't a relationship line (those have arrows)
190
235
  const rest = inlineAttrMatch[2]!
191
236
  if (!rest.match(/<\|--|--|\*--|o--|-->|\.\.>|\.\.\|>/)) {
192
- addMember(ensureClass(classMap, inlineAttrMatch[1]!), rest)
237
+ addMember(ensureClass(classMap, inlineAttrMatch[1]!), rest, stmt.line)
193
238
  continue
194
239
  }
195
240
  }
@@ -209,6 +254,25 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
209
254
  diagram.relationships.push(rel)
210
255
  continue
211
256
  }
257
+
258
+ // A line containing a relationship-arrow token that still didn't parse
259
+ // above is a malformed/dangling relationship attempt — e.g. "Animal
260
+ // <|--" with no target, or an unsupported arrow shape — rather than an
261
+ // unrelated line that merely falls through. Scoped to lines that
262
+ // already look like an attempt (same "attempt, then validate" pattern
263
+ // #722 used for ER/xychart-beta) so genuinely unrecognized syntax with
264
+ // no arrow at all keeps falling through silently (#761).
265
+ if (RELATIONSHIP_ARROW_MARKER.test(line)) {
266
+ throw new Error(
267
+ `Line ${stmt.line}: Malformed class-diagram relationship "${line}". Expected "FROM ARROW TO" (optionally with cardinalities and a ": label"), e.g. "Animal <|-- Dog" or 'A "1" --> "*" B : label'. ARROW must be one of <|--, <|.., *--, o--, -->, --*, --o, --|>, ..>, ..|>, <--, <.., or --.`,
268
+ )
269
+ }
270
+ }
271
+
272
+ if (currentClass !== null) {
273
+ throw new Error(
274
+ `Line ${openClassLine}: Unclosed class body for "${currentClass.id}" — expected a closing "}" before the diagram ends.`,
275
+ )
212
276
  }
213
277
 
214
278
  diagram.classes = [...classMap.values()]
@@ -258,8 +322,8 @@ export function parseClassDiagram(lines: string[]): ClassDiagram {
258
322
  }
259
323
 
260
324
  /** Parse one member line and file it under the class's attributes or methods. */
261
- function addMember(cls: ClassNode, line: string): void {
262
- const member = parseMember(line)
325
+ function addMember(cls: ClassNode, line: string, lineNumber: number): void {
326
+ const member = parseMember(line, lineNumber)
263
327
  if (!member) return
264
328
  if (member.isMethod) {
265
329
  cls.methods.push(member.member)
@@ -351,6 +415,7 @@ export function parseGenericTypes(input: string): string {
351
415
  /** Parse a class member line (attribute or method) */
352
416
  function parseMember(
353
417
  line: string,
418
+ lineNumber: number,
354
419
  ): { member: ClassMember; isMethod: boolean } | null {
355
420
  const trimmed = line.trim().replace(/;$/, '')
356
421
  if (!trimmed) return null
@@ -369,6 +434,17 @@ function parseMember(
369
434
  rest = rest.slice(1).trim()
370
435
  }
371
436
 
437
+ // An attempted method signature with an opening "(" but no closing ")"
438
+ // at all can't be a genuine attribute either (an attribute name/type
439
+ // never legitimately contains a bare, unclosed paren) — surface it
440
+ // instead of silently parsing "eat(void" as a member literally named
441
+ // that (#761).
442
+ if (rest.includes('(') && !rest.includes(')')) {
443
+ throw new Error(
444
+ `Line ${lineNumber}: Malformed class member "${trimmed}" — unclosed "(" in a method signature. Expected e.g. "+eat() void" or "+eat(Food f) void".`,
445
+ )
446
+ }
447
+
372
448
  // Mermaid renders `List~Observer~` as `List<Observer>` (its own
373
449
  // `parseGenericTypes`). It's applied per field below — name, params and
374
450
  // return type separately, the way mermaid's ClassMember does — rather
@@ -440,7 +516,9 @@ function parseRelationship(line: string): ClassRelationship | null {
440
516
  // label separator that follows can't swallow it as a label of `::style`;
441
517
  // it's re-joined onto the id here and split off again by the caller.
442
518
  const match = line.match(
443
- /^(\S+?)\s+(?:"([^"]*?)"\s+)?(<\|--|<\|\.\.|\*--|o--|-->|--\*|--o|--\|>|\.\.>|\.\.\|>|<--|<\.\.?|--)\s+(?:"([^"]*?)"\s+)?(\S+?)(?::::([\w][\w-]*))?(?:\s*:\s*(.+))?$/,
519
+ new RegExp(
520
+ `^(\\S+?)\\s+(?:"([^"]*?)"\\s+)?(${RELATIONSHIP_ARROW_SOURCE})\\s+(?:"([^"]*?)"\\s+)?(\\S+?)(?::::([\\w][\\w-]*))?(?:\\s*:\\s*(.+))?$`,
521
+ ),
444
522
  )
445
523
  if (!match) return null
446
524
 
@@ -5,8 +5,11 @@ import type {
5
5
  ErRelationship,
6
6
  Cardinality,
7
7
  } from './types.ts'
8
- import { normalizeBrTags } from '@zombie-mermaid/core'
9
- import { toDirection } from '../parser.ts'
8
+ import {
9
+ normalizeBrTags,
10
+ toDirection,
11
+ type Statement,
12
+ } from '@zombie-mermaid/core'
10
13
 
11
14
  // ============================================================================
12
15
  // ER diagram parser
@@ -49,7 +52,7 @@ import { toDirection } from '../parser.ts'
49
52
  // concern from these `!`s) — `noUncheckedIndexedAccess` can't see either
50
53
  // guarantee, but removing the `!` would only replace a proven-safe
51
54
  // assertion with an unreachable guard. Left as-is; no behavior change.
52
- export function parseErDiagram(lines: string[]): ErDiagram {
55
+ export function parseErDiagram(lines: Statement[]): ErDiagram {
53
56
  const diagram: ErDiagram = {
54
57
  entities: [],
55
58
  relationships: [],
@@ -61,7 +64,8 @@ export function parseErDiagram(lines: string[]): ErDiagram {
61
64
  let currentEntity: ErEntity | null = null
62
65
 
63
66
  for (let i = 1; i < lines.length; i++) {
64
- const line = lines[i]!
67
+ const stmt = lines[i]!
68
+ const line = stmt.text
65
69
 
66
70
  // --- Inside entity body ---
67
71
  if (currentEntity) {
@@ -121,7 +125,7 @@ export function parseErDiagram(lines: string[]): ErDiagram {
121
125
  }
122
126
 
123
127
  // --- Relationship: `ENTITY1 cardinality1--cardinality2 ENTITY2 : label` ---
124
- const rel = parseRelationshipLine(line)
128
+ const rel = parseRelationshipLine(line, stmt.line)
125
129
  if (rel) {
126
130
  // Ensure both entities exist
127
131
  ensureEntity(entityMap, rel.entity1)
@@ -197,33 +201,62 @@ function parseAttribute(line: string): ErAttribute | null {
197
201
  *
198
202
  * Full pattern example: CUSTOMER ||--o{ ORDER : places
199
203
  */
200
- function parseRelationshipLine(line: string): ErRelationship | null {
201
- // Match: ENTITY1 <cardinality_and_line> ENTITY2 : label
202
- const match = line.match(
203
- /^(\S+)\s+([|o}{]+(?:--|\.\.)[|o}{]+)\s+(\S+)\s*:\s*(.+)$/,
204
+ function parseRelationshipLine(
205
+ line: string,
206
+ lineNumber: number,
207
+ ): ErRelationship | null {
208
+ // Loosely match a line shaped like a relationship attempt: two bare
209
+ // tokens flanking a `--`/`..`-based marker, with an optional `: label`.
210
+ // A line with no such marker at all doesn't look like a relationship
211
+ // attempt and falls through silently (returns null), same as before —
212
+ // that part of the parser's leniency is unchanged.
213
+ //
214
+ // Everything that *does* match this shape is validated below and either
215
+ // returns a fully-parsed relationship or throws an actionable error.
216
+ // Before this pass, an invalid cardinality token or a missing/empty
217
+ // label silently dropped the *entire* line (both entities included)
218
+ // with zero indication anything was wrong — see issue #541 (parser
219
+ // error-message quality audit — this parser had zero throw sites before
220
+ // this pass).
221
+ const attempt = line.match(
222
+ /^(\S+)\s+(\S*(?:--|\.\.)\S*)\s+(\S+)\s*(?::\s*(.*))?$/,
204
223
  )
205
- if (!match) return null
224
+ if (!attempt) return null
206
225
 
207
- const entity1 = match[1]!
208
- const cardinalityStr = match[2]!
209
- const entity2 = match[3]!
210
- // Strip surrounding quotes if present, then normalize br tags
211
- const rawLabel = match[4]!.trim().replace(/^["']|["']$/g, '')
212
- const label = normalizeBrTags(rawLabel)
226
+ const entity1 = attempt[1]!
227
+ const cardinalityStr = attempt[2]!
228
+ const entity2 = attempt[3]!
229
+ const hasLabel = attempt[4] !== undefined
230
+ const rawLabel = attempt[4]?.trim() ?? ''
213
231
 
214
- // Split the cardinality string into left side, line style, right side
215
- const lineMatch = cardinalityStr.match(/^([|o}{]+)(--|\.\.?)([|o}{]+)$/)
216
- if (!lineMatch) return null
232
+ // Cardinality symbols on each side of the line style:
233
+ // Left side (entity1): || |o }| }o
234
+ // Line: -- (identifying) or .. (non-identifying)
235
+ // Right side (entity2): || o| |{ o{
236
+ // `shapeMatch` only confirms the token is built from crow's-foot
237
+ // characters around a line-style marker — `parseLeftCardinality`/
238
+ // `parseRightCardinality` still reject a shape match that isn't one of
239
+ // the four valid two-character combinations per side (e.g. a lone "|").
240
+ const shapeMatch = cardinalityStr.match(/^([|o}{]*)(--|\.\.?)([|o}{]*)$/)
241
+ const cardinality1 = shapeMatch ? parseLeftCardinality(shapeMatch[1]!) : null
242
+ const cardinality2 = shapeMatch ? parseRightCardinality(shapeMatch[3]!) : null
217
243
 
218
- const leftStr = lineMatch[1]!
219
- const lineStyle = lineMatch[2]!
220
- const rightStr = lineMatch[3]!
244
+ if (!cardinality1 || !cardinality2) {
245
+ throw new Error(
246
+ `Line ${lineNumber}: Invalid ER relationship cardinality "${cardinalityStr}" in "${line}". ` +
247
+ 'Left side must be one of ||, |o, }|, }o; right side must be one of ||, o|, |{, o{ (e.g. "||--o{").',
248
+ )
249
+ }
221
250
 
222
- const cardinality1 = parseLeftCardinality(leftStr)
223
- const cardinality2 = parseRightCardinality(rightStr)
224
- const identifying = lineStyle === '--'
251
+ if (!hasLabel || rawLabel.length === 0) {
252
+ throw new Error(
253
+ `Line ${lineNumber}: ER relationship "${entity1} ${cardinalityStr} ${entity2}" is missing a ": label" — expected e.g. "${entity1} ${cardinalityStr} ${entity2} : label".`,
254
+ )
255
+ }
225
256
 
226
- if (!cardinality1 || !cardinality2) return null
257
+ // Strip surrounding quotes if present, then normalize br tags.
258
+ const label = normalizeBrTags(rawLabel.replace(/^["']|["']$/g, ''))
259
+ const identifying = shapeMatch![2] === '--'
227
260
 
228
261
  return { entity1, entity2, cardinality1, cardinality2, label, identifying }
229
262
  }
@@ -0,0 +1,48 @@
1
+ // ============================================================================
2
+ // @zombie-mermaid/mermaid-parser — per-type diagram parsers
3
+ //
4
+ // Class, ER, sequence, and XY chart diagrams have no shared generic model
5
+ // the way flowcharts/state diagrams do (`MermaidGraph`, parsed by the
6
+ // umbrella's own `src/parser.ts`). Both `svg-renderer` and `ascii-renderer`
7
+ // import each type's parse function and types directly — confirmed by grep
8
+ // (zombie-mermaid#624, umbrella #620, `monorepo-conversion-scoping.md`
9
+ // finding 2) — so this package's public API is every per-type parse
10
+ // function plus its types, not a single generic entry point.
11
+ //
12
+ // Each of `src/class/`, `src/er/`, `src/sequence/`, `src/xychart/` used to
13
+ // mix this parser half (`parser.ts`, `types.ts`, and — per file, not
14
+ // per-half-pair, see the scoping doc's addendum correction 3 —
15
+ // `class/format.ts`, `sequence/box-color.ts`, `sequence/activation-check.ts`,
16
+ // `xychart/colors.ts`) with a renderer half (`layout.ts`, `renderer.ts`) in
17
+ // the same directory. The renderer half moved into
18
+ // `packages/svg-renderer/src/<type>/` instead — see that package's `index.ts`
19
+ // header for the reverse dependency this split introduces (`svg-renderer`
20
+ // depends on this package for the positioned-diagram types and a handful of
21
+ // parser-side helpers, an ordinary acyclic workspace shape per finding 2).
22
+ //
23
+ // This package depends only on `@zombie-mermaid/core` — verified: no file
24
+ // below imports `elkjs`, `@zombie-mermaid/svg-renderer`, or anything from
25
+ // the umbrella. `toDirection` moved here from the umbrella's `src/parser.ts`
26
+ // (alongside `isDirection`, already `core` since #625) specifically so
27
+ // `er/parser.ts` below could use it without importing the umbrella and
28
+ // creating a cycle — see `packages/core/src/direction.ts`'s header.
29
+ // ============================================================================
30
+
31
+ export * from './class/parser.ts'
32
+ export * from './class/types.ts'
33
+ export * from './class/format.ts'
34
+
35
+ export * from './er/parser.ts'
36
+ export * from './er/types.ts'
37
+
38
+ export * from './sequence/parser.ts'
39
+ export * from './sequence/types.ts'
40
+ export * from './sequence/box-color.ts'
41
+ export * from './sequence/activation-check.ts'
42
+ export * from './sequence/activation-fix.ts'
43
+
44
+ export * from './xychart/parser.ts'
45
+ export * from './xychart/types.ts'
46
+ export * from './xychart/colors.ts'
47
+
48
+ export * from './expanded-shapes.ts'
@@ -4,9 +4,10 @@
4
4
  // A mechanical, deterministic semantic check: every `activate X` (or the
5
5
  // `+` arrow shorthand) must be closed by a matching `deactivate X` (or the
6
6
  // `-` shorthand) before the diagram ends. This doesn't need an LLM judge —
7
- // it's the same activation-stack bookkeeping src/sequence/layout.ts already
8
- // runs to *draw* activation bars (see its `activationStacks` map), reused
9
- // here to *report* imbalance instead of silently rendering around it.
7
+ // it's the same activation-stack bookkeeping
8
+ // packages/svg-renderer/src/sequence/layout.ts already runs to *draw*
9
+ // activation bars (see its `activationStacks` map), reused here to *report*
10
+ // imbalance instead of silently rendering around it.
10
11
  //
11
12
  // Motivation (issue #539, split from #536): research on LLM-generated
12
13
  // Mermaid sequence diagrams found they fail mostly on activation handling