agentic-mermaid 0.1.1 → 0.1.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 (336) hide show
  1. package/CHANGELOG.md +144 -4
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/README.md +25 -32
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/agent-core.d.ts +463 -0
  6. package/dist/agent-core.js +397 -0
  7. package/dist/agent.d.ts +73 -1868
  8. package/dist/agent.js +336 -37325
  9. package/dist/agentic-mermaid-mcp.js +7 -38399
  10. package/dist/am.js +33632 -40445
  11. package/dist/chunk-4QECACIA.js +4702 -0
  12. package/dist/chunk-CDPKJ2BQ.js +37 -0
  13. package/dist/chunk-QKDLMOJJ.js +3487 -0
  14. package/dist/chunk-WI35L7IR.js +615 -0
  15. package/dist/chunk-WN3YDOBG.js +149 -0
  16. package/dist/chunk-ZYMMKQ3I.js +62637 -0
  17. package/dist/index-D54dqSdC.d.ts +6777 -0
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +310 -33014
  20. package/dist/mcp-cli-SBQSTJFC.js +17 -0
  21. package/docs/README.md +14 -6
  22. package/docs/schemas/style-spec.schema.json +1221 -30
  23. package/examples/styles/catalog.json +54 -0
  24. package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
  25. package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
  26. package/examples/styles/cupertino-prototype.mmd +10 -0
  27. package/examples/styles/cupertino-prototype.style.json +63 -0
  28. package/examples/styles/mid-century-report.style.json +2 -2
  29. package/examples/styles/star-chart-atlas.style.json +2 -1
  30. package/examples/styles/transit-route-map.style.json +2 -2
  31. package/examples/styles/vercel-inspired-prototype.mmd +6 -0
  32. package/examples/styles/vercel-inspired-prototype.style.json +87 -0
  33. package/package.json +68 -43
  34. package/server.json +2 -2
  35. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
  36. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
  37. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
  38. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
  39. package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
  40. package/AGENT_NATIVE.md +0 -607
  41. package/Instructions_for_agents.md +0 -89
  42. package/TODO.md +0 -684
  43. package/assets/hero.png +0 -0
  44. package/dist/index-wjRjbsP-.d.ts +0 -1102
  45. package/docs/agent-api-cookbook.md +0 -308
  46. package/docs/agent-mutation-policy.md +0 -104
  47. package/docs/agent-workflow-examples.md +0 -46
  48. package/docs/api.md +0 -211
  49. package/docs/ascii.md +0 -103
  50. package/docs/assets/improvements/box-start-connector.png +0 -0
  51. package/docs/assets/improvements/comment-dropped-lint.png +0 -0
  52. package/docs/assets/improvements/er-content-loss.png +0 -0
  53. package/docs/assets/improvements/fan-in-trunks.png +0 -0
  54. package/docs/assets/improvements/gantt-family.png +0 -0
  55. package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
  56. package/docs/assets/improvements/gantt-verify-seam.png +0 -0
  57. package/docs/assets/improvements/subgraph-container-edges.png +0 -0
  58. package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
  59. package/docs/assets/improvements/wrapper-init-directive.png +0 -0
  60. package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
  61. package/docs/assets/style-cookbook/mid-century-report.png +0 -0
  62. package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
  63. package/docs/assets/style-cookbook/transit-route-map.png +0 -0
  64. package/docs/comparison.md +0 -94
  65. package/docs/config.md +0 -105
  66. package/docs/contributing/adding-diagram-types.md +0 -144
  67. package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
  68. package/docs/contributing/diagram-family-citizenship.md +0 -82
  69. package/docs/contributing/harvesting-upstream-tests.md +0 -126
  70. package/docs/contributing/lessons-learned.md +0 -276
  71. package/docs/contributing/releasing.md +0 -82
  72. package/docs/contributing/visual-review-evidence.md +0 -53
  73. package/docs/custom-style-cookbook.md +0 -154
  74. package/docs/design/families/README.md +0 -26
  75. package/docs/design/families/architecture-beta.md +0 -48
  76. package/docs/design/families/flowchart-parser-conformance.md +0 -22
  77. package/docs/design/families/gantt-research.md +0 -137
  78. package/docs/design/families/gantt.md +0 -329
  79. package/docs/design/families/journey-agentic-cards-before.png +0 -0
  80. package/docs/design/families/journey-experience-curve-implementation.png +0 -0
  81. package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
  82. package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
  83. package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
  84. package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
  85. package/docs/design/families/journey-migration-parity.md +0 -439
  86. package/docs/design/families/journey-section-overlap-after.png +0 -0
  87. package/docs/design/families/journey-section-overlap-before.png +0 -0
  88. package/docs/design/families/journey-usage-research.md +0 -423
  89. package/docs/design/families/journey.md +0 -153
  90. package/docs/design/families/xychart.md +0 -85
  91. package/docs/design/system/README.md +0 -45
  92. package/docs/design/system/abstraction-audit.md +0 -224
  93. package/docs/design/system/abstraction-recommendations.md +0 -655
  94. package/docs/design/system/architecture.mmd +0 -29
  95. package/docs/design/system/architecture.svg +0 -137
  96. package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
  97. package/docs/design/system/layout-rubric.md +0 -138
  98. package/docs/design/system/route-contracts.md +0 -848
  99. package/docs/design/system/source-preservation-ladder.md +0 -52
  100. package/docs/design/system/styles-rollout.md +0 -216
  101. package/docs/design/system/ugly-layouts.md +0 -119
  102. package/docs/diagram-families.md +0 -193
  103. package/docs/features.md +0 -147
  104. package/docs/fork-differences.md +0 -130
  105. package/docs/getting-started.md +0 -175
  106. package/docs/issue-derived-test-cases.md +0 -156
  107. package/docs/layout-characterization/README.md +0 -245
  108. package/docs/layout-characterization/contact-sheet-families.md +0 -498
  109. package/docs/layout-characterization/contact-sheet.md +0 -638
  110. package/docs/layout-characterization/properties.md +0 -281
  111. package/docs/layout-characterization/visual-quality.md +0 -160
  112. package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
  113. package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
  114. package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
  115. package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
  116. package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
  117. package/docs/layout-characterization/visual-snapshots/journey.svg +0 -98
  118. package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
  119. package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
  120. package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
  121. package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
  122. package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
  123. package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
  124. package/docs/mcp-code-mode-rationale.md +0 -101
  125. package/docs/mcp-http-transport.md +0 -223
  126. package/docs/mermaid-layout-complaints.md +0 -837
  127. package/docs/mutation-testing.md +0 -206
  128. package/docs/project/divergences.md +0 -98
  129. package/docs/project/dogfooding-docs-strategy.md +0 -66
  130. package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
  131. package/docs/project/lessons-learned.md +0 -1019
  132. package/docs/project/remove-role-styling-plan.md +0 -176
  133. package/docs/quality.md +0 -215
  134. package/docs/react.md +0 -97
  135. package/docs/style-authoring.md +0 -133
  136. package/docs/testing-strategy.md +0 -335
  137. package/docs/theming.md +0 -162
  138. package/examples/agent-improve-auth-flow.ts +0 -206
  139. package/examples/agent-loop.ts +0 -53
  140. package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
  141. package/llms.txt +0 -104
  142. package/skill-evals/README.md +0 -77
  143. package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
  144. package/skill-evals/fixtures/class-payment/input.mmd +0 -4
  145. package/skill-evals/fixtures/er-orders/input.mmd +0 -10
  146. package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
  147. package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
  148. package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
  149. package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
  150. package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
  151. package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
  152. package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
  153. package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
  154. package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
  155. package/skill-evals/shared-benchmark.json +0 -510
  156. package/src/agent/analyze.ts +0 -157
  157. package/src/agent/apply.ts +0 -146
  158. package/src/agent/architecture-body.ts +0 -458
  159. package/src/agent/certificates.ts +0 -110
  160. package/src/agent/class-body.ts +0 -319
  161. package/src/agent/core.ts +0 -207
  162. package/src/agent/create.ts +0 -106
  163. package/src/agent/describe.ts +0 -368
  164. package/src/agent/er-body.ts +0 -224
  165. package/src/agent/facts.ts +0 -360
  166. package/src/agent/families-builtin.ts +0 -920
  167. package/src/agent/families.ts +0 -232
  168. package/src/agent/family-layouts.ts +0 -832
  169. package/src/agent/flowchart-body.ts +0 -372
  170. package/src/agent/flowchart-unsupported.ts +0 -243
  171. package/src/agent/font-coverage.ts +0 -288
  172. package/src/agent/gantt-body.ts +0 -495
  173. package/src/agent/index.ts +0 -10
  174. package/src/agent/journey-body.ts +0 -374
  175. package/src/agent/label-metrics.ts +0 -28
  176. package/src/agent/layout-to-rendered.ts +0 -63
  177. package/src/agent/mutate.ts +0 -97
  178. package/src/agent/mutation-ops.ts +0 -51
  179. package/src/agent/op-schema.ts +0 -443
  180. package/src/agent/parse.ts +0 -223
  181. package/src/agent/pie-body.ts +0 -270
  182. package/src/agent/png.ts +0 -171
  183. package/src/agent/quadrant-body.ts +0 -336
  184. package/src/agent/quality.ts +0 -363
  185. package/src/agent/readability-audit.ts +0 -92
  186. package/src/agent/rendered-route-audit.ts +0 -61
  187. package/src/agent/sequence-body.ts +0 -345
  188. package/src/agent/serialize.ts +0 -214
  189. package/src/agent/state-body.ts +0 -589
  190. package/src/agent/structural-count.ts +0 -150
  191. package/src/agent/timeline-body.ts +0 -280
  192. package/src/agent/trace-log.ts +0 -43
  193. package/src/agent/types.ts +0 -995
  194. package/src/agent/verify.ts +0 -603
  195. package/src/agent/xychart-body.ts +0 -472
  196. package/src/architecture/config.ts +0 -282
  197. package/src/architecture/layout.ts +0 -496
  198. package/src/architecture/parser.ts +0 -375
  199. package/src/architecture/renderer.ts +0 -611
  200. package/src/architecture/types.ts +0 -113
  201. package/src/ascii/ansi.ts +0 -423
  202. package/src/ascii/architecture.ts +0 -210
  203. package/src/ascii/canvas.ts +0 -443
  204. package/src/ascii/class-diagram.ts +0 -697
  205. package/src/ascii/converter.ts +0 -475
  206. package/src/ascii/draw.ts +0 -1693
  207. package/src/ascii/edge-bundling.ts +0 -328
  208. package/src/ascii/edge-routing.ts +0 -330
  209. package/src/ascii/er-diagram.ts +0 -439
  210. package/src/ascii/gantt.ts +0 -276
  211. package/src/ascii/grid.ts +0 -747
  212. package/src/ascii/index.ts +0 -196
  213. package/src/ascii/journey.ts +0 -169
  214. package/src/ascii/meta.ts +0 -244
  215. package/src/ascii/multiline-utils.ts +0 -80
  216. package/src/ascii/pathfinder.ts +0 -301
  217. package/src/ascii/pie.ts +0 -67
  218. package/src/ascii/quadrant.ts +0 -158
  219. package/src/ascii/reverse.ts +0 -216
  220. package/src/ascii/sequence.ts +0 -499
  221. package/src/ascii/shapes/circle.ts +0 -27
  222. package/src/ascii/shapes/corners.ts +0 -143
  223. package/src/ascii/shapes/diamond.ts +0 -27
  224. package/src/ascii/shapes/hexagon.ts +0 -27
  225. package/src/ascii/shapes/index.ts +0 -106
  226. package/src/ascii/shapes/rectangle.ts +0 -168
  227. package/src/ascii/shapes/rounded.ts +0 -27
  228. package/src/ascii/shapes/special.ts +0 -332
  229. package/src/ascii/shapes/stadium.ts +0 -110
  230. package/src/ascii/shapes/state.ts +0 -192
  231. package/src/ascii/shapes/types.ts +0 -73
  232. package/src/ascii/timeline.ts +0 -141
  233. package/src/ascii/types.ts +0 -312
  234. package/src/ascii/validate.ts +0 -120
  235. package/src/ascii/width.ts +0 -81
  236. package/src/ascii/wrap.ts +0 -131
  237. package/src/ascii/xychart.ts +0 -919
  238. package/src/browser.ts +0 -29
  239. package/src/class/layout.ts +0 -240
  240. package/src/class/parser.ts +0 -332
  241. package/src/class/renderer.ts +0 -638
  242. package/src/class/types.ts +0 -129
  243. package/src/cli/agent-instructions.ts +0 -1
  244. package/src/cli/am-bin.ts +0 -6
  245. package/src/cli/exit-codes.ts +0 -18
  246. package/src/cli/index.ts +0 -1132
  247. package/src/cli/init-agent.ts +0 -147
  248. package/src/cli/run-entrypoint.ts +0 -10
  249. package/src/color-resolver.ts +0 -152
  250. package/src/elk-instance.ts +0 -114
  251. package/src/er/layout.ts +0 -187
  252. package/src/er/parser.ts +0 -226
  253. package/src/er/renderer.ts +0 -792
  254. package/src/er/types.ts +0 -99
  255. package/src/family-rubric.ts +0 -425
  256. package/src/font-manifest.ts +0 -31
  257. package/src/gantt/layout.ts +0 -365
  258. package/src/gantt/parser.ts +0 -282
  259. package/src/gantt/pipeline.ts +0 -27
  260. package/src/gantt/renderer.ts +0 -414
  261. package/src/gantt/schedule.ts +0 -513
  262. package/src/gantt/types.ts +0 -255
  263. package/src/index.ts +0 -368
  264. package/src/journey/layout.ts +0 -554
  265. package/src/journey/parse-core.ts +0 -251
  266. package/src/journey/parser.ts +0 -101
  267. package/src/journey/renderer.ts +0 -917
  268. package/src/journey/types.ts +0 -144
  269. package/src/layout/geometry.ts +0 -182
  270. package/src/layout/pass.ts +0 -142
  271. package/src/layout/passes/index.ts +0 -3916
  272. package/src/layout-engine.ts +0 -1565
  273. package/src/layout-rubric.ts +0 -659
  274. package/src/mcp/artifacts.ts +0 -137
  275. package/src/mcp/dynamic-harness.ts +0 -31
  276. package/src/mcp/dynamic-modules.d.ts +0 -7
  277. package/src/mcp/facade.ts +0 -608
  278. package/src/mcp/harness-runtime.ts +0 -203
  279. package/src/mcp/hosted-server.ts +0 -468
  280. package/src/mcp/mcp-bin.ts +0 -3
  281. package/src/mcp/mcp-cli.ts +0 -82
  282. package/src/mcp/protocol.ts +0 -13
  283. package/src/mcp/sandbox.ts +0 -195
  284. package/src/mcp/sdk-decl.ts +0 -391
  285. package/src/mcp/server.ts +0 -362
  286. package/src/mcp/tool-surface.ts +0 -146
  287. package/src/mermaid-source.ts +0 -655
  288. package/src/multiline-utils.ts +0 -228
  289. package/src/parser.ts +0 -1031
  290. package/src/pie/layout.ts +0 -168
  291. package/src/pie/parser.ts +0 -136
  292. package/src/pie/renderer.ts +0 -234
  293. package/src/pie/types.ts +0 -82
  294. package/src/quadrant/layout.ts +0 -191
  295. package/src/quadrant/parser.ts +0 -183
  296. package/src/quadrant/renderer.ts +0 -322
  297. package/src/quadrant/types.ts +0 -113
  298. package/src/render-family-hooks.ts +0 -244
  299. package/src/renderer.ts +0 -1099
  300. package/src/route-contracts.ts +0 -2723
  301. package/src/scene/backend.ts +0 -76
  302. package/src/scene/fidelity.ts +0 -183
  303. package/src/scene/hybrid-backend.ts +0 -174
  304. package/src/scene/ir.ts +0 -181
  305. package/src/scene/marks.ts +0 -127
  306. package/src/scene/rough-backend.ts +0 -378
  307. package/src/scene/seed.ts +0 -46
  308. package/src/scene/style-registry.ts +0 -556
  309. package/src/sequence/layout.ts +0 -456
  310. package/src/sequence/parser.ts +0 -255
  311. package/src/sequence/renderer.ts +0 -604
  312. package/src/sequence/types.ts +0 -154
  313. package/src/shape-clipping.ts +0 -351
  314. package/src/shared/accessibility-directives.ts +0 -22
  315. package/src/shared/batched.ts +0 -61
  316. package/src/shared/color-math.ts +0 -93
  317. package/src/shared/svg-a11y.ts +0 -29
  318. package/src/shared/syntax-error.ts +0 -17
  319. package/src/shared/unicode-ranges.ts +0 -135
  320. package/src/styles.ts +0 -318
  321. package/src/svg-paths.ts +0 -28
  322. package/src/text-metrics.ts +0 -248
  323. package/src/theme.ts +0 -710
  324. package/src/timeline/layout.ts +0 -381
  325. package/src/timeline/parser.ts +0 -215
  326. package/src/timeline/renderer.ts +0 -538
  327. package/src/timeline/types.ts +0 -105
  328. package/src/types.ts +0 -462
  329. package/src/website-worker-modules.d.ts +0 -18
  330. package/src/xychart/axis-utils.ts +0 -109
  331. package/src/xychart/colors.ts +0 -124
  332. package/src/xychart/config.ts +0 -88
  333. package/src/xychart/layout.ts +0 -656
  334. package/src/xychart/parser.ts +0 -504
  335. package/src/xychart/renderer.ts +0 -640
  336. package/src/xychart/types.ts +0 -282
@@ -1,245 +0,0 @@
1
- # Characterising the layout system
2
-
3
- This folder bootstraps a **characterisation-test** suite for the layout
4
- algorithm, in the sense of
5
- [adewale/testing-best-practices](https://github.com/adewale/testing-best-practices):
6
- pin what the code does today, with worked examples + property-based tests, so
7
- the algorithm can be refactored safely and improved deliberately.
8
-
9
- It contains three layers — a **deep** characterisation of the flowchart/state
10
- grid engine, a **breadth** layer spanning every renderer, and a **visual-quality**
11
- approval layer for reviewable layout drift:
12
-
13
- | File | What it is |
14
- |------|------------|
15
- | [`contact-sheet.md`](./contact-sheet.md) | **Depth** — the minimum set of worked examples that exercise every load-bearing decision in the grid engine. One phenomenon per example. (Generated by `scripts/characterization/contact-sheet.ts`.) |
16
- | [`properties.md`](./properties.md) | **Depth** — the smallest load-bearing set of properties for the grid engine, with a minimality (mutation-kill) argument and academic grounding. |
17
- | [`../../src/__tests__/characterization-layout.test.ts`](../../src/__tests__/characterization-layout.test.ts) | **Depth** — those properties as executable `fast-check` tests (13 tests). |
18
- | [`contact-sheet-families.md`](./contact-sheet-families.md) | **Breadth** — one canonical example per renderer (all 12 families) + the universal-invariant coverage matrix. (Generated by `scripts/characterization/contact-sheet-families.ts`.) |
19
- | [`../../src/__tests__/characterization-families.test.ts`](../../src/__tests__/characterization-families.test.ts) | **Breadth** — the universal invariants extended across every family and public output surface, asserting only what holds per family (17 tests). |
20
- | [`visual-quality.md`](./visual-quality.md) | **Visual approval** — SVG snapshots, SVG/PNG fingerprints, and advisory graph-drawing metrics for all 12 families. (Generated by `scripts/characterization/visual-quality.ts`.) |
21
- | [`../../src/__tests__/characterization-generated-artifacts.test.ts`](../../src/__tests__/characterization-generated-artifacts.test.ts) | **Drift check** — fails when generated contact sheets, visual report, or SVG snapshots are stale. |
22
-
23
- No implementation code was changed to produce any of this.
24
-
25
- ## Visual testing rule
26
-
27
- Snapshots and contact sheets are approval evidence, not the whole oracle. When a
28
- bug report says something **looks** wrong, add at least one executable visual
29
- contract that would fail before updating any golden file. Pick the cheapest
30
- contract that observes the thing users actually see:
31
-
32
- | Visual risk | Preferred contract | Examples |
33
- |-------------|--------------------|----------|
34
- | Route geometry, ports, label lanes, overlaps | Geometry/rubric invariant over positioned layout | `route-contracts*.test.ts`, `layout-rubric.test.ts`, `contact-sheet.test.ts` hard metrics |
35
- | Effective color, stroke thickness, blank/collapsed render, visible endpoint glyphs | Raster invariant with `@resvg/resvg-js` pixels | `visual-rendering-contracts.test.ts`, `helpers/raster.ts` |
36
- | ASCII/Unicode line style or marker placement | Row/region assertion on the rendered character grid | `ascii-edge-styles.test.ts` connector-row contracts |
37
- | Broad family drift that needs human judgement | Golden/snapshot/contact sheet after an invariant already guards the principle | `visual-quality.md`, `visual-snapshots/*.svg`, PR screenshots |
38
- | Parser, escaping, config, IDs, public API shape | Structural/string assertion | Parser/security/integration tests |
39
-
40
- The red-green loop for visual work is:
41
-
42
- 1. Reproduce the bad rendering with the smallest diagram that shows the fault.
43
- 2. Encode the visual principle as geometry, raster, or row-level evidence.
44
- 3. Prove the test is sensitive: where practical, simulate the old behaviour or
45
- run a temporary source-level sabotage before trusting the green run.
46
- 4. Fix the implementation.
47
- 5. Regenerate approval artifacts only after the invariant test passes and the
48
- visual diff has been reviewed.
49
-
50
- ## Relationship to PR 30
51
-
52
- PR 30 changed the right baseline for layout characterisation. It introduced the
53
- route-contract layer (`src/route-contracts.ts`), the deterministic graph-drawing
54
- rubric (`src/layout-rubric.ts`), route/contact-sheet gates
55
- (`src/__tests__/contact-sheet.test.ts`, `src/__tests__/layout-rubric.test.ts`),
56
- and the heuristic tracker (`eval/heuristic-tracker/`). Those tests now own the
57
- question "is this flowchart/state/architecture route geometrically valid and
58
- free of hitches, stale certificates, off-outline endpoints, and label-route
59
- ambiguity?"
60
-
61
- This directory owns a different question: "what observable layout behaviour did
62
- we approve, and did it drift deliberately?" After rebasing this PR over PR 30,
63
- `bun run characterization:check` reported only the visual-quality report plus
64
- the flowchart/state SVG snapshots as stale. That is the intended signal:
65
- flowchart/state are exactly the families PR 30's route-contract work should
66
- move, while the other renderer-family snapshots stayed unchanged. The correct
67
- course is therefore to approve the new flowchart/state baselines after the PR 30
68
- route gates pass, rather than add duplicate route-contract assertions here.
69
-
70
- For future layout changes:
71
-
72
- | If this changes | Use this gate | Review action |
73
- |-----------------|---------------|---------------|
74
- | Flowchart/state/architecture routing geometry | `bun test src/__tests__/contact-sheet.test.ts src/__tests__/layout-rubric.test.ts` and `bun run track` | Hard rubric violations must stay zero; baseline deltas must be explained as improvement or intended drift. |
75
- | Generated characterisation artifacts | `bun run characterization:check` | Regenerate the contact sheets / visual snapshots only after reviewing the visual diff. |
76
- | ASCII grid mechanics | `bun test src/__tests__/characterization-layout.test.ts` plus `bun run mutation-test:characterization` | Update P-properties only when the algorithm deliberately changes. |
77
- | Renderer-family dispatch/output surfaces | `bun test src/__tests__/characterization-families.test.ts` | Drift outside the PR's claimed layout surface is suspicious and needs a separate explanation. |
78
-
79
- ## Coverage across renderers
80
-
81
- The **depth** layer targets the flowchart + `stateDiagram-v2` family (the
82
- hand-written grid + A\* engine — see next section for why). The **breadth** layer
83
- extends the universal invariants to every diagram family and public output
84
- surface: text (`renderMermaidASCII`), SVG (`renderMermaidSVG`), and PNG
85
- (`renderMermaidPNG`, which rasterizes the SVG path). It asserts only what is
86
- empirically true for each:
87
-
88
- | Invariant | Holds for |
89
- |-----------|-----------|
90
- | Dispatch totality (non-empty text/SVG and valid PNG signature) | **every** family and public output surface |
91
- | Sentinel label conservation | **every** family on text/SVG surfaces |
92
- | Determinism (byte-identical) | **every** family on text/SVG/PNG matrix cases (also pinned corpus-wide for ASCII by `ascii-determinism.test.ts`) |
93
- | Output hygiene (no `NaN` / `Infinity` / `undefined`, no ANSI when color is disabled) | **every** family on text/SVG surfaces |
94
- | No diagonals | **every** family on text output (xychart plots with block glyphs, not `/\`) |
95
- | Rectangular canvas (all rows one width) | box/graph families only: flowchart, state, sequence, class, er |
96
- | Layered placement, non-overlap, round-trip (P5–P10) | flowchart/state grid engine only |
97
-
98
- The chart, list, schedule, and architecture families (timeline, journey, xychart,
99
- pie, quadrant, gantt, architecture) emit ragged rows by design, so rectangularity is **not**
100
- asserted there — and that boundary is pinned as a known limit. The deep
101
- structural and layering properties are specific to the grid engine and do not
102
- generalise; each non-grid family has its own layout strategy (documented in
103
- `contact-sheet-families.md`) whose deep per-family invariants are the natural
104
- next increment.
105
-
106
- The visual-quality layer deliberately sits beside, not inside, the minimal
107
- property kernel. It records SVG snapshots, PNG hashes, crossings, bends, route
108
- length, area fill, label fit, and edge-label overlap risk for one canonical case
109
- per family. Those values are approval signals: a diff should be inspected and
110
- approved, not automatically interpreted as a semantic bug. PR 30's rubric is the
111
- hard correctness oracle for route-contract families; these snapshots are the
112
- cross-family drift ledger.
113
-
114
- ---
115
-
116
- ## What "the layout algorithm" means here
117
-
118
- This project has **two** distinct layout engines:
119
-
120
- 1. **ELK-based engine** (`src/layout-engine.ts`) — wraps Eclipse Layout Kernel's
121
- *layered* (Sugiyama) algorithm to produce pixel coordinates for **SVG/PNG**.
122
- The placement is a configured third-party black box; the bespoke part is the
123
- post-processing (layer snapping, edge bundling, margin routing, shape
124
- clipping).
125
- 2. **ASCII grid engine** (`src/ascii/grid.ts` + `pathfinder.ts` +
126
- `edge-routing.ts` + `edge-bundling.ts`) — a **hand-written** grid layout with
127
- **A\* orthogonal edge routing** that renders flowcharts and state diagrams as
128
- character art. It is a TypeScript port and extension of
129
- [`AlexanderGrooff/mermaid-ascii`](https://github.com/AlexanderGrooff/mermaid-ascii).
130
-
131
- **This characterisation targets the ASCII grid engine.** It is the genuinely
132
- "ours" algorithm (the ELK one delegates placement), it is pure / synchronous /
133
- deterministic / dependency-free, and it is the surface the project already
134
- mutation-tests (`stryker.ascii.config.json`). It is therefore the ideal
135
- characterisation subject. The flowchart and `stateDiagram-v2` families share
136
- this exact pipeline (`src/ascii/index.ts`); the other families (sequence, class,
137
- ER, pie, quadrant, xychart, timeline, journey, architecture) have their own
138
- renderers and are out of scope here.
139
-
140
- ### The pipeline in one line
141
-
142
- ```
143
- parseMermaid → convertToAsciiGraph → createMapping (grid + A*) → drawGraph → canvasToString
144
- ```
145
-
146
- `createMapping` (`grid.ts`) is the heart: it places each node as a **3×3 grid
147
- block**, assigns layers along the flow axis with a **stride of 4**, routes every
148
- edge with a **bounded, deterministic A\***, and bundles fan-in/fan-out edges onto
149
- shared trunks.
150
-
151
- ---
152
-
153
- ## How the layout works (the load-bearing mechanics)
154
-
155
- - **Grid model.** Every node owns a 3×3 block of an integer grid; `gridCoord` is
156
- its top-left cell, and the eight surrounding cells are edge attachment points.
157
- Blocks are placed 4 grid units apart (3 cells + a 1-cell routing gutter).
158
- - **Layer assignment.** Roots (nodes with no incoming edge) go at level 0;
159
- each child is placed one level (stride 4) along the **flow axis** (y for
160
- TD/BT, x for LR/RL). TD and LR are the same code with x/y transposed; **BT =
161
- TD then vertical flip**; **RL is currently treated as LR**.
162
- - **A\* routing.** Edges are routed cell-by-cell with A\* over the same grid that
163
- tracks node occupancy. Moves are 4-directional only (⇒ **orthogonal**, no
164
- diagonals); the heuristic is Manhattan distance + a corner penalty (prefers
165
- straight runs); ties break FIFO (⇒ **deterministic**); the search is bounded
166
- (⇒ **terminates**, returns `null` + a straight fallback if walled off).
167
- - **Edge bundling.** Sibling fan-out / fan-in edges of the same style merge onto
168
- a single shared trunk that splits at one junction; labelled siblings (which
169
- can't bundle) share a trunk prefix instead.
170
- - **Best-effort, not a solver.** For cyclic / dense graphs the multi-pass
171
- placement can drop or overlap nodes. That limitation is real, current, and
172
- pinned by property **P10** rather than hidden.
173
-
174
- A fuller mechanical anatomy (with `file:line` citations for all 30+ invariants)
175
- informed `properties.md`; the citations are inlined there.
176
-
177
- ---
178
-
179
- ## How this connects to the testing literature
180
-
181
- - **Characterisation tests** (Feathers, *WELC* ch. 13): tests that document the
182
- system's *actual* behaviour, not its intended behaviour — the safety net for
183
- refactoring. The contact sheet is the worked-example form; the property suite
184
- is the generalised form.
185
- - **Approval / golden tests** (Falco): the contact sheet is generated and
186
- reviewed as a diff — a surprising change is a regression, an expected change
187
- is the new approved baseline. The repo's `src/__tests__/testdata/` corpus is
188
- the byte-level golden layer beneath it.
189
- - **Property-based testing** (fast-check): the kernel asserts **invariants** and
190
- **metamorphic relations** rather than exact outputs, so it generalises across
191
- thousands of generated graphs instead of a handful of fixtures.
192
- - **Mutation testing** (Stryker, already configured): the oracle for *which*
193
- properties are load-bearing — a property is kept only if it kills a mutant no
194
- other test kills. See the minimality argument in `properties.md`.
195
- - **Visual approval / metric drift:** `visual-quality.md` keeps the literature's
196
- aesthetic objectives visible (crossings, bends, area, label overlap) without
197
- turning them into brittle universal laws.
198
-
199
- Together: **goldens characterise, properties generalise, mutation proves which
200
- assertions do work, visual snapshots make quality drift reviewable.**
201
-
202
- ---
203
-
204
- ## Reproduce
205
-
206
- ```bash
207
- bun install
208
-
209
- # Executable characterisation kernels
210
- bun test src/__tests__/characterization-layout.test.ts # grid engine (depth)
211
- bun test src/__tests__/characterization-families.test.ts # all families (breadth)
212
- bun test src/__tests__/characterization-generated-artifacts.test.ts
213
-
214
- # Regenerate the contact sheets / visual report, then review the diff and commit
215
- bun run scripts/characterization/contact-sheet.ts
216
- bun run scripts/characterization/contact-sheet-families.ts
217
- bun run scripts/characterization/visual-quality.ts
218
- git diff docs/layout-characterization/
219
-
220
- # CI-friendly generated-artifact drift check
221
- bun run characterization:check
222
-
223
- # Route-contract correctness gates introduced by PR 30
224
- bun test src/__tests__/contact-sheet.test.ts src/__tests__/layout-rubric.test.ts
225
- bun run track
226
-
227
- # (optional) quick mutation evidence for the load-bearing ranges
228
- bun run mutation-test:characterization
229
-
230
- # exhaustive but slow: mutates the whole ASCII layout core
231
- bun run mutation-test:ascii
232
- ```
233
-
234
- ## Sources
235
-
236
- Layered graph drawing: Sugiyama–Tagawa–Toda (1981); Gansner–Koutsofios–North–Vo
237
- (1993, the `dot` algorithm, <https://www.graphviz.org/documentation/TSE93.pdf>);
238
- Brandes–Köpf (2002). A\*: Hart–Nilsson–Raphael (1968). Orthogonal routing:
239
- Tamassia (1987); Wybrow–Marriott–Stuckey (2009),
240
- <https://users.monash.edu/~mwybrow/papers/wybrow-gd-2009.pdf>. ELK:
241
- <https://eclipse.dev/elk/>. ASCII prior art: mermaid-ascii
242
- (<https://github.com/AlexanderGrooff/mermaid-ascii>), Graph::Easy. Testing:
243
- Feathers, *Working Effectively with Legacy Code* (2004); Falco, ApprovalTests
244
- (<https://approvaltests.com/>); Bartocci et al., property-based mutation testing
245
- (2023, <https://arxiv.org/pdf/2301.13615>).