fix(mcp-server): make edit_diagram all-or-nothing and fix preview sync races

- edit_diagram applies nothing when any operation fails, rejects invalid or
  multi-cell new_xml, validates only the target page, and returns the
  current page XML on every rejection (including stale edits)
- Fix get_diagram reading the old diagram right after an AI write: the
  preview pushed its sync reply with a newer version than it was taken at
- Keep a user edit that loses the race with an AI write in history and
  tell the user in the preview
- Autofix removes only exact foreign tags (a stray <mxGraph/> deleted
  <mxGraphModel>), fixes tag case, drops orphan <mxPoint>s, and rejects
  unknown element names in model XML
- Edit empty and compressed pages; PNG exports use the page on screen;
  tag download exports; reload from the server after a page export
- Expand ~ in paths, tell the model when the browser sync timed out,
  use registerPrompt, require SDK ^1.31.0
This commit is contained in:
dayuan.jiang
2026-10-03 22:03:44 +09:00
parent a46787c1b8
commit 6d67a0ec69
13 changed files with 712 additions and 204 deletions
+5 -4
View File
@@ -302,14 +302,15 @@ export function deletePageFromDoc(
doc: Document,
selector: PageSelector,
): { ok: boolean; reason?: string; deletedId?: string; deletedIndex?: number } {
const pages = listPagesFromDoc(doc)
if (pages.length <= 1) {
return { ok: false, reason: "Cannot delete the only remaining page" }
}
// Match first, so a wrong selector reports "not found" even on a
// one-page document
const found = findPageElement(doc, selector)
if (!found) {
return { ok: false, reason: "Page not found" }
}
if (listPagesFromDoc(doc).length <= 1) {
return { ok: false, reason: "Cannot delete the only remaining page" }
}
const id = found.element.getAttribute("id") || ""
const index = found.index
found.element.parentNode?.removeChild(found.element)