@superdoc/mcp 1.6.0-next.16 → 1.6.0-next.18

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 (2) hide show
  1. package/dist/index.js +120 -13
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31600,7 +31600,7 @@ var init_host = __esm(() => {
31600
31600
  });
31601
31601
 
31602
31602
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31603
- var SDK_VERSION = "2.19.0-next.16";
31603
+ var SDK_VERSION = "2.19.0-next.18";
31604
31604
 
31605
31605
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31606
31606
  import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
@@ -195388,7 +195388,7 @@ function isBreakRunToken(token) {
195388
195388
  }
195389
195389
  function compileOverlapEdit(input) {
195390
195390
  const paragraphInlineMap = input.paragraphInlineMap ?? parseParagraphInlineMap(input.paragraphXml, input.namespaceBindings);
195391
- const consecutiveBreakInsertion = tryConsecutiveManualBreakInsertion(input, paragraphInlineMap);
195391
+ const consecutiveBreakInsertion = input.newTextRunsXml === undefined ? tryConsecutiveManualBreakInsertion(input, paragraphInlineMap) : null;
195392
195392
  if (consecutiveBreakInsertion)
195393
195393
  return consecutiveBreakInsertion;
195394
195394
  const readsComplexDeletionForCollapsedInsert = input.newText.length > 0 && input.rangeStart === input.rangeEnd && ((input.coordinateSpace ?? "visible") === "visible" || input.changeMode === "tracked");
@@ -195483,6 +195483,12 @@ function compileParsedOverlapEdit(input, tokens, descendedEditableContainers) {
195483
195483
  if (touched.length === 0 && touchedBreaks.length === 0) {
195484
195484
  return { ok: false, reason: "invalid-range", detail: "overlap compiler: no tokens touched by the range." };
195485
195485
  }
195486
+ if (input.newTextRunsXml !== undefined) {
195487
+ const parent = touched.length === 1 ? touched[0].token : null;
195488
+ if (input.changeMode !== "tracked" || input.rangeStart !== input.rangeEnd || !input.newText.length || parent?.kind !== "ins" || input.rangeStart <= parent.visibleStart || input.rangeStart >= parent.visibleEnd || parent.nestedDeletions?.length || parent.commentedBoundary || descendedEditableContainers.length || !parent.sourceIdentity.rsid && !parent.sourceIdentity.wId) {
195489
+ return { ok: false, reason: "text-range-in-unsupported-tracked-wrapper" };
195490
+ }
195491
+ }
195486
195492
  if (touchedBreaks.length > 0) {
195487
195493
  const withBreaks = tryPureDeleteAcrossTokens(input, tokens, touched, touchedBreaks);
195488
195494
  if (withBreaks)
@@ -196587,7 +196593,10 @@ function foldInsideOwnInsertion(input, allTokens, parent) {
196587
196593
  return result2.ok && input.changeMode === "direct" ? { ...result2, requiresCollaborationSessionSync: true } : result2;
196588
196594
  }
196589
196595
  let innerXml = null;
196590
- if (nestedDeletions.length > 0) {
196596
+ if (input.newTextRunsXml !== undefined) {
196597
+ const runs = parent.innerRuns ?? [parent.inner];
196598
+ innerXml = buildInsInnerXmlFromRuns(sliceWrappedRuns(runs, 0, localStart)) + input.newTextRunsXml + buildInsInnerXmlFromRuns(sliceWrappedRuns(runs, localEnd, text.length));
196599
+ } else if (nestedDeletions.length > 0) {
196591
196600
  const runs = spliceInnerRuns(parent.innerRuns ?? [parent.inner], localStart, localEnd, input.newText, parent, localStart);
196592
196601
  const delta = input.newText.length - (localEnd - localStart);
196593
196602
  const preservedDeletions = nestedDeletions.map((entry) => {
@@ -196988,7 +196997,8 @@ function splitInsertionAroundChildChange(input, allTokens, parent) {
196988
196997
  runClose: insertMeta.runClose,
196989
196998
  rPr: insertRPr,
196990
196999
  text: input.newText
196991
- }
197000
+ },
197001
+ ...input.newTextRunsXml !== undefined ? { innerXml: input.newTextRunsXml } : {}
196992
197002
  });
196993
197003
  const closed = closeFreshInsertionScope(childInsXml, Object.fromEntries(parent.namespaceBindings), input.namespaceBindings ?? {});
196994
197004
  if (closed == null)
@@ -221707,7 +221717,12 @@ function planDirectParagraphRangeRewrite(input) {
221707
221717
  if (!bytes || end.partUri !== start.partUri)
221708
221718
  return { ok: false, reason: "unsupported-context" };
221709
221719
  const partXml = TD56.decode(bytes);
221710
- const cascadingComments = expandCommentThreadWIds(state, collectCommentsTouchedByByteRange(partXml, input.selectionStartByte, input.selectionEndByte));
221720
+ const commentMarkers = collectBodyCommentMarkers(partXml);
221721
+ const touchedComments = collectCommentsTouchedByByteRange(commentMarkers, input.selectionStartByte, input.selectionEndByte);
221722
+ const retainedStarts = retainedCommentStarts(input, bytes, commentMarkers, touchedComments);
221723
+ for (const marker of retainedStarts)
221724
+ touchedComments.delete(marker.id);
221725
+ const cascadingComments = expandCommentThreadWIds(state, touchedComments);
221711
221726
  const startXml = decodeByteRange2(bytes, start.byteStart, start.byteEnd);
221712
221727
  const endXml = decodeByteRange2(bytes, end.byteStart, end.byteEnd);
221713
221728
  const beforeWindowXml = decodeByteRange2(bytes, start.byteStart, end.byteEnd);
@@ -221741,7 +221756,13 @@ function planDirectParagraphRangeRewrite(input) {
221741
221756
  });
221742
221757
  if (!endSlice.ok)
221743
221758
  return endSlice;
221744
- const collapsed = sectionCollapse ? sectionCollapse.render(startSlice.head, endSlice.tail) : renderCollapsedParagraph(startXml, startSlice.head, endSlice.tail);
221759
+ let movedStarts = "";
221760
+ if (retainedStarts.length > 0) {
221761
+ const destinationNamespaces = namespaceBindingsAtPosition(bytes, start.byteStart, matchParagraphOpenTag(startXml) ?? "");
221762
+ const retainedHeadStarts = collectBodyCommentMarkers(startSlice.head, destinationNamespaces).filter((marker) => marker.kind === "commentRangeStart").map((marker) => marker.id);
221763
+ movedStarts = retainedStarts.filter((marker) => !retainedHeadStarts.includes(marker.id)).map((marker) => commentMarkerWithNamespaces(bytes, marker, destinationNamespaces)).join("");
221764
+ }
221765
+ const collapsed = sectionCollapse ? sectionCollapse.render(startSlice.head + movedStarts, endSlice.tail) : renderCollapsedParagraph(startXml, startSlice.head + movedStarts, endSlice.tail);
221745
221766
  if (!collapsed)
221746
221767
  return { ok: false, reason: "invalid-range" };
221747
221768
  collapsedXml = collapsed;
@@ -223555,14 +223576,42 @@ function collectCascadingComments(paraXml, resolveNamespaceBindings) {
223555
223576
  return new Set;
223556
223577
  return new Set(collectBodyCommentMarkers(paraXml, resolveNamespaceBindings()).map((marker) => marker.id));
223557
223578
  }
223558
- function collectCommentsTouchedByByteRange(xml, startByte, endByte) {
223579
+ function collectCommentsTouchedByByteRange(markers, startByte, endByte) {
223559
223580
  const touched = new Set;
223560
- for (const marker of collectBodyCommentMarkers(xml)) {
223581
+ for (const marker of markers) {
223561
223582
  if (marker.range.byteStart < endByte && marker.range.byteEnd > startByte)
223562
223583
  touched.add(marker.id);
223563
223584
  }
223564
223585
  return touched;
223565
223586
  }
223587
+ function retainedCommentStarts(input, bytes, markers, touched) {
223588
+ if (input.fullBlockReplacementXml !== undefined)
223589
+ return [];
223590
+ return markers.filter((marker) => {
223591
+ if (marker.kind !== "commentRangeStart" || !touched.has(marker.id))
223592
+ return false;
223593
+ const anchors = markers.filter((candidate2) => candidate2.id === marker.id);
223594
+ const end = anchors.find((candidate2) => candidate2.kind === "commentRangeEnd");
223595
+ const reference = anchors.find((candidate2) => candidate2.kind === "commentReference");
223596
+ if (anchors.length !== 3 || !end || !reference || marker.range.byteStart < input.selectionStartByte || marker.range.byteEnd > input.selectionEndByte || end.range.byteStart < input.selectionEndByte || reference.range.byteStart < end.range.byteEnd)
223597
+ return false;
223598
+ const endEntry = input.indexEntries.find((entry) => end.range.byteStart >= entry.byteStart && end.range.byteStart < entry.byteEnd);
223599
+ if (!endEntry || endEntry.ordinal < input.end.ordinal)
223600
+ return false;
223601
+ const endXml = decodeByteRange2(bytes, endEntry.byteStart, endEntry.byteEnd);
223602
+ const model = parseParagraphInlineMap(endXml, end.paragraph?.namespaceBindings);
223603
+ const endMarkerOffset = resolveParagraphVisibleOffsetAtByte(model, end.range.byteStart - endEntry.byteStart);
223604
+ const remainingChars = endEntry.ordinal === input.end.ordinal ? endMarkerOffset - input.endOffset : input.end.textLength - input.endOffset + endMarkerOffset + input.indexEntries.filter((entry) => entry.ordinal > input.end.ordinal && entry.ordinal < endEntry.ordinal).reduce((sum, entry) => sum + entry.textLength, 0);
223605
+ return remainingChars > 0;
223606
+ });
223607
+ }
223608
+ function commentMarkerWithNamespaces(bytes, marker, destinationNamespaces) {
223609
+ const xml = decodeByteRange2(bytes, marker.range.byteStart, marker.range.byteEnd);
223610
+ const openTag = xml.match(/^<(?:"[^"]*"|'[^']*'|[^>"'])*>/)?.[0] ?? "";
223611
+ const localNamespaces = namespaceBindingsAtPosition(TE25.encode(xml), 0, openTag);
223612
+ const declarations = Object.entries(namespaceBindingsAtPosition(bytes, marker.range.byteStart)).filter(([prefix, uri]) => localNamespaces[prefix] === undefined && destinationNamespaces[prefix] !== uri).map(([prefix, uri]) => ` xmlns${prefix ? `:${prefix}` : ""}="${escapeXmlAttribute(uri)}"`).join("");
223613
+ return xml.replace(/^<[\w.-]+(?::[\w.-]+)?\b/, (tag) => tag + declarations);
223614
+ }
223566
223615
  function stripCommentAnchorsFromXml(xml, commentIds, resolveNamespaceBindings) {
223567
223616
  const bytes = TE25.encode(xml);
223568
223617
  if (commentIds.size === 0)
@@ -238014,6 +238063,50 @@ var init_types6 = __esm(() => {
238014
238063
  });
238015
238064
 
238016
238065
  // ../../../v2/editor-core/dist/document/transactions/compile-paste-splice.js
238066
+ function planTrackedInsertionSplice(input) {
238067
+ const block = input.blocks.length === 1 ? input.blocks[0] : null;
238068
+ const stamp = input.trackedStamp;
238069
+ if (!stamp || input.wrapAllTracked === false || input.collapsedObjectBoundary || (input.replaceToOffset ?? input.charOffset) !== input.charOffset || block?.kind !== "paragraph" || block.styleRef || block.numbering || block.listIntent || block.paragraphProps || block.pPrXml || block.blockSdts?.length || block.complete)
238070
+ return null;
238071
+ const runs = input.inlineSpecs?.get(block) ?? block.runs.map(toPasteTextRunSpec);
238072
+ if (runs.some((run) => run.kind !== undefined && run.kind !== "text" || ("commentIds" in run) && run.commentIds?.length || ("trackedInsertion" in run) && run.trackedInsertion))
238073
+ return null;
238074
+ const newText = runs.map((run) => ("text" in run) ? run.text : "").join("");
238075
+ if (!newText)
238076
+ return null;
238077
+ const envelope = parseParagraphEnvelope(input.anchorXml);
238078
+ if (!envelope)
238079
+ return null;
238080
+ const newTextRunsXml = renderPasteRuns(runs).replace(/<w:r(?=[\s>])/g, '<w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"');
238081
+ const overlap = compileOverlapEdit({
238082
+ storyId: input.storyId,
238083
+ paragraphXml: input.anchorXml,
238084
+ namespaceBindings: namespaceBindingsAtPosition(input.partBytes, input.paragraphStartByte, envelope.open),
238085
+ rangeStart: input.charOffset,
238086
+ rangeEnd: input.charOffset,
238087
+ newText,
238088
+ newTextRunsXml,
238089
+ changeMode: "tracked",
238090
+ currentAuthor: stamp.author,
238091
+ txTimestamp: stamp.date,
238092
+ rsid: stamp.rsid,
238093
+ insRsid: stamp.rsid,
238094
+ nextWId: () => stamp.allocateWId(),
238095
+ reserveWId: () => stamp.allocateWId()
238096
+ });
238097
+ if (!overlap.ok)
238098
+ return { ok: false, reason: overlap.reason };
238099
+ return {
238100
+ ok: true,
238101
+ xml: overlap.xml,
238102
+ createdParaIds: [],
238103
+ destinationParaIdsByBlock: [[input.anchorParaId ?? ""]],
238104
+ insertedVisibleChars: newText.length,
238105
+ removedVisibleChars: 0,
238106
+ anchorParagraphUnchanged: false,
238107
+ trackedChangeRsids: { created: overlap.emittedRsids, updated: overlap.updatedRsids ?? [] }
238108
+ };
238109
+ }
238017
238110
  function planParagraphSplice(input) {
238018
238111
  const start = input.charOffset;
238019
238112
  const end = input.replaceToOffset ?? input.charOffset;
@@ -238341,6 +238434,7 @@ function withTrackedRsid(openTag, rsid) {
238341
238434
  var init_compile_paste_splice = __esm(() => {
238342
238435
  init_paragraph_inline_model();
238343
238436
  init_xml_text();
238437
+ init_overlap_edit_compiler();
238344
238438
  init_paragraph_contribution();
238345
238439
  init_paragraph_para_id_attrs();
238346
238440
  });
@@ -242680,7 +242774,7 @@ function runPasteSpliceCommit(input, target, resolvedBlocks, listExtras, imageEx
242680
242774
  return deleted;
242681
242775
  rewrittenXml = deleted.xml;
242682
242776
  }
242683
- return planParagraphSplice({
242777
+ const spliceInput = {
242684
242778
  anchorXml: rewrittenXml,
242685
242779
  anchorParaId: anchor.entry.blockId,
242686
242780
  blocks: resolvedBlocks,
@@ -242695,7 +242789,12 @@ function runPasteSpliceCommit(input, target, resolvedBlocks, listExtras, imageEx
242695
242789
  ...stamp ? { trackedStamp: stamp, wrapAllTracked } : {},
242696
242790
  ...listExtras.commentIdMap ? { commentIdMap: listExtras.commentIdMap } : {},
242697
242791
  ...listExtras.noteIdMap ? { noteIdMap: listExtras.noteIdMap } : {}
242698
- });
242792
+ };
242793
+ const ordinary = planParagraphSplice(spliceInput);
242794
+ if (!ordinary.ok && ordinary.reason === "paste-target-unsupported" && wrapAllTracked && (target.replaceToOffset ?? target.charOffset) === target.charOffset) {
242795
+ return planTrackedInsertionSplice({ ...spliceInput, storyId: target.storyId }) ?? ordinary;
242796
+ }
242797
+ return ordinary;
242699
242798
  };
242700
242799
  const plan = planForParagraph(anchorXml, trackedStamp, () => mintParaId(state, state.packageRevision, anchor.ordinal + 1 + (mintSalt += 1)));
242701
242800
  if (!plan.ok)
@@ -242767,8 +242866,9 @@ function runPasteSpliceCommit(input, target, resolvedBlocks, listExtras, imageEx
242767
242866
  nodeId: paraId,
242768
242867
  storyId: target.storyId
242769
242868
  }));
242770
- if (trackedStamp) {
242771
- createdRefs.push({ kind: "trackedChange", entityId: trackedStamp.rsid, storyId: target.storyId });
242869
+ const createdTrackedRsids = plan.trackedChangeRsids?.created ?? (trackedStamp ? [trackedStamp.rsid] : []);
242870
+ for (const entityId of createdTrackedRsids) {
242871
+ createdRefs.push({ kind: "trackedChange", entityId, storyId: target.storyId });
242772
242872
  }
242773
242873
  if (listExtras.createdRefs)
242774
242874
  createdRefs.push(...listExtras.createdRefs);
@@ -242780,7 +242880,14 @@ function runPasteSpliceCommit(input, target, resolvedBlocks, listExtras, imageEx
242780
242880
  textRangeShifts,
242781
242881
  createdParaIds: [...plan.createdParaIds],
242782
242882
  createdRefs,
242783
- updatedRefs: [{ kind: "block", nodeId: target.paraId, storyId: target.storyId }],
242883
+ updatedRefs: [
242884
+ { kind: "block", nodeId: target.paraId, storyId: target.storyId },
242885
+ ...(plan.trackedChangeRsids?.updated ?? []).map((entityId) => ({
242886
+ kind: "trackedChange",
242887
+ entityId,
242888
+ storyId: target.storyId
242889
+ }))
242890
+ ],
242784
242891
  relativeToBlockId: target.paraId,
242785
242892
  provisionalToFinal: buildPasteProvisionalMappings(txId, plan.createdParaIds, resolvedBlocks, plan.destinationParaIdsByBlock),
242786
242893
  extraPatchMaps: listExtras.patchMaps,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc/mcp",
3
- "version": "1.6.0-next.16",
3
+ "version": "1.6.0-next.18",
4
4
  "description": "Model Context Protocol server for SuperDoc, giving an AI agent tools to read and edit .docx files.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0",
@@ -24,13 +24,13 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "@modelcontextprotocol/sdk": "^1.26.0",
27
- "@superdoc/sdk": "2.19.0-next.16",
27
+ "@superdoc/sdk": "2.19.0-next.18",
28
28
  "debug": "^4.4.3",
29
29
  "zod": "^4.3.6"
30
30
  },
31
31
  "devDependencies": {
32
- "superdoc": "2.22.0-next.15",
33
- "@superdoc/docx-engine": "0.21.0-next.16",
32
+ "superdoc": "2.22.0-next.17",
33
+ "@superdoc/docx-engine": "0.21.0-next.18",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",