Adopt the general diagram-quality guidance from #45 (by @michaelHMK): group
related nodes and route convergent edges through a hub, encode secondary
detail in node text rather than edges, keep edge labels short, and apply
consistent dashed/color semantics with a legend when mixing.
These are design-layer rules, complementary to the new libavoid routing pass.
The PR's skill-cli / static-file routing guidance is intentionally NOT adopted:
the next desktop app version brings Mermaid parsing + ELK layout to the CLI,
which will invalidate the 'static files get no layout/routing' premise.
Co-Authored-By: Michael Huang <michaelHMK@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New `routing: "libavoid"` param on create_diagram (XML only): a WASM
orthogonal edge router that keeps the LLM's vertex positions and only
recomputes connectors so they route around shapes in clean right angles,
instead of the basic built-in router that cuts straight through boxes.
- Vendor libavoid-js 0.5.0-beta.5 (glue + 492KB wasm) under
mcp-app-server/vendor/libavoid/. processLibavoidBundle neutralizes
import.meta.url, patches the loader to take an inlined wasmBinary, and
aliases globalThis.AvoidLib. The wasm is base64-inlined and fed as
wasmBinary (no fetch — the sandbox has no allow-same-origin and the CSP
forbids data: URIs in connect-src). Confirmed WASM instantiates under the
Claude.ai MCP-app sandbox CSP.
- applyRouting/routeWithLibavoid: vertices -> ShapeRef obstacles, edges ->
ConnRef at shape centers, processTransaction, interior bends written back
as waypoints (collinear-filtered). Edges keep orthogonalEdgeStyle so the
segments stay draggable in the editor; endpoints float (libavoid always
meets a side at its midpoint, where a floating orthogonal endpoint connects
anyway). shapeBufferDistance=16, idealNudgingDistance=14.
- Wire routing through finalizeStreamingView, the browser payload parser, the
handler and the Zod schema. Node (index.js) and Worker (build-html.js) both
inline the bundle.
- Treat routing and postLayout as alternatives (ELK already routes its edges),
not a stack.
- xml-reference.md: correct the stale 'automatic ELK edge-routing pass' claim
(no such always-on pass exists); document the basic built-in router and the
two opt-in passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- create_diagram schema: replace verticalFlow/horizontalFlow/tree/force/
stress/radial with postLayout "elk" (ELK layered flow) plus an optional
XML-only "direction" (vertical/horizontal). Mermaid derives direction
from the flowchart code (TD/LR), so it never passes direction.
- Drop startNodeIds/endNodeIds and the layered start/end pinning pass: the
pins were inert and add fragile cell-id metadata for no layout gain.
- On copy/open, inject the ELK renderer init directive into the Mermaid
source only when ELK is the live on-screen layout.
- Re-vendor drawio-mermaid (uniform transparentBounds wrapper +
groupPadding=20) and drawio-elk (enum-coercion fix, 4c24b73).
- Docs: shared/xml-reference.md and README updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
drawio-elk now handles top-level "isolated" cells (no edges, no
sub-children — i.e. mermaid's frontmatter title vertex) as a pre/post
hook around the ELK layered pass. Wire that into applyPostLayout via
ElkLayout.extractIsolatedTopLevel + placeIsolatedTopLevelAbove, then
drop the workaround layers that built up around the original problem:
- Remove mermaidHasTitleFrontmatter and the three call sites that
null-ed out a requested horizontalFlow when the source had a title.
ELK no longer crushes the diagram, so the downgrade is unneeded.
- Remove the "omit horizontalFlow on titled flowcharts" exception from
the postLayout parameter description. The exception was leaking into
unrelated LR/RL flowchart requests — the LLM defensively substituted
verticalFlow even on untitled flowcharts.
- Rewrite xml-reference.md's postLayout guidance to scope "usually
omit" to XML authoring. The blanket version contradicted the
parameter description's complex-Mermaid trigger rules, and since
xml-reference is appended after the parameter description, its
stronger negative framing won — the LLM was skipping postLayout
even on Mermaid flowcharts well past the complexity threshold.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related fixes that both targeted complex Mermaid flowcharts with a
"--- title: ... ---" frontmatter block:
- isMermaidFlowchart / isMermaidHorizontalFlowchart only inspected the
first non-empty, non-comment line — which for titled sources is the
frontmatter opener "---", not "flowchart TD". The viewer therefore
hid the layout toggle button on every titled flowchart. Extract a
firstMermaidDirectiveLine helper that skips the leading frontmatter
block, and route both detectors through it.
- xml-reference.md's "When NOT to use postLayout" list categorically
excluded all Mermaid diagrams, contradicting the postLayout parameter
description that mandates verticalFlow/horizontalFlow once a Mermaid
flowchart crosses any of the complexity thresholds (>=20 nodes,
>=3 diamonds, feedback edges, >=3 endpoints). Replace the blanket
exclusion with a pointer to those thresholds so the LLM gets one
coherent rule instead of two contradictory ones.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prevent LLMs from using literal \n in value attributes, which renders
as backslash-n text instead of a newline. Recommend 
 (universal)
or <br> (html=1 only).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Edge examples lacked html=1, causing LLMs to generate edges without
it. When edge labels contain HTML tags, they render as literal text
without this flag. Also add guidance on fontStyle vs HTML tags: use
fontStyle for whole-label formatting, HTML tags for partial formatting,
never both.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without html=1 in the style, draw.io renders HTML tags (<b>, <br>,
<font>, etc.) as literal text instead of formatting them. Added html=1
to all code examples and a new "HTML labels" section documenting the
requirement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add explicit decision step: skip search_shapes for flowcharts, UML, ERD,
org charts, mind maps etc. that use basic geometric shapes. Only use it
for industry-specific icons (cloud, P&ID, network, electrical, Cisco, K8s).
Updated in xml-reference.md (single source of truth), search_shapes tool
description, and CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a shape search system that lets LLMs discover correct draw.io style
strings for domain-specific shapes (AWS, Azure, GCP, P&ID, electrical,
Cisco, Kubernetes, UML, BPMN, etc.) before generating XML.
- shape-search/generate-index.js: loads app.min.js via jsdom, runs all
sidebar palette initializations, intercepts createVertexTemplateEntry
and createEdgeTemplateEntry to capture {style, w, h, title, tags}
for every shape. Produces search-index.json (10,440 shapes).
- mcp-app-server/src/shared.js: adds soundex(), buildTagMap(), and
searchShapes() implementing the same search algorithm as draw.io's
Sidebar (exact + phonetic matching, AND across terms). Registers
search_shapes tool in createServer() when shapeIndex is provided.
- Build pipeline: build-html.js embeds the index in generated-html.js,
worker.js and index.js pass it through to createServer().
- xml-reference.md: guides LLMs to use search_shapes for domain shapes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nudge LLMs to use semantically correct draw.io shapes and to match
the user's language in diagram labels.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move mxfile.xsd from www.diagrams.net-source to the public repo so
all references can point here. Update XSD links in xml-reference.md
and drawio-style-reference.md to use the GitHub URL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move drawio-style-reference.md from drawusaurus to shared/ (public
repo so it can be referenced from the docs site). Update the style
reference link in xml-reference.md to point to the new location.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the draw.io XML generation reference to shared/xml-reference.md
and wire all four consumers to use it instead of duplicating the
content. Add layers, tags, and metadata/placeholders documentation.
- MCP app server: reads at startup (Node.js) or pre-builds into
generated-html.js (Workers) via build-html.js
- MCP tool server: reads at startup with fallback to local copy;
prepack script bundles the file before npm publish
- Skill: references the GitHub raw URL so it works after install
- Project instructions: tells users to copy from GitHub
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>