* fix: preserve multi-page diagrams after export
* fix: keep chartXML sourced from autosave to preserve multi-page state
The export event's data.xml (xmlsvg format) contains compressed <diagram>
payloads, which would break applyDiagramOperations/replaceNodes consumers
that need plain <root> elements. Instead of writing export results into
chartXML, stop overwriting it entirely: autosave already delivers the full
uncompressed multi-page document, and loadDiagram covers AI-driven updates.
Also stop overwriting chartXMLRef with the page-only export before sending
a chat message, so session persistence never sees single-page XML.
Keep the data.xml preference for .drawio file downloads (compressed pages
are a valid drawio format).
---------
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
* fix(mcp): keep diagram context valid during edits
Closes#885
* fix(mcp): replace edit_diagram time gate with content comparison
The 30s wall-clock gate rejected slow-but-correct clients (#885).
Instead of a timeout, remember the exact state-store XML the model
last saw (get_diagram / create_new_diagram / edit_diagram / page CRUD)
and reject edit_diagram only when the live browser state differs -
i.e. the user made edits the model hasn't seen yet. Slow reasoning
no longer trips the gate, while unseen manual edits still do.
* docs(mcp): align edit_diagram/get_diagram descriptions with content-based gate
The 'You MUST call get_diagram BEFORE this tool' requirement and the
'Skipping get_diagram WILL cause user's changes to be LOST' warning no
longer match server behavior: a stale edit is rejected with no side
effects, never silently applied. Describe the freshness check instead,
and direct get_diagram usage at its real purpose - learning the current
diagram content when the model doesn't already know it.
* fix(mcp): compare diagram content structurally in the edit gate
draw.io re-serialises the document when pushing state back (attribute
order, pretty-printing, regenerated diagram ids, viewport attributes,
mxfile host), so byte comparison could flag an unchanged diagram as
stale. Fingerprint what a user can actually change instead - page set,
page names, and each page's root cell tree with sorted attributes -
keeping byte equality as the fast path. A bare mxGraphModel now also
fingerprints identically to its single-page mxfile wrapping.
* fix(mcp): don't compare page names against bare mxGraphModel pushes
A bare <mxGraphModel> pushed by the embed/sync path carries no page name,
so normalizeToMxfile invents "Page-1" — falsely reading any custom page
name as a content change and re-triggering the stale rejection on every
edit. When either side of the gate comparison is a bare mxGraphModel,
fingerprint cell trees only; full-mxfile comparisons still detect renames.
* chore(mcp): bump version to 0.2.2
* chore(mcp): sync package-lock.json version to 0.2.2
---------
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>