18 Commits

Author SHA1 Message Date
Gaudenz Alder e26beb5582 docs(xml-reference): add layout-quality rules (hubs, short labels, visual semantics)
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>
2026-06-17 16:12:35 +02:00
Gaudenz Alder 20b4686b7a feat(routing): add libavoid obstacle-avoiding edge routing for XML diagrams
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>
2026-06-17 15:48:28 +02:00
Gaudenz Alder 2e49443f51 mcp-app-server: postLayout "elk" + uniform Mermaid wrapper round-trip
- 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>
2026-06-03 21:09:35 +02:00
Gaudenz Alder f452d684b4 mermaid: make horizontalFlow work with titled flowcharts
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>
2026-05-11 17:28:00 +02:00
Gaudenz Alder 81c9ed57ef mermaid: surface layout button + postLayout on titled flowcharts
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>
2026-05-11 16:50:43 +02:00
Gaudenz Alder 3b6df74994 Preview for mermaid and ELK support 2026-04-17 18:26:47 +02:00
Gaudenz Alder 61762b47a1 fix: document line break encoding in xml-reference.md
Prevent LLMs from using literal \n in value attributes, which renders
as backslash-n text instead of a newline. Recommend &#xa; (universal)
or <br> (html=1 only).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 14:32:00 +02:00
Gaudenz Alder 9e4d11ae4a fix: add html=1 to edge examples and document fontStyle usage
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>
2026-04-12 06:10:37 +02:00
Gaudenz Alder 875b75fe67 fix: add html=1 to all XML examples to prevent raw HTML tag display
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>
2026-04-11 16:03:15 +02:00
Gaudenz Alder eececbee95 feat: add edge routing guidance and style selection to xml-reference.md
- Edge style selection table (orthogonal, elbow, entity relation, straight, curved)
- Priority-based orthogonal routing rules (P1: layout, P2: no crossings, P3: clean routes)
- Fan-out/fan-in bus bundling for cleaner multi-edge routing
- Scoping: detailed routing rules apply only to orthogonal/elbow edges
- Consistency rule: one primary edge style per diagram type
- Container edge guidance for swimlanes and VPCs
- UML lifeline shape in style properties table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 10:36:14 +02:00
Gaudenz Alder 079768d7a0 rename drawio-style-reference.md to style-reference.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 08:06:48 +02:00
Gaudenz Alder a8941a7d69 docs: skip search_shapes when user asks for basic/simple shapes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 21:40:33 +02:00
Gaudenz Alder 6ade58cd4a docs: guide LLMs to skip search_shapes for standard diagram types
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>
2026-04-02 21:36:10 +02:00
Gaudenz Alder d026f26c39 feat: add search_shapes tool with 10,400+ shape index
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>
2026-04-02 20:53:41 +02:00
Gaudenz Alder 3e9f667bb1 docs: add general principles to xml-reference (shapes, language)
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>
2026-04-02 19:34:20 +02:00
Gaudenz Alder cdf3578ae1 feat: add mxfile.xsd schema to shared/, update XSD links
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>
2026-04-02 19:24:43 +02:00
Gaudenz Alder 3c0e40acaa feat: add style reference and update xml-reference link
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>
2026-04-02 19:17:40 +02:00
Gaudenz Alder 3366c8e7b3 feat: single source of truth for XML generation prompt
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>
2026-04-02 18:59:19 +02:00