@superdoc/mcp 1.3.0-next.13 → 1.3.0-next.14

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 +352 -93
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31318,7 +31318,7 @@ var init_host = __esm(() => {
31318
31318
  });
31319
31319
 
31320
31320
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31321
- var SDK_VERSION = "2.16.0-next.13";
31321
+ var SDK_VERSION = "2.16.0-next.14";
31322
31322
 
31323
31323
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31324
31324
  import { chmodSync, existsSync } from "node:fs";
@@ -134761,6 +134761,20 @@ function isValidRevisionDate(value) {
134761
134761
  const daysInMonth = [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
134762
134762
  return day <= daysInMonth[month - 1];
134763
134763
  }
134764
+ function parseRevisionMarkerAttributes(attributes) {
134765
+ const idAttributes = attributes.filter((attribute) => attribute.local === "id");
134766
+ const authorAttributes = attributes.filter((attribute) => attribute.local === "author");
134767
+ const dateAttributes = attributes.filter((attribute) => attribute.local === "date");
134768
+ const hasValidIdAttribute = idAttributes.length === 1 && idAttributes[0].uri === W_NS;
134769
+ const id = hasValidIdAttribute ? parseRevisionWId(idAttributes[0].value) : null;
134770
+ const hasValidAuthorAttribute = authorAttributes.length === 1 && authorAttributes[0].uri === W_NS;
134771
+ const author = hasValidAuthorAttribute ? authorAttributes[0].value : "";
134772
+ const hasValidDateAttributes = dateAttributes.every((attribute) => attribute.uri === W_NS && isValidRevisionDate(attribute.value));
134773
+ if (!hasValidIdAttribute || !hasValidAuthorAttribute || id === null || !author || !hasValidDateAttributes) {
134774
+ return null;
134775
+ }
134776
+ return { id, author, date: dateAttributes[0]?.value };
134777
+ }
134764
134778
  function parseDirectRunSequence(xml, allowRevisions) {
134765
134779
  const revisions = [];
134766
134780
  const stack = [];
@@ -134815,21 +134829,13 @@ function parseDirectRunSequence(xml, allowRevisions) {
134815
134829
  return;
134816
134830
  }
134817
134831
  if (allowRevisions && tag.uri === W_NS && (tag.local === "ins" || tag.local === "del") && !tag.isSelfClosing) {
134818
- const attributes = Object.values(tag.attributes);
134819
- const idAttributes = attributes.filter((attribute) => attribute.local === "id");
134820
- const authorAttributes = attributes.filter((attribute) => attribute.local === "author");
134821
- const dateAttributes = attributes.filter((attribute) => attribute.local === "date");
134822
- const hasValidIdAttribute = idAttributes.length === 1 && idAttributes[0].uri === W_NS;
134823
- const idValue = hasValidIdAttribute ? idAttributes[0].value : "";
134824
- const id = parseRevisionWId(idValue);
134825
- const hasValidAuthorAttribute = authorAttributes.length === 1 && authorAttributes[0].uri === W_NS;
134826
- const author = hasValidAuthorAttribute ? authorAttributes[0].value : "";
134827
- if (!hasValidIdAttribute || !hasValidAuthorAttribute || id === null || !author || dateAttributes.some((attribute) => attribute.uri !== W_NS || !isValidRevisionDate(attribute.value)))
134832
+ const marker = parseRevisionMarkerAttributes(Object.values(tag.attributes));
134833
+ if (!marker)
134828
134834
  valid = false;
134829
134835
  activeRevision = tag.local;
134830
134836
  activeRevisionRunCount = 0;
134831
- if (id !== null)
134832
- revisions.push({ kind: tag.local, wId: id, author });
134837
+ if (marker)
134838
+ revisions.push({ kind: tag.local, wId: marker.id, author: marker.author });
134833
134839
  stack.push("revision");
134834
134840
  return;
134835
134841
  }
@@ -134977,6 +134983,116 @@ function sameNoteMarkerRunXml(base2, target) {
134977
134983
  function inspectDirectParagraphRevisionRuns(xml) {
134978
134984
  return parseDirectRunSequence(xml, true);
134979
134985
  }
134986
+ function inspectDirectRunSequence(xml) {
134987
+ return parseDirectRunSequence(xml, false);
134988
+ }
134989
+ function parseParagraphMarkRevisionMarker(pPrXml) {
134990
+ if (pPrXml === "")
134991
+ return null;
134992
+ let valid = true;
134993
+ const stack = [];
134994
+ let hasSectPr = false;
134995
+ let markerCount = 0;
134996
+ let marker = null;
134997
+ const parser = new import_saxes3.SaxesParser({
134998
+ xmlns: true,
134999
+ additionalNamespaces: replayAdditionalNamespaces(pPrXml)
135000
+ });
135001
+ parser.on("error", () => {
135002
+ valid = false;
135003
+ });
135004
+ parser.on("opentag", (tag) => {
135005
+ const parent = stack.at(-1);
135006
+ const grandparent = stack.at(-2);
135007
+ if (parent === undefined && (tag.local !== "pPr" || tag.uri !== W_NS))
135008
+ valid = false;
135009
+ if (tag.uri === W_NS && tag.local === "sectPr")
135010
+ hasSectPr = true;
135011
+ const parentIsLiveRPr = stack.length === 2 && parent !== undefined && parent.uri === W_NS && parent.local === "rPr" && grandparent !== undefined && grandparent.uri === W_NS && grandparent.local === "pPr";
135012
+ if (parentIsLiveRPr && tag.uri === W_NS && (tag.local === "ins" || tag.local === "del")) {
135013
+ markerCount += 1;
135014
+ if (!tag.isSelfClosing) {
135015
+ valid = false;
135016
+ } else {
135017
+ const attrs = parseRevisionMarkerAttributes(Object.values(tag.attributes));
135018
+ if (!attrs || marker !== null) {
135019
+ valid = false;
135020
+ } else {
135021
+ marker = { kind: tag.local, wId: attrs.id, author: attrs.author, date: attrs.date };
135022
+ }
135023
+ }
135024
+ } else if (parentIsLiveRPr && tag.uri === W_NS && (tag.local === "moveFrom" || tag.local === "moveTo")) {
135025
+ valid = false;
135026
+ }
135027
+ stack.push({ uri: tag.uri ?? "", local: tag.local ?? "" });
135028
+ });
135029
+ parser.on("closetag", () => {
135030
+ stack.pop();
135031
+ });
135032
+ try {
135033
+ parser.write(pPrXml).close();
135034
+ } catch {
135035
+ valid = false;
135036
+ }
135037
+ if (!valid || stack.length !== 0 || hasSectPr || markerCount !== 1 || marker === null)
135038
+ return null;
135039
+ return marker;
135040
+ }
135041
+ function removeProvenParagraphMarkMarker(xml, marker) {
135042
+ const baseBindings = new Map([["w", W_NS]]);
135043
+ const stack = [];
135044
+ let removal = null;
135045
+ let position = 0;
135046
+ while (position < xml.length) {
135047
+ const start = xml.indexOf("<", position);
135048
+ if (start < 0)
135049
+ break;
135050
+ if (xml.startsWith("<!--", start) || xml.startsWith("<![CDATA[", start) || xml.startsWith("<?", start)) {
135051
+ return null;
135052
+ }
135053
+ const end = findXmlTagEnd2(xml, start);
135054
+ if (end < 0)
135055
+ return null;
135056
+ const rawTag = xml.slice(start, end + 1);
135057
+ if (rawTag.startsWith("</")) {
135058
+ const close = /^<\/\s*([A-Za-z_][\w.-]*(?::[A-Za-z_][\w.-]*)?)\s*>$/.exec(rawTag);
135059
+ if (!close || stack.pop()?.qname !== close[1])
135060
+ return null;
135061
+ position = end + 1;
135062
+ continue;
135063
+ }
135064
+ const parsed = parseXmlStartTag(rawTag);
135065
+ if (!parsed)
135066
+ return null;
135067
+ const bindings = new Map(stack.at(-1)?.bindings ?? baseBindings);
135068
+ for (const attribute of parsed.attributes) {
135069
+ if (attribute.qname === "xmlns")
135070
+ bindings.set("", attribute.value);
135071
+ else if (attribute.prefix === "xmlns")
135072
+ bindings.set(attribute.localName, attribute.value);
135073
+ }
135074
+ const namespaceUri = bindings.get(parsed.prefix) ?? "";
135075
+ const parentEntry = stack.at(-1);
135076
+ const grandparentEntry = stack.at(-2);
135077
+ const isLiveRPrChild = stack.length === 2 && parentEntry?.localName === "rPr" && grandparentEntry?.localName === "pPr";
135078
+ if (isLiveRPrChild && namespaceUri === W_NS && parsed.localName === marker.kind && parsed.selfClosing) {
135079
+ const idValue = parsed.attributes.find((attribute) => attribute.localName === "id" && (bindings.get(attribute.prefix) ?? "") === W_NS)?.value;
135080
+ const authorValue = parsed.attributes.find((attribute) => attribute.localName === "author" && (bindings.get(attribute.prefix) ?? "") === W_NS)?.value;
135081
+ const dateValue = parsed.attributes.find((attribute) => attribute.localName === "date" && (bindings.get(attribute.prefix) ?? "") === W_NS)?.value;
135082
+ if (parseRevisionWId(idValue ?? "") === marker.wId && authorValue === marker.author && dateValue === marker.date) {
135083
+ if (removal !== null)
135084
+ return null;
135085
+ removal = { start, end: end + 1 };
135086
+ }
135087
+ }
135088
+ if (!parsed.selfClosing)
135089
+ stack.push({ qname: parsed.qname, localName: parsed.localName, bindings });
135090
+ position = end + 1;
135091
+ }
135092
+ if (stack.length > 0 || removal === null)
135093
+ return null;
135094
+ return xml.slice(0, removal.start) + xml.slice(removal.end);
135095
+ }
134980
135096
  function trackedAnnotationEntries(annotations) {
134981
135097
  return annotations?.find((capture) => capture.family === "tracked-changes")?.entries ?? [];
134982
135098
  }
@@ -135367,9 +135483,27 @@ function validateCompareReplayPayload(payload, options = {}) {
135367
135483
  if (!dependencyResult.ok)
135368
135484
  return dependencyResult;
135369
135485
  if (payload.targetParagraphPropertiesXml !== undefined) {
135370
- const result = validateParagraphProperties(payload.targetParagraphPropertiesXml);
135371
- if (!result.ok)
135372
- return result;
135486
+ if (payload.targetParagraphMarkRevisionReplay !== undefined) {
135487
+ const proof = payload.targetParagraphMarkRevisionReplay;
135488
+ if (proof.policy !== "preserve-target-paragraph-mark-revision") {
135489
+ return { ok: false, reason: "target paragraph mark revision replay policy is incomplete" };
135490
+ }
135491
+ const marker = parseParagraphMarkRevisionMarker(payload.targetParagraphPropertiesXml);
135492
+ if (!marker || marker.kind !== proof.kind || marker.wId !== proof.wId || marker.author !== proof.author || marker.date !== proof.date) {
135493
+ return { ok: false, reason: "target paragraph mark revision replay proof does not match the target paragraph properties" };
135494
+ }
135495
+ const strippedXml = removeProvenParagraphMarkMarker(payload.targetParagraphPropertiesXml, marker);
135496
+ if (strippedXml === null) {
135497
+ return { ok: false, reason: "target paragraph mark revision replay proof could not be isolated from the target paragraph properties" };
135498
+ }
135499
+ const result = validateParagraphProperties(strippedXml);
135500
+ if (!result.ok)
135501
+ return result;
135502
+ } else {
135503
+ const result = validateParagraphProperties(payload.targetParagraphPropertiesXml);
135504
+ if (!result.ok)
135505
+ return result;
135506
+ }
135373
135507
  }
135374
135508
  if (payload.targetRevisionReplay !== undefined) {
135375
135509
  if (payload.targetRevisionReplay.policy !== "preserve-target-revision-set" || payload.targetRunXml === undefined) {
@@ -136167,14 +136301,27 @@ function validateBodyOperation(operation, label, problems, replayOptions = {}) {
136167
136301
  }
136168
136302
  }
136169
136303
  }
136170
- const carriesReplayPayload = operation.targetParagraphPropertiesXml !== undefined || operation.targetRunXml !== undefined || operation.replayDependencies !== undefined || operation.replayDependencyProofFailed !== undefined;
136171
- if (carriesReplayPayload && hasValidReplayPayloadShape && hasValidReplayShape) {
136304
+ let hasValidParagraphMarkReplayShape = operation.targetParagraphMarkRevisionReplay === undefined;
136305
+ if (operation.targetParagraphMarkRevisionReplay !== undefined) {
136306
+ const replay = operation.targetParagraphMarkRevisionReplay;
136307
+ const hasValidShape = isRecord9(replay) && replay.policy === "preserve-target-paragraph-mark-revision" && (replay.kind === "ins" || replay.kind === "del") && typeof replay.wId === "number" && Number.isSafeInteger(replay.wId) && isNonEmptyString2(replay.author) && (replay.date === undefined || typeof replay.date === "string");
136308
+ hasValidParagraphMarkReplayShape = hasValidShape;
136309
+ if (!hasValidShape) {
136310
+ problems.push(`${label}.targetParagraphMarkRevisionReplay: invalid target paragraph mark revision replay`);
136311
+ }
136312
+ if (operation.kind === "edit" || operation.kind === "formatEdit") {
136313
+ problems.push(`${label}.targetParagraphMarkRevisionReplay: ${operation.kind} does not support paragraph mark revision replay`);
136314
+ hasValidParagraphMarkReplayShape = false;
136315
+ }
136316
+ }
136317
+ const carriesReplayPayload = operation.kind !== "delete" && (operation.targetParagraphPropertiesXml !== undefined || operation.targetRunXml !== undefined || operation.replayDependencies !== undefined || operation.replayDependencyProofFailed !== undefined || operation.targetParagraphMarkRevisionReplay !== undefined);
136318
+ if (carriesReplayPayload && hasValidReplayPayloadShape && hasValidReplayShape && hasValidParagraphMarkReplayShape) {
136172
136319
  const proof = validateCompareReplayPayload(operation, {
136173
136320
  ...replayOptions,
136174
136321
  expectedCurrentText: operation.kind !== "delete" && typeof operation.text === "string" ? operation.text : undefined
136175
136322
  });
136176
136323
  if (!proof.ok) {
136177
- const field = operation.targetRevisionReplay === undefined ? "replayPayload" : "targetRevisionReplay";
136324
+ const field = operation.targetRevisionReplay === undefined ? operation.targetParagraphMarkRevisionReplay === undefined ? "replayPayload" : "targetParagraphMarkRevisionReplay" : "targetRevisionReplay";
136178
136325
  problems.push(`${label}.${field}: ${proof.reason}`);
136179
136326
  }
136180
136327
  }
@@ -136940,8 +137087,8 @@ function validatePlanDispositions(value, steps, problems) {
136940
137087
  }
136941
137088
  });
136942
137089
  }
136943
- const bodyHasTargetRevisionReplay = Array.isArray(value.bodyOperations) && value.bodyOperations.some((operation) => isRecord9(operation) && operation.targetRevisionReplay !== undefined);
136944
- const storyHasTargetRevisionReplay = Array.isArray(value.storyOperations) && value.storyOperations.some((group) => isRecord9(group) && Array.isArray(group.operations) && group.operations.some((operation) => isRecord9(operation) && operation.targetRevisionReplay !== undefined));
137090
+ const bodyHasTargetRevisionReplay = Array.isArray(value.bodyOperations) && value.bodyOperations.some((operation) => isRecord9(operation) && (operation.targetRevisionReplay !== undefined || operation.targetParagraphMarkRevisionReplay !== undefined));
137091
+ const storyHasTargetRevisionReplay = Array.isArray(value.storyOperations) && value.storyOperations.some((group) => isRecord9(group) && Array.isArray(group.operations) && group.operations.some((operation) => isRecord9(operation) && (operation.targetRevisionReplay !== undefined || operation.targetParagraphMarkRevisionReplay !== undefined)));
136945
137092
  if ((bodyHasTargetRevisionReplay || storyHasTargetRevisionReplay) && dispositions.get("tracked-changes") !== "supported") {
136946
137093
  problems.push("target revision replay requires a supported tracked-changes step");
136947
137094
  }
@@ -139035,6 +139182,33 @@ function matchingRevisionAnnotationKeys(annotations, revisions, partUri, paragra
139035
139182
  }
139036
139183
  return keys;
139037
139184
  }
139185
+ function matchingParagraphMarkAnnotationKey(annotations, marker, structuralKind, paragraphStructuralAnnotationKeys) {
139186
+ const entries = annotations?.find((capture) => capture.family === "tracked-changes")?.entries ?? [];
139187
+ const exactKeys = paragraphStructuralAnnotationKeys === undefined ? null : new Set(paragraphStructuralAnnotationKeys);
139188
+ const matches = entries.filter((entry) => entry.label === `structural revision ${structuralKind}` && (entry.semanticKey?.startsWith(`structural:${structuralKind}|`) ?? false) && entry.key.includes(`|${marker.wId}|`) && (exactKeys === null || exactKeys.has(entry.key)));
139189
+ return matches.length === 1 ? matches[0].key : null;
139190
+ }
139191
+ function paragraphMarkTargetRevisionReplay(entry, annotations) {
139192
+ if (!entry)
139193
+ return null;
139194
+ const marker = parseParagraphMarkRevisionMarker(entry.paragraphPropertiesXml ?? "");
139195
+ if (!marker)
139196
+ return null;
139197
+ const structuralKind = marker.kind === "ins" ? "paragraph-mark-insertion" : "paragraph-mark-deletion";
139198
+ const key2 = matchingParagraphMarkAnnotationKey(annotations, marker, structuralKind, entry.structuralChangeAnnotationKeys);
139199
+ if (!key2)
139200
+ return null;
139201
+ return {
139202
+ key: key2,
139203
+ replay: {
139204
+ policy: "preserve-target-paragraph-mark-revision",
139205
+ kind: marker.kind,
139206
+ wId: marker.wId,
139207
+ author: marker.author,
139208
+ date: marker.date
139209
+ }
139210
+ };
139211
+ }
139038
139212
  function attachExactTargetRevisionReplay(operations, baseEntries, targetEntries, entityMatch, baseAnnotations, targetAnnotations, basePartUri, targetPartUri, entityId = (blockId) => blockId) {
139039
139213
  if (!entityMatch) {
139040
139214
  return {
@@ -139053,51 +139227,69 @@ function attachExactTargetRevisionReplay(operations, baseEntries, targetEntries,
139053
139227
  const replayOperations = operations.map((operation) => {
139054
139228
  if (operation.kind === "insert" || operation.kind === "insertAtStart") {
139055
139229
  const targetEntry2 = targetById.get(entityId(operation.blockId));
139056
- if (!targetEntry2)
139057
- return operation;
139058
- const targetInspection2 = inspectDirectParagraphRevisionRuns(targetEntry2.runXml ?? "");
139059
- if (!targetInspection2 || targetInspection2.revisions.length === 0 || targetInspection2.currentText !== targetEntry2.text) {
139060
- return operation;
139230
+ let targetRevisionReplayPatch;
139231
+ let targetParagraphMarkRevisionReplayPatch;
139232
+ if (targetEntry2) {
139233
+ const targetInspection2 = inspectDirectParagraphRevisionRuns(targetEntry2.runXml ?? "");
139234
+ if (targetInspection2 && targetInspection2.revisions.length > 0 && targetInspection2.currentText === targetEntry2.text) {
139235
+ const targetAnnotationKeys2 = matchingRevisionAnnotationKeys(targetAnnotations, targetInspection2.revisions, targetPartUri, targetEntry2.trackedChangeAnnotationKeys);
139236
+ if (targetAnnotationKeys2) {
139237
+ for (const key2 of targetAnnotationKeys2)
139238
+ coveredTargetAnnotations.add(key2);
139239
+ changedTrackedXmlReplayed = true;
139240
+ targetRevisionReplayPatch = {
139241
+ targetRevisionReplay: {
139242
+ policy: "preserve-target-revision-set",
139243
+ structuralAction: "insert",
139244
+ originalText: targetInspection2.originalText,
139245
+ revisionWIds: targetInspection2.revisions.map((revision) => revision.wId)
139246
+ }
139247
+ };
139248
+ }
139249
+ }
139250
+ const markResult = paragraphMarkTargetRevisionReplay(targetEntry2, targetAnnotations);
139251
+ if (markResult) {
139252
+ coveredTargetAnnotations.add(markResult.key);
139253
+ changedTrackedXmlReplayed = true;
139254
+ targetParagraphMarkRevisionReplayPatch = { targetParagraphMarkRevisionReplay: markResult.replay };
139255
+ }
139061
139256
  }
139062
- const targetAnnotationKeys2 = matchingRevisionAnnotationKeys(targetAnnotations, targetInspection2.revisions, targetPartUri, targetEntry2.trackedChangeAnnotationKeys);
139063
- if (!targetAnnotationKeys2)
139257
+ if (!targetRevisionReplayPatch && !targetParagraphMarkRevisionReplayPatch)
139064
139258
  return operation;
139065
- for (const key2 of targetAnnotationKeys2)
139066
- coveredTargetAnnotations.add(key2);
139067
- changedTrackedXmlReplayed = true;
139068
- return {
139069
- ...operation,
139070
- targetRevisionReplay: {
139071
- policy: "preserve-target-revision-set",
139072
- structuralAction: "insert",
139073
- originalText: targetInspection2.originalText,
139074
- revisionWIds: targetInspection2.revisions.map((revision) => revision.wId)
139075
- }
139076
- };
139259
+ return { ...operation, ...targetRevisionReplayPatch, ...targetParagraphMarkRevisionReplayPatch };
139077
139260
  }
139078
139261
  if (operation.kind === "delete") {
139079
139262
  const baseEntry2 = baseById.get(entityId(operation.blockId));
139080
- if (!baseEntry2)
139081
- return operation;
139082
- const baseInspection2 = inspectDirectParagraphRevisionRuns(baseEntry2.runXml ?? "");
139083
- if (!baseInspection2 || baseInspection2.revisions.length === 0 || baseInspection2.currentText !== baseEntry2.text) {
139084
- return operation;
139263
+ let targetRevisionReplayPatch;
139264
+ let targetParagraphMarkRevisionReplayPatch;
139265
+ if (baseEntry2) {
139266
+ const baseInspection2 = inspectDirectParagraphRevisionRuns(baseEntry2.runXml ?? "");
139267
+ if (baseInspection2 && baseInspection2.revisions.length > 0 && baseInspection2.currentText === baseEntry2.text) {
139268
+ const baseAnnotationKeys2 = matchingRevisionAnnotationKeys(baseAnnotations, baseInspection2.revisions, basePartUri, baseEntry2.trackedChangeAnnotationKeys);
139269
+ if (baseAnnotationKeys2) {
139270
+ for (const key2 of baseAnnotationKeys2)
139271
+ coveredBaseAnnotations.add(key2);
139272
+ changedTrackedXmlReplayed = true;
139273
+ targetRevisionReplayPatch = {
139274
+ targetRevisionReplay: {
139275
+ policy: "preserve-target-revision-set",
139276
+ structuralAction: "delete",
139277
+ originalText: baseInspection2.originalText,
139278
+ revisionWIds: baseInspection2.revisions.map((revision) => revision.wId)
139279
+ }
139280
+ };
139281
+ }
139282
+ }
139283
+ const markResult = paragraphMarkTargetRevisionReplay(baseEntry2, baseAnnotations);
139284
+ if (markResult) {
139285
+ coveredBaseAnnotations.add(markResult.key);
139286
+ changedTrackedXmlReplayed = true;
139287
+ targetParagraphMarkRevisionReplayPatch = { targetParagraphMarkRevisionReplay: markResult.replay };
139288
+ }
139085
139289
  }
139086
- const baseAnnotationKeys2 = matchingRevisionAnnotationKeys(baseAnnotations, baseInspection2.revisions, basePartUri, baseEntry2.trackedChangeAnnotationKeys);
139087
- if (!baseAnnotationKeys2)
139290
+ if (!targetRevisionReplayPatch && !targetParagraphMarkRevisionReplayPatch)
139088
139291
  return operation;
139089
- for (const key2 of baseAnnotationKeys2)
139090
- coveredBaseAnnotations.add(key2);
139091
- changedTrackedXmlReplayed = true;
139092
- return {
139093
- ...operation,
139094
- targetRevisionReplay: {
139095
- policy: "preserve-target-revision-set",
139096
- structuralAction: "delete",
139097
- originalText: baseInspection2.originalText,
139098
- revisionWIds: baseInspection2.revisions.map((revision) => revision.wId)
139099
- }
139100
- };
139292
+ return { ...operation, ...targetRevisionReplayPatch, ...targetParagraphMarkRevisionReplayPatch };
139101
139293
  }
139102
139294
  const baseEntryId = entityId(operation.blockId);
139103
139295
  const baseEntry = baseById.get(baseEntryId);
@@ -222543,7 +222735,7 @@ function hasTerminalTrackedParagraphDeletion(state, groups, storyPackageOperatio
222543
222735
  if (!index)
222544
222736
  return false;
222545
222737
  return group.bodySteps.some((step2, stepIndex) => {
222546
- if (step2.kind !== "delete" || step2.targetRevisionReplay !== undefined)
222738
+ if (step2.kind !== "delete" || step2.targetRevisionReplay !== undefined || step2.targetParagraphMarkRevisionReplay !== undefined)
222547
222739
  return false;
222548
222740
  if (isBodyReplayNoteReferenceRemoval(state, group.storyId, step2, storyPackageOperations))
222549
222741
  return false;
@@ -222667,7 +222859,8 @@ function normalizeCompareBodyStep(step2, sectionSteps, referenceSteps, allowedNo
222667
222859
  targetParagraphPropertiesXml,
222668
222860
  targetRunXml,
222669
222861
  replayDependencies: "replayDependencies" in step2 ? step2.replayDependencies : undefined,
222670
- targetRevisionReplay: "targetRevisionReplay" in step2 ? step2.targetRevisionReplay : undefined
222862
+ targetRevisionReplay: "targetRevisionReplay" in step2 ? step2.targetRevisionReplay : undefined,
222863
+ targetParagraphMarkRevisionReplay: "targetParagraphMarkRevisionReplay" in step2 ? step2.targetParagraphMarkRevisionReplay : undefined
222671
222864
  }, sectionSteps, referenceSteps, allowedNoteReferences, step2.text, baseRunXml, noteMarkerFamily) ? normalized : null;
222672
222865
  }
222673
222866
  function liveCompareBodyRunXml(state, storyId, blockId) {
@@ -223165,8 +223358,8 @@ function runBodyStep(input, storyId, noteId, step2, changeMode, options, pushHis
223165
223358
  if (!hasSuccessor)
223166
223359
  return rejected14(txId, "unsupported-context");
223167
223360
  }
223168
- if (step2.targetRevisionReplay !== undefined) {
223169
- if (step2.targetRevisionReplay.structuralAction !== "delete") {
223361
+ if (step2.targetRevisionReplay !== undefined || step2.targetParagraphMarkRevisionReplay !== undefined) {
223362
+ if (step2.targetRevisionReplay !== undefined && step2.targetRevisionReplay.structuralAction !== "delete") {
223170
223363
  return rejected14(txId, "unsupported-context");
223171
223364
  }
223172
223365
  const entry = getStoryParagraphIndexFromState(state, storyId)?.byParaId(step2.blockId);
@@ -223305,7 +223498,10 @@ function prepareTrackedTerminalParagraphDeleteAtState(input) {
223305
223498
  }
223306
223499
  function resolveExactStructuralRevisionDeletion(state, storyId, step2) {
223307
223500
  const replay = step2.targetRevisionReplay;
223308
- if (!replay || replay.structuralAction !== "delete")
223501
+ const markReplay = step2.targetParagraphMarkRevisionReplay;
223502
+ if (replay !== undefined && replay.structuralAction !== "delete")
223503
+ return null;
223504
+ if (replay === undefined && markReplay === undefined)
223309
223505
  return null;
223310
223506
  const entry = getStoryParagraphIndexFromState(state, storyId)?.byParaId(step2.blockId);
223311
223507
  const bytes = entry ? state.packageBytes.get(entry.partUri) : undefined;
@@ -223313,9 +223509,22 @@ function resolveExactStructuralRevisionDeletion(state, storyId, step2) {
223313
223509
  return null;
223314
223510
  const paraXml = TD59.decode(bytes.subarray(entry.byteStart, entry.byteEnd));
223315
223511
  const wrapper = readParagraphWrapper(paraXml, step2.blockId, bytes, entry.byteStart);
223316
- const inspection = inspectDirectParagraphRevisionRuns(stripElements(paraXml.slice(wrapper.contentStart, paraXml.lastIndexOf("</")), "pPr"));
223317
- if (!inspection || inspection.originalText !== replay.originalText || JSON.stringify(inspection.revisions.map((revision) => revision.wId)) !== JSON.stringify(replay.revisionWIds))
223318
- return null;
223512
+ const runContent = stripElements(paraXml.slice(wrapper.contentStart, paraXml.lastIndexOf("</")), "pPr");
223513
+ if (replay !== undefined && replay.structuralAction === "delete") {
223514
+ const inspection = inspectDirectParagraphRevisionRuns(runContent);
223515
+ if (!inspection || inspection.originalText !== replay.originalText || JSON.stringify(inspection.revisions.map((revision) => revision.wId)) !== JSON.stringify(replay.revisionWIds))
223516
+ return null;
223517
+ } else {
223518
+ const inspection = inspectDirectRunSequence(runContent);
223519
+ if (!inspection || inspection.revisions.length > 0)
223520
+ return null;
223521
+ }
223522
+ if (markReplay !== undefined) {
223523
+ const pPrXml = findFirstElement(paraXml, "pPr")?.xml ?? "";
223524
+ const marker = parseParagraphMarkRevisionMarker(pPrXml);
223525
+ if (!marker || marker.kind !== markReplay.kind || marker.wId !== markReplay.wId || marker.author !== markReplay.author || marker.date !== markReplay.date)
223526
+ return null;
223527
+ }
223319
223528
  const parsedPart = collectXmlElementRanges(TD59.decode(bytes));
223320
223529
  const paragraphCharStart = TD59.decode(bytes.subarray(0, entry.byteStart)).length;
223321
223530
  const paragraphRange = parsedPart.ranges.find((range) => range.start === paragraphCharStart && range.tag.namespaceUri === NS_W && range.tag.localName === "p");
@@ -223330,7 +223539,7 @@ function resolveExactStructuralRevisionDeletion(state, storyId, step2) {
223330
223539
  byteEnd: entry.byteEnd,
223331
223540
  charStart: paragraphRange.start,
223332
223541
  charEnd: paragraphRange.end,
223333
- revisionWIds: replay.revisionWIds
223542
+ revisionWIds: [...replay?.revisionWIds ?? [], ...markReplay ? [markReplay.wId] : []]
223334
223543
  };
223335
223544
  }
223336
223545
  function runTargetRevisionReplayCommit(input, storyId, step2, options, pushHistory) {
@@ -223458,7 +223667,7 @@ function incomingRevisionIdsCollide(input, targetPartUri, targetStart, targetEnd
223458
223667
  return true;
223459
223668
  if (liveTargetRunXml) {
223460
223669
  const previousOwner = parseTargetRevisionReplayOwner(transferFrom);
223461
- const previousInspection = previousOwner ? inspectDirectParagraphRevisionRuns(previousOwner.targetRunXml) : null;
223670
+ const previousInspection = previousOwner?.targetRunXml !== undefined ? inspectDirectParagraphRevisionRuns(previousOwner.targetRunXml) : null;
223462
223671
  if (!previousInspection)
223463
223672
  return true;
223464
223673
  for (const { wId } of previousInspection.revisions) {
@@ -223500,7 +223709,7 @@ function transferableInPlaceRevisionReplayOwner(input) {
223500
223709
  return null;
223501
223710
  const previousKey = parseTargetRevisionReplayOwner(previousOwner);
223502
223711
  const nextKey = parseTargetRevisionReplayOwner(input.replayOwner);
223503
- if (!previousKey || !nextKey || previousKey.partUri !== input.targetPartUri || nextKey.partUri !== input.targetPartUri || previousKey.blockId !== nextKey.blockId || previousKey.targetParagraphPropertiesXml !== nextKey.targetParagraphPropertiesXml || !sameTargetRevisionReplayProvenance(previousKey.targetRevisionReplay, nextKey.targetRevisionReplay))
223712
+ if (!previousKey || !nextKey || previousKey.partUri !== input.targetPartUri || nextKey.partUri !== input.targetPartUri || previousKey.blockId !== nextKey.blockId || previousKey.targetParagraphPropertiesXml !== nextKey.targetParagraphPropertiesXml || !sameTargetRevisionReplayProvenance(previousKey.targetRevisionReplay, nextKey.targetRevisionReplay) || !sameTargetParagraphMarkRevisionReplay(previousKey.targetParagraphMarkRevisionReplay, nextKey.targetParagraphMarkRevisionReplay) || previousKey.targetRunXml === undefined || nextKey.targetRunXml === undefined)
223504
223713
  return null;
223505
223714
  const previousInspection = inspectDirectParagraphRevisionRuns(previousKey.targetRunXml);
223506
223715
  if (!previousInspection || !liveInspection || JSON.stringify(previousInspection) !== JSON.stringify(liveInspection)) {
@@ -223534,7 +223743,7 @@ function transferableRevisionReplayOwner(input) {
223534
223743
  const nextKey = parseTargetRevisionReplayOwner(input.replayOwner);
223535
223744
  if (!previousKey || !nextKey || previousKey.blockId !== nextKey.blockId)
223536
223745
  return null;
223537
- if (previousKey.targetParagraphPropertiesXml !== nextKey.targetParagraphPropertiesXml || previousKey.targetRunXml !== nextKey.targetRunXml || !sameTargetRevisionReplaySet(previousKey.targetRevisionReplay, nextKey.targetRevisionReplay))
223746
+ if (previousKey.targetParagraphPropertiesXml !== nextKey.targetParagraphPropertiesXml || previousKey.targetRunXml !== nextKey.targetRunXml || !sameTargetRevisionReplaySet(previousKey.targetRevisionReplay, nextKey.targetRevisionReplay) || !sameTargetParagraphMarkRevisionReplay(previousKey.targetParagraphMarkRevisionReplay, nextKey.targetParagraphMarkRevisionReplay))
223538
223747
  return null;
223539
223748
  const previousDeletion = input.scheduledDeletions.find((deletion) => deletion.partUri === previousKey.partUri && deletion.blockId === previousKey.blockId && JSON.stringify(deletion.revisionWIds) === JSON.stringify(input.revisionWIds));
223540
223749
  return previousDeletion && input.revisionWIds.every((id) => previousDeletion.completeLiveCarrierWIds?.includes(id)) ? previousOwner : null;
@@ -223542,21 +223751,24 @@ function transferableRevisionReplayOwner(input) {
223542
223751
  function parseTargetRevisionReplayOwner(owner) {
223543
223752
  try {
223544
223753
  const key2 = JSON.parse(owner);
223545
- if (!Array.isArray(key2) || key2.length !== 5 || typeof key2[0] !== "string" || typeof key2[1] !== "string" || typeof key2[3] !== "string") {
223754
+ if (!Array.isArray(key2) || key2.length !== 6 || typeof key2[0] !== "string" || typeof key2[1] !== "string" || key2[3] !== null && typeof key2[3] !== "string") {
223546
223755
  return null;
223547
223756
  }
223548
223757
  return {
223549
223758
  partUri: key2[0],
223550
223759
  blockId: key2[1],
223551
223760
  targetParagraphPropertiesXml: key2[2],
223552
- targetRunXml: key2[3],
223553
- targetRevisionReplay: key2[4]
223761
+ targetRunXml: key2[3] === null ? undefined : key2[3],
223762
+ targetRevisionReplay: key2[4] === null ? undefined : key2[4],
223763
+ targetParagraphMarkRevisionReplay: key2[5] === null ? undefined : key2[5]
223554
223764
  };
223555
223765
  } catch {
223556
223766
  return null;
223557
223767
  }
223558
223768
  }
223559
223769
  function sameTargetRevisionReplayProvenance(left, right) {
223770
+ if (left === undefined && right === undefined)
223771
+ return true;
223560
223772
  if (!left || typeof left !== "object" || !right || typeof right !== "object")
223561
223773
  return false;
223562
223774
  const leftReplay = left;
@@ -223564,12 +223776,23 @@ function sameTargetRevisionReplayProvenance(left, right) {
223564
223776
  return leftReplay.policy === "preserve-target-revision-set" && rightReplay.policy === "preserve-target-revision-set" && leftReplay.originalText === rightReplay.originalText;
223565
223777
  }
223566
223778
  function sameTargetRevisionReplaySet(left, right) {
223779
+ if (left === undefined && right === undefined)
223780
+ return true;
223567
223781
  if (!sameTargetRevisionReplayProvenance(left, right))
223568
223782
  return false;
223569
223783
  const leftReplay = left;
223570
223784
  const rightReplay = right;
223571
223785
  return Array.isArray(leftReplay.revisionWIds) && Array.isArray(rightReplay.revisionWIds) && JSON.stringify(leftReplay.revisionWIds) === JSON.stringify(rightReplay.revisionWIds);
223572
223786
  }
223787
+ function sameTargetParagraphMarkRevisionReplay(left, right) {
223788
+ if (left === undefined && right === undefined)
223789
+ return true;
223790
+ if (!left || typeof left !== "object" || !right || typeof right !== "object")
223791
+ return false;
223792
+ const leftReplay = left;
223793
+ const rightReplay = right;
223794
+ return leftReplay.policy === "preserve-target-paragraph-mark-revision" && rightReplay.policy === "preserve-target-paragraph-mark-revision" && leftReplay.kind === rightReplay.kind && leftReplay.wId === rightReplay.wId && leftReplay.author === rightReplay.author && leftReplay.date === rightReplay.date;
223795
+ }
223573
223796
  function applyRevisionReplayOwnershipTransfers(state, transfers) {
223574
223797
  const reservations = state.idReservations.revisionWIds.replayOwners;
223575
223798
  for (const transfer of transfers) {
@@ -223655,22 +223878,36 @@ function targetRevisionReplayOwner(partUri, step2, fallbackParagraphPropertiesXm
223655
223878
  step2.blockId,
223656
223879
  step2.targetParagraphPropertiesXml ?? fallbackParagraphPropertiesXml ?? null,
223657
223880
  step2.targetRunXml,
223658
- step2.targetRevisionReplay
223881
+ step2.targetRevisionReplay,
223882
+ "targetParagraphMarkRevisionReplay" in step2 ? step2.targetParagraphMarkRevisionReplay : undefined
223659
223883
  ]);
223660
223884
  }
223661
223885
  function prepareExactTargetRevisionInsert(input, partUri, insertByte, step2) {
223662
223886
  const replay = step2.targetRevisionReplay;
223663
- if (!replay)
223887
+ const markReplay = step2.targetParagraphMarkRevisionReplay;
223888
+ if (!replay && !markReplay)
223664
223889
  return null;
223665
- if (replay.structuralAction !== "insert" || !step2.targetRunXml)
223666
- return false;
223890
+ const revisionWIds = [];
223891
+ if (replay !== undefined) {
223892
+ if (replay.structuralAction !== "insert" || !step2.targetRunXml)
223893
+ return false;
223894
+ const inspection = inspectDirectParagraphRevisionRuns(step2.targetRunXml);
223895
+ if (!inspection || inspection.currentText !== step2.text || inspection.originalText !== replay.originalText || JSON.stringify(inspection.revisions.map((revision) => revision.wId)) !== JSON.stringify(replay.revisionWIds))
223896
+ return false;
223897
+ revisionWIds.push(...replay.revisionWIds);
223898
+ }
223899
+ if (markReplay !== undefined) {
223900
+ const marker = parseParagraphMarkRevisionMarker(step2.targetParagraphPropertiesXml ?? "");
223901
+ if (!marker || marker.kind !== markReplay.kind || marker.wId !== markReplay.wId || marker.author !== markReplay.author || marker.date !== markReplay.date)
223902
+ return false;
223903
+ revisionWIds.push(markReplay.wId);
223904
+ }
223667
223905
  const replayOwner = targetRevisionReplayOwner(partUri, step2);
223668
223906
  const ownershipTransfers = [];
223669
- const inspection = inspectDirectParagraphRevisionRuns(step2.targetRunXml);
223670
- if (!inspection || inspection.currentText !== step2.text || inspection.originalText !== replay.originalText || JSON.stringify(inspection.revisions.map((revision) => revision.wId)) !== JSON.stringify(replay.revisionWIds) || incomingRevisionIdsCollide(input, partUri, insertByte, insertByte, replay.revisionWIds, replayOwner, ownershipTransfers))
223907
+ if (incomingRevisionIdsCollide(input, partUri, insertByte, insertByte, revisionWIds, replayOwner, ownershipTransfers))
223671
223908
  return false;
223672
223909
  applyRevisionReplayOwnershipTransfers(input.state, ownershipTransfers);
223673
- for (const wId of replay.revisionWIds)
223910
+ for (const wId of revisionWIds)
223674
223911
  reserveRevisionWIdForReplay(input.state, wId, replayOwner);
223675
223912
  return true;
223676
223913
  }
@@ -358885,6 +359122,10 @@ function trackedChangeAnnotationKeysForParagraph(context, paragraph4) {
358885
359122
  const fragments = getSDDocumentSessionInternalTrackedChangeCatalog(context.session).byPart.get(paragraph4.partUri) ?? [];
358886
359123
  return fragments.filter((fragment3) => fragment3.storyId === paragraph4.storyId && fragment3.sourceByteStart >= paragraph4.byteStart && fragment3.sourceByteEnd <= paragraph4.byteEnd).map(trackedChangeAnnotationKey);
358887
359124
  }
359125
+ function structuralChangeAnnotationKeysForParagraph(context, paragraph4) {
359126
+ const fragments = getSDDocumentSessionInternalTrackedChangeCatalog(context.session).structuralByPart.get(paragraph4.partUri) ?? [];
359127
+ return fragments.filter((fragment3) => fragment3.storyId === paragraph4.storyId && (fragment3.sourceByteStart ?? fragment3.byteStart) >= paragraph4.byteStart && (fragment3.sourceByteEnd ?? fragment3.byteEnd) <= paragraph4.byteEnd).map((fragment3) => fragment3.entityKey);
359128
+ }
358888
359129
  function projectFieldsReferences(context) {
358889
359130
  const entries = [];
358890
359131
  let ordinal = 0;
@@ -359830,6 +360071,7 @@ function projectStories(context, slots) {
359830
360071
  runSignature: runSignatureByOrdinal.get(p.ordinal),
359831
360072
  runXml,
359832
360073
  trackedChangeAnnotationKeys: trackedChangeAnnotationKeysForParagraph(context, p),
360074
+ structuralChangeAnnotationKeys: structuralChangeAnnotationKeysForParagraph(context, p),
359833
360075
  paragraphPropertiesXml,
359834
360076
  paragraphPropertiesSignature: computeParagraphPropertiesSignature2(paragraphPropertiesXml)
359835
360077
  };
@@ -359915,6 +360157,7 @@ function projectBody(context) {
359915
360157
  runSignature: runSignatures[ordinal],
359916
360158
  runXml,
359917
360159
  trackedChangeAnnotationKeys: trackedChangeAnnotationKeysForParagraph(context, p),
360160
+ structuralChangeAnnotationKeys: structuralChangeAnnotationKeysForParagraph(context, p),
359918
360161
  paragraphPropertiesXml,
359919
360162
  paragraphPropertiesSignature: computeParagraphPropertiesSignature2(paragraphPropertiesXml)
359920
360163
  };
@@ -360139,7 +360382,7 @@ function applyComparePlan(context, plan, options = {}) {
360139
360382
  const appliedFamilySet = new Set;
360140
360383
  if (plan.bodyOperations.length > 0)
360141
360384
  appliedFamilySet.add("body");
360142
- const appliedTargetRevisionReplay = plan.bodyOperations.some((operation) => ("targetRevisionReplay" in operation) && operation.targetRevisionReplay !== undefined) || storyGroups.some((group) => group.bodySteps.some((step3) => step3.targetRevisionReplay !== undefined));
360385
+ const appliedTargetRevisionReplay = plan.bodyOperations.some((operation) => ("targetRevisionReplay" in operation) && operation.targetRevisionReplay !== undefined || ("targetParagraphMarkRevisionReplay" in operation) && operation.targetParagraphMarkRevisionReplay !== undefined) || storyGroups.some((group) => group.bodySteps.some((step3) => step3.targetRevisionReplay !== undefined || ("targetParagraphMarkRevisionReplay" in step3) && step3.targetParagraphMarkRevisionReplay !== undefined));
360143
360386
  if (appliedTargetRevisionReplay)
360144
360387
  appliedFamilySet.add("tracked-changes");
360145
360388
  for (const group of storyGroups) {
@@ -369817,16 +370060,19 @@ function validateFullDiffApplyConsistency(diff, payload, physicalPlan, canonical
369817
370060
  }
369818
370061
  return problems;
369819
370062
  }
370063
+ function hasAnyTargetRevisionReplay(operation) {
370064
+ return "targetRevisionReplay" in operation && operation.targetRevisionReplay !== undefined || "targetParagraphMarkRevisionReplay" in operation && operation.targetParagraphMarkRevisionReplay !== undefined;
370065
+ }
369820
370066
  function buildApplyOperationCounts(applyPlan) {
369821
370067
  const counts = new Map;
369822
370068
  let revisionReplayCount = 0;
369823
370069
  if (applyPlan.bodyOperations.length > 0) {
369824
370070
  counts.set("body", applyPlan.bodyOperations.length);
369825
- revisionReplayCount += applyPlan.bodyOperations.filter((operation) => ("targetRevisionReplay" in operation) && operation.targetRevisionReplay !== undefined).length;
370071
+ revisionReplayCount += applyPlan.bodyOperations.filter(hasAnyTargetRevisionReplay).length;
369826
370072
  }
369827
370073
  for (const group of applyPlan.storyOperations ?? []) {
369828
370074
  counts.set(group.family, (counts.get(group.family) ?? 0) + group.operations.length);
369829
- revisionReplayCount += group.operations.filter((operation) => ("targetRevisionReplay" in operation) && operation.targetRevisionReplay !== undefined).length;
370075
+ revisionReplayCount += group.operations.filter(hasAnyTargetRevisionReplay).length;
369830
370076
  }
369831
370077
  if (revisionReplayCount > 0)
369832
370078
  counts.set("tracked-changes", revisionReplayCount);
@@ -369837,8 +370083,8 @@ function buildApplyOperationCounts(applyPlan) {
369837
370083
  }
369838
370084
  function setRuntimeBodyOperationCounts(counts, applyPlan, bodyOperations) {
369839
370085
  counts.set("body", bodyOperations.length);
369840
- const storyRevisionReplayCount = (applyPlan.storyOperations ?? []).reduce((total, group) => total + group.operations.filter((operation) => operation.targetRevisionReplay !== undefined).length, 0);
369841
- const bodyRevisionReplayCount = bodyOperations.filter((operation) => operation.targetRevisionReplay !== undefined).length;
370086
+ const storyRevisionReplayCount = (applyPlan.storyOperations ?? []).reduce((total, group) => total + group.operations.filter(hasAnyTargetRevisionReplay).length, 0);
370087
+ const bodyRevisionReplayCount = bodyOperations.filter(hasAnyTargetRevisionReplay).length;
369842
370088
  const revisionReplayCount = storyRevisionReplayCount + bodyRevisionReplayCount;
369843
370089
  if (revisionReplayCount > 0)
369844
370090
  counts.set("tracked-changes", revisionReplayCount);
@@ -369886,16 +370132,27 @@ function throwLocalizedBodyCorrespondenceError(sectionSteps, referenceSteps) {
369886
370132
  unsupportedReason: "section-reference-replay-unsafe"
369887
370133
  });
369888
370134
  }
370135
+ function paragraphMarkReplayOf(operation) {
370136
+ return operation.kind === "insert" || operation.kind === "insertAtStart" || operation.kind === "delete" ? operation.targetParagraphMarkRevisionReplay : undefined;
370137
+ }
369889
370138
  function mergeCanonicalRevisionReplay(derivedOperations, canonicalOperations) {
369890
370139
  return derivedOperations.map((derived) => {
369891
- const candidates = canonicalOperations.filter((canonical) => sameBodyOperationIdentity(derived, canonical));
370140
+ const candidates = canonicalOperations.filter((canonical2) => sameBodyOperationIdentity(derived, canonical2));
369892
370141
  if (candidates.length !== 1)
369893
370142
  return derived;
369894
- const replay = candidates[0].targetRevisionReplay;
369895
- if (replay === undefined || derived.targetRevisionReplay !== undefined)
370143
+ const canonical = candidates[0];
370144
+ const replay = canonical.targetRevisionReplay;
370145
+ const markReplay = paragraphMarkReplayOf(canonical);
370146
+ const wantsReplay = replay !== undefined && derived.targetRevisionReplay === undefined;
370147
+ const wantsMarkReplay = markReplay !== undefined && paragraphMarkReplayOf(derived) === undefined;
370148
+ if (!wantsReplay && !wantsMarkReplay)
369896
370149
  return derived;
369897
- const merged = { ...derived, targetRevisionReplay: replay };
369898
- if (derived.kind === "delete" && replay.structuralAction === "delete")
370150
+ const merged = {
370151
+ ...derived,
370152
+ ...wantsReplay ? { targetRevisionReplay: replay } : {},
370153
+ ...wantsMarkReplay ? { targetParagraphMarkRevisionReplay: markReplay } : {}
370154
+ };
370155
+ if (derived.kind === "delete" && (merged.targetRevisionReplay === undefined || merged.targetRevisionReplay.structuralAction === "delete"))
369899
370156
  return merged;
369900
370157
  return validateCompareReplayPayload(merged).ok ? merged : derived;
369901
370158
  });
@@ -370220,8 +370477,9 @@ function findStructurallyUnsupportedOperationFamilies(context, runtimeApplyPlan,
370220
370477
  return bodyStructuralIds.editDelete.has(op.blockId.toUpperCase()) && !localizedReferenceEditIsProtected(op.targetRunXml, referenceSteps) && !(referenceSteps.length === 0 && localizedRetainedFieldEditIsProtected(op.targetRunXml));
370221
370478
  }
370222
370479
  if (op.kind === "delete") {
370223
- if (op.targetRevisionReplay?.structuralAction === "delete")
370480
+ if (op.targetRevisionReplay?.structuralAction === "delete" || op.targetParagraphMarkRevisionReplay !== undefined) {
370224
370481
  return false;
370482
+ }
370225
370483
  return bodyStructuralIds.editDelete.has(op.blockId.toUpperCase());
370226
370484
  }
370227
370485
  if (op.kind === "formatEdit")
@@ -370251,8 +370509,9 @@ function findStructurallyUnsupportedOperationFamilies(context, runtimeApplyPlan,
370251
370509
  return storyStructuralIds.editDelete.has(op.blockId.toUpperCase());
370252
370510
  }
370253
370511
  if (op.kind === "delete") {
370254
- if (op.targetRevisionReplay?.structuralAction === "delete")
370512
+ if (op.targetRevisionReplay?.structuralAction === "delete" || op.targetParagraphMarkRevisionReplay !== undefined) {
370255
370513
  return false;
370514
+ }
370256
370515
  return storyStructuralIds.editDelete.has(op.blockId.toUpperCase());
370257
370516
  }
370258
370517
  if (op.kind === "formatEdit")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc/mcp",
3
- "version": "1.3.0-next.13",
3
+ "version": "1.3.0-next.14",
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.16.0-next.13",
27
+ "@superdoc/sdk": "2.16.0-next.14",
28
28
  "debug": "^4.4.3",
29
29
  "zod": "^4.3.6"
30
30
  },
31
31
  "devDependencies": {
32
- "superdoc": "2.19.0-next.12",
33
- "@superdoc/docx-engine": "0.18.0-next.12",
32
+ "superdoc": "2.19.0-next.13",
33
+ "@superdoc/docx-engine": "0.18.0-next.13",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",