@superdoc/mcp 1.0.0-next.8 → 1.0.0-next.9

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 +237 -39
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -349815,7 +349815,7 @@ var init_host = __esm(() => {
349815
349815
  });
349816
349816
 
349817
349817
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
349818
- var SDK_VERSION = "2.13.0-next.10";
349818
+ var SDK_VERSION = "2.13.0-next.11";
349819
349819
 
349820
349820
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
349821
349821
  import { chmodSync, existsSync } from "node:fs";
@@ -489460,7 +489460,8 @@ function tryRangeReplacementAcrossTokens(input, allTokens, touched) {
489460
489460
  if (touchedInsertions.some(({ token }) => token.innerRuns && token.innerRuns.length > 1 || token.nestedDeletions && token.nestedDeletions.length > 0)) {
489461
489461
  return null;
489462
489462
  }
489463
- return input.changeMode === "tracked" ? authorTrackedPureDelete(input, allTokens, touched) : authorDirectPureDelete(input, allTokens, touched);
489463
+ const result = input.changeMode === "tracked" ? authorTrackedPureDelete(input, allTokens, touched) : authorDirectPureDelete(input, allTokens, touched);
489464
+ return result?.ok && input.changeMode === "tracked" ? { ...result, requiresCollaborationSessionSync: true } : result;
489464
489465
  }
489465
489466
  function renderBreakRunPureDelete(token, input, mode, wrapDeleted) {
489466
489467
  const { controlXml, runOpen, runClose, rPr, text, controlVisibleStart } = token.inertBreakRun;
@@ -491550,11 +491551,16 @@ function buildCoalescedDeletionReplacement(change, partXml) {
491550
491551
  return null;
491551
491552
  if (index > 0) {
491552
491553
  const previous = orderedFragments[index - 1];
491553
- xml += partXml.slice(previous.byteEnd, fragment2.byteStart);
491554
+ const interstitialXml = partXml.slice(previous.byteEnd, fragment2.byteStart);
491555
+ if (/<(?:[\w.-]+:)?(?:fldChar|fldSimple|instrText)\b/.test(interstitialXml))
491556
+ return null;
491557
+ xml += interstitialXml;
491554
491558
  }
491555
491559
  xml += parts.innerXml;
491556
491560
  }
491557
491561
  xml += firstParts.closeTag;
491562
+ if (parseXmlForError(`<root>${xml}</root>`, { namespaceAware: false }) !== null)
491563
+ return null;
491558
491564
  return { start: first.byteStart, end: last.byteEnd, xml };
491559
491565
  }
491560
491566
  function readTrackedWrapperParts(partXml, fragment2, expectedKind) {
@@ -491689,6 +491695,7 @@ function escapeRegExp6(value) {
491689
491695
  }
491690
491696
  var DECODER, ENCODER;
491691
491697
  var init_export_projection = __esm(() => {
491698
+ init_xml_sax();
491692
491699
  init_catalog3();
491693
491700
  init_logical_catalog();
491694
491701
  init_move_stamps();
@@ -493652,6 +493659,9 @@ function commitTracked(input, view) {
493652
493659
  }
493653
493660
  if (!localized.ok)
493654
493661
  return rejected2(txId, localized.reason);
493662
+ if (compileOp.on.coordinateSpace !== "tracked" && requiresStructuralTrackedRewriteSessionSync(paragraphXml, inlineContext.model.leaves(), compileOp.on.startOffset, compileOp.on.endOffset)) {
493663
+ localized = { ...localized, requiresCollaborationSessionSync: true };
493664
+ }
493655
493665
  if (op.newText.includes("\t"))
493656
493666
  localized = { ...localized, requiresCollaborationSessionSync: true };
493657
493667
  if (localized.foldedInsRsid != null) {
@@ -494691,6 +494701,36 @@ function rewriteLocalizedDirect(bytes, window2, op, inheritedNamespaceBindings =
494691
494701
  }
494692
494702
  return { ok: false, reason: plan.reason };
494693
494703
  }
494704
+ function requiresStructuralTrackedRewriteSessionSync(paragraphXml, leaves, startOffset, endOffset) {
494705
+ if (startOffset >= endOffset)
494706
+ return false;
494707
+ const transparentMarkerRe = /<[\w.-]+:(?:proofErr|lastRenderedPageBreak)\b[^>]*\/?>/g;
494708
+ for (const match of paragraphXml.matchAll(transparentMarkerRe)) {
494709
+ const markerStart = match.index;
494710
+ const markerEnd = markerStart + match[0].length;
494711
+ let before;
494712
+ for (let index = leaves.length - 1;index >= 0; index -= 1) {
494713
+ if (leaves[index].charEnd <= markerStart) {
494714
+ before = leaves[index];
494715
+ break;
494716
+ }
494717
+ }
494718
+ const after = leaves.find((piece) => piece.charStart >= markerEnd);
494719
+ const markerOffset = before?.visibleEnd ?? after?.visibleStart;
494720
+ if (markerOffset != null && startOffset < markerOffset && endOffset > markerOffset)
494721
+ return true;
494722
+ }
494723
+ const affected = leaves.filter((piece) => {
494724
+ const overlapsVisibleRange = startOffset < piece.visibleEnd && endOffset > piece.visibleStart;
494725
+ const crossesZeroWidthPiece = startOffset < piece.visibleStart && endOffset > piece.visibleEnd;
494726
+ return overlapsVisibleRange || crossesZeroWidthPiece;
494727
+ });
494728
+ if (affected.some((piece) => piece.kind !== "text" && piece.kind !== "control"))
494729
+ return true;
494730
+ const structuralStack = (piece) => JSON.stringify(piece.containerStack.filter((scope) => scope.kind !== "ins" && scope.kind !== "del" && scope.kind !== "moveFrom" && scope.kind !== "moveTo").map((scope) => [scope.kind, scope.qname]));
494731
+ const textStacks = affected.filter((piece) => piece.kind === "text").map(structuralStack);
494732
+ return textStacks.some((stack) => stack !== textStacks[0]);
494733
+ }
494694
494734
  function rewriteLocalizedTracked(bytes, window2, op, stamp, preparedContext) {
494695
494735
  const paragraphBytes = bytes.subarray(window2.byteStart, window2.byteEnd);
494696
494736
  const inlineContext = preparedContext ?? prepareParagraphInlineEditContext(paragraphBytes);
@@ -496464,7 +496504,7 @@ function rewriteRunSpanTrackedReplace(paragraphXml, startOffset, endOffset, stam
496464
496504
  return { ok: false, reason: "tracked-inline-control-unsupported" };
496465
496505
  }
496466
496506
  }
496467
- if (collected.markerIntegrity.hasPreservableMarker) {
496507
+ if (collected.markerIntegrity.hasPreservableMarker || stamp.newText.length > 0 && requiresStructuralTrackedRewriteSessionSync(paragraphXml, parseParagraphInlineMap(paragraphXml).leaves(), startOffset, endOffset)) {
496468
496508
  return rewriteRunSpanTrackedReplacePreservingMarkers(paragraphXml, span, stamp, paragraphMarkFallback.rPr);
496469
496509
  }
496470
496510
  const first = span.runs[span.firstRunIdx];
@@ -503109,7 +503149,7 @@ function runTrackedChangeDecideCommit(input) {
503109
503149
  fragmentsByPart,
503110
503150
  structuralTargets
503111
503151
  });
503112
- const sessionSyncedTextDecision = trackedTextDecide && (hasNestedTextDecision(catalog, fragmentsByPart) || hasStructuralInlineDeletionDecision(state, fragmentsByPart));
503152
+ const sessionSyncedTextDecision = trackedTextDecide && (hasNestedTextDecision(catalog, fragmentsByPart) || hasStructuralInlineDeletionDecision(state, fragmentsByPart) || hasMarkerSeparatedTextDecision(state, fragmentsByPart));
503113
503153
  const prepared = {
503114
503154
  txId,
503115
503155
  source: op,
@@ -503479,6 +503519,45 @@ function hasStructuralInlineDeletionDecision(state, fragmentsByPart) {
503479
503519
  }
503480
503520
  return false;
503481
503521
  }
503522
+ function hasMarkerSeparatedTextDecision(state, fragmentsByPart) {
503523
+ for (const [partUri, fragments] of fragmentsByPart) {
503524
+ const partBytes = state.packageBytes.get(partUri);
503525
+ if (!partBytes)
503526
+ continue;
503527
+ const textFragments = fragments.filter((fragment2) => fragment2.kind === "ins" || fragment2.kind === "del");
503528
+ const paragraphByFragment = findParagraphsContainingFragments(state, textFragments);
503529
+ const grouped = new Map;
503530
+ for (const fragment2 of textFragments) {
503531
+ const paragraph = paragraphByFragment.get(fragment2);
503532
+ if (!paragraph)
503533
+ continue;
503534
+ const key2 = `${fragment2.storyId}|${paragraph.blockId}|${fragment2.kind}|${fragment2.rsid}`;
503535
+ const group = grouped.get(key2) ?? [];
503536
+ group.push(fragment2);
503537
+ grouped.set(key2, group);
503538
+ }
503539
+ for (const group of grouped.values()) {
503540
+ if (group.length < 2)
503541
+ continue;
503542
+ const ordered = [...group].sort((left, right) => {
503543
+ const leftRange = preparedFragmentSourceRange(left);
503544
+ const rightRange = preparedFragmentSourceRange(right);
503545
+ return leftRange.start - rightRange.start;
503546
+ });
503547
+ for (let index = 1;index < ordered.length; index += 1) {
503548
+ const previous = preparedFragmentSourceRange(ordered[index - 1]);
503549
+ const current = preparedFragmentSourceRange(ordered[index]);
503550
+ if (!previous || !current || previous.end > current.start)
503551
+ continue;
503552
+ const separator = TD44.decode(partBytes.subarray(previous.end, current.start));
503553
+ if (/<[\w.-]+:(?:bookmarkStart|bookmarkEnd|commentRangeStart|commentRangeEnd|commentReference)\b/.test(separator)) {
503554
+ return true;
503555
+ }
503556
+ }
503557
+ }
503558
+ }
503559
+ return false;
503560
+ }
503482
503561
  function buildPreparedTrackedTextDecide(input) {
503483
503562
  if (input.op.targets.some((target) => target.partial || target.formatting || target.derivedStructural || (target.moveRangeMarkers?.ids.length ?? 0) > 0)) {
503484
503563
  return;
@@ -707175,44 +707254,130 @@ function syncParagraphMarkerCarriers(carriers, next, create10) {
707175
707254
  offset += carrier.text.length;
707176
707255
  return { ...carrier, start, end: offset, next: [] };
707177
707256
  });
707178
- for (const marker of next) {
707179
- const position2 = Number(marker.visibleOffset ?? 0);
707180
- const owner = windows.find((window2) => window2.markers.toArray().some((existing) => readInlineControlOffset(existing) + window2.start === position2 && sameMarker(existing, marker))) ?? windows.find((window2) => position2 < window2.end) ?? windows[windows.length - 1];
707181
- owner.next.push({ ...marker, visibleOffset: position2 - owner.start });
707257
+ for (let markerIndex = 0;markerIndex < next.length; ) {
707258
+ const position2 = Number(next[markerIndex].visibleOffset ?? 0);
707259
+ let groupEnd = markerIndex + 1;
707260
+ while (groupEnd < next.length && Number(next[groupEnd].visibleOffset ?? 0) === position2)
707261
+ groupEnd += 1;
707262
+ const group = next.slice(markerIndex, groupEnd);
707263
+ const retainedOwners = windows.filter((window2) => group.some((marker) => window2.markers.toArray().some((existing) => readInlineControlOffset(existing) + window2.start === position2 && sameMarker(existing, marker))));
707264
+ const sharedOwner = retainedOwners.length === 1 ? retainedOwners[0] : null;
707265
+ for (const marker of group) {
707266
+ const owner = sharedOwner ?? windows.find((window2) => window2.markers.toArray().some((existing) => readInlineControlOffset(existing) + window2.start === position2 && sameMarker(existing, marker))) ?? windows.find((window2) => position2 < window2.end) ?? windows[windows.length - 1];
707267
+ owner.next.push({ ...marker, visibleOffset: position2 - owner.start });
707268
+ }
707269
+ markerIndex = groupEnd;
707182
707270
  }
707183
707271
  for (const window2 of windows)
707184
707272
  syncParagraphMarkers(window2.markers, window2.next, create10);
707185
707273
  }
707186
707274
  function syncParagraphMarkers(array3, next, create10) {
707187
707275
  const previous3 = array3.toArray();
707188
- let prefix = 0;
707189
- while (prefix < previous3.length && prefix < next.length && sameMarker(previous3[prefix], next[prefix]))
707190
- prefix += 1;
707191
- let suffix = 0;
707192
- while (suffix < previous3.length - prefix && suffix < next.length - prefix && sameMarker(previous3[previous3.length - suffix - 1], next[next.length - suffix - 1]))
707193
- suffix += 1;
707194
- const removed = previous3.length - prefix - suffix;
707195
- if (removed > 0)
707196
- array3.delete(prefix, removed);
707197
- const additions = next.slice(prefix, next.length - suffix);
707198
- const inserted = additions.map(create10);
707199
- if (inserted.length > 0)
707200
- array3.insert(prefix, inserted);
707276
+ const retained = longestSharedMarkerSubsequence(previous3, next);
707277
+ const anchors2 = [
707278
+ { previous: -1, next: -1 },
707279
+ ...retained,
707280
+ { previous: previous3.length, next: next.length }
707281
+ ];
707282
+ for (let anchorIndex = anchors2.length - 2;anchorIndex >= 0; anchorIndex -= 1) {
707283
+ const left = anchors2[anchorIndex];
707284
+ const right = anchors2[anchorIndex + 1];
707285
+ const start = left.previous + 1;
707286
+ const removed = right.previous - start;
707287
+ if (removed > 0)
707288
+ array3.delete(start, removed);
707289
+ const additions = next.slice(left.next + 1, right.next);
707290
+ const inserted = additions.map(create10);
707291
+ if (inserted.length > 0)
707292
+ array3.insert(start, inserted);
707293
+ assignInsertedTrackedMarkerIds(array3, inserted, additions, start);
707294
+ }
707295
+ next.forEach((value2, index2) => {
707296
+ const marker = array3.get(index2);
707297
+ if (marker.get("visibleOffset") !== value2.visibleOffset)
707298
+ marker.set("visibleOffset", value2.visibleOffset);
707299
+ anchorInlineControl(marker, Number(value2.visibleOffset));
707300
+ });
707301
+ }
707302
+ function longestSharedMarkerSubsequence(previous3, next) {
707303
+ const exactCells = (previous3.length + 1) * (next.length + 1);
707304
+ if (exactCells > 1e6)
707305
+ return orderedSharedMarkerSubsequence(previous3, next);
707306
+ const lengths = Array.from({ length: previous3.length + 1 }, () => new Uint32Array(next.length + 1));
707307
+ for (let previousIndex2 = previous3.length - 1;previousIndex2 >= 0; previousIndex2 -= 1) {
707308
+ for (let nextIndex2 = next.length - 1;nextIndex2 >= 0; nextIndex2 -= 1) {
707309
+ lengths[previousIndex2][nextIndex2] = sameMarker(previous3[previousIndex2], next[nextIndex2]) ? 1 + lengths[previousIndex2 + 1][nextIndex2 + 1] : Math.max(lengths[previousIndex2 + 1][nextIndex2], lengths[previousIndex2][nextIndex2 + 1]);
707310
+ }
707311
+ }
707312
+ const retained = [];
707313
+ let previousIndex = 0;
707314
+ let nextIndex = 0;
707315
+ while (previousIndex < previous3.length && nextIndex < next.length) {
707316
+ if (sameMarker(previous3[previousIndex], next[nextIndex]) && lengths[previousIndex][nextIndex] === 1 + lengths[previousIndex + 1][nextIndex + 1]) {
707317
+ retained.push({ previous: previousIndex, next: nextIndex });
707318
+ previousIndex += 1;
707319
+ nextIndex += 1;
707320
+ } else if (lengths[previousIndex + 1][nextIndex] >= lengths[previousIndex][nextIndex + 1]) {
707321
+ previousIndex += 1;
707322
+ } else {
707323
+ nextIndex += 1;
707324
+ }
707325
+ }
707326
+ return retained;
707327
+ }
707328
+ function orderedSharedMarkerSubsequence(previous3, next) {
707329
+ const positions = new Map;
707330
+ previous3.forEach((marker, index2) => {
707331
+ const key2 = markerDiscriminator((name) => marker.get(name));
707332
+ const indexes = positions.get(key2);
707333
+ if (indexes)
707334
+ indexes.push(index2);
707335
+ else
707336
+ positions.set(key2, [index2]);
707337
+ });
707338
+ const retained = [];
707339
+ let minimumPrevious = 0;
707340
+ next.forEach((marker, nextIndex) => {
707341
+ const indexes = positions.get(markerDiscriminator((name) => marker[name]));
707342
+ if (!indexes)
707343
+ return;
707344
+ let low = 0;
707345
+ let high = indexes.length;
707346
+ while (low < high) {
707347
+ const middle = low + high >>> 1;
707348
+ if (indexes[middle] < minimumPrevious)
707349
+ low = middle + 1;
707350
+ else
707351
+ high = middle;
707352
+ }
707353
+ while (low < indexes.length && !sameMarker(previous3[indexes[low]], marker))
707354
+ low += 1;
707355
+ if (low === indexes.length)
707356
+ return;
707357
+ const previousIndex = indexes[low];
707358
+ retained.push({ previous: previousIndex, next: nextIndex });
707359
+ minimumPrevious = previousIndex + 1;
707360
+ });
707361
+ return retained;
707362
+ }
707363
+ function markerDiscriminator(read) {
707364
+ return JSON.stringify([
707365
+ read("kind"),
707366
+ read("xml"),
707367
+ read("length"),
707368
+ read("meta")
707369
+ ]);
707370
+ }
707371
+ function assignInsertedTrackedMarkerIds(array3, inserted, additions, start) {
707201
707372
  inserted.forEach((marker, index2) => {
707202
707373
  const value2 = additions[index2];
707203
707374
  const meta3 = value2.meta;
707204
707375
  const trackedCarrier = value2.kind === "tracked-wrapper" || value2.kind === "preserved" && (meta3?.tag === "delTextRun" || meta3?.container === "tracked-deletion");
707205
707376
  if (trackedCarrier) {
707206
- const item = createRelativePositionFromTypeIndex(array3, prefix + index2).item;
707377
+ const item = createRelativePositionFromTypeIndex(array3, start + index2).item;
707207
707378
  marker.set("id", `${value2.id}:sync:${item.client.toString(36)}:${item.clock.toString(36)}`);
707208
707379
  }
707209
707380
  });
707210
- next.forEach((value2, index2) => {
707211
- const marker = array3.get(index2);
707212
- if (marker.get("visibleOffset") !== value2.visibleOffset)
707213
- marker.set("visibleOffset", value2.visibleOffset);
707214
- anchorInlineControl(marker, Number(value2.visibleOffset));
707215
- });
707216
707381
  }
707217
707382
  var init_paragraph_inline_sync = __esm(() => {
707218
707383
  init_yjs();
@@ -707239,13 +707404,14 @@ function mirrorStorySurfaceFromSession(input) {
707239
707404
  };
707240
707405
  }
707241
707406
  try {
707407
+ const extension2 = storyScopedTrackedDecisionExtension(input.extension, storyId);
707242
707408
  const scope = resolveStoryShardScope(doc2);
707243
707409
  scope.doc.transact(() => {
707244
- const groups = input.extension.contentControlRewrite || hasContentControlGroups(scope) ? prepareStoryContentControlGroups(input.session, storyId, doc2) : null;
707410
+ const groups = extension2.contentControlRewrite || hasContentControlGroups(scope) ? prepareStoryContentControlGroups(input.session, storyId, doc2) : null;
707245
707411
  mirrorFamilyIntoStory({
707246
707412
  session: input.session,
707247
707413
  prepared: input.prepared,
707248
- extension: input.extension,
707414
+ extension: extension2,
707249
707415
  paragraphOnlyReviewStoryIds: input.paragraphOnlyReviewStoryIds,
707250
707416
  storyId,
707251
707417
  doc: doc2
@@ -707265,6 +707431,16 @@ function mirrorStorySurfaceFromSession(input) {
707265
707431
  }
707266
707432
  return { mirrored: true };
707267
707433
  }
707434
+ function storyScopedTrackedDecisionExtension(extension2, storyId) {
707435
+ if (extension2.family !== "storyTrackedDecide" || !extension2.trackedTextDecide)
707436
+ return extension2;
707437
+ const targets = extension2.trackedTextDecide.targets.filter((target) => target.storyId === storyId);
707438
+ return {
707439
+ ...extension2,
707440
+ targetBlockIds: [...new Set(targets.map((target) => target.blockId))],
707441
+ trackedTextDecide: { ...extension2.trackedTextDecide, targets }
707442
+ };
707443
+ }
707268
707444
  function prepareStoryContentControlGroups(session, storyId, doc2) {
707269
707445
  const scope = resolveStoryShardScope(doc2);
707270
707446
  const source = readContentControlBlockGroups(loadStorySyncContext(session, storyId).bytes);
@@ -708769,7 +708945,7 @@ function hasStrictMirrorPrerequisites(prepared, options) {
708769
708945
  case "storyText":
708770
708946
  return !extension2.historyReplay && !extension2.resyncFromSession && !extension2.sessionSync ? true : options.session != null;
708771
708947
  case "storyTrackedDecide":
708772
- return !usesTrackedDecisionSessionSync(prepared, extension2) || options.session != null;
708948
+ return !usesTrackedDecisionSessionSync(prepared, extension2, options) || options.session != null;
708773
708949
  case "storyTable":
708774
708950
  return true;
708775
708951
  case "storyBlocks":
@@ -708836,7 +709012,7 @@ function runFamilyMirror(prepared, extension2, options, directStoryText, tracked
708836
709012
  return { mirrored: true };
708837
709013
  }
708838
709014
  if (extension2.family === "storyTrackedDecide") {
708839
- if (usesTrackedDecisionSessionSync(prepared, extension2)) {
709015
+ if (usesTrackedDecisionSessionSync(prepared, extension2, options)) {
708840
709016
  if (!options.session) {
708841
709017
  return {
708842
709018
  mirrored: false,
@@ -708850,11 +709026,19 @@ function runFamilyMirror(prepared, extension2, options, directStoryText, tracked
708850
709026
  const sessionSync = mirrorStorySurfaceFromSession({
708851
709027
  session: options.session,
708852
709028
  prepared,
708853
- extension: extension2,
709029
+ extension: extension2.sessionSync || !extension2.trackedTextDecide ? extension2 : { ...extension2, sessionSync: { reason: "structural-inline-edit" } },
708854
709030
  storyIds: storyIdsRequiringShards(prepared, extension2),
708855
709031
  paragraphOnlyReviewStoryIds,
708856
709032
  resolveStoryShard: options.resolveStoryShard
708857
709033
  });
709034
+ if (sessionSync.mirrored && extension2.trackedTextDecide) {
709035
+ for (const target of extension2.trackedTextDecide.targets) {
709036
+ const doc2 = options.resolveStoryShard(target.storyId);
709037
+ if (doc2) {
709038
+ recordTrackedDecision(doc2, target.rsid, extension2.trackedTextDecide.decision, prepared.txId);
709039
+ }
709040
+ }
709041
+ }
708858
709042
  return { ...sessionSync, mirrorPath: "session-sync" };
708859
709043
  }
708860
709044
  if (!trackedDecision) {
@@ -709623,7 +709807,7 @@ function admitPreparedStorySurfaceMutation(prepared, options) {
709623
709807
  return options.session && extension2.family === "storyBlocks" && extension2.contentControlRewrite && storyIds.length === 1 ? { ok: true } : { ok: false, message: "Content-control rewrite requires a prepared structural delta and owning session." };
709624
709808
  }
709625
709809
  if (extension2.family === "storyTrackedDecide") {
709626
- if (usesTrackedDecisionSessionSync(prepared, extension2)) {
709810
+ if (usesTrackedDecisionSessionSync(prepared, extension2, options)) {
709627
709811
  return options.session ? { ok: true } : { ok: false, message: "tracked-change decision session sync requires an authoritative session" };
709628
709812
  }
709629
709813
  const trackedDecision = validatePreparedTrackedDecide(prepared, extension2, options);
@@ -709701,14 +709885,28 @@ function touchesOwnedStoryPart(prepared) {
709701
709885
  const touchedParts = new Set(prepared.resolvedTargets.partUris.map((partUri) => String(partUri)));
709702
709886
  return prepared.resolvedTargets.storyPartOwnership.some((entry) => touchedParts.has(String(entry.partUri)));
709703
709887
  }
709704
- function usesTrackedDecisionSessionSync(prepared, extension2) {
709888
+ function usesTrackedDecisionSessionSync(prepared, extension2, options) {
709705
709889
  if (extension2.historyReplay || extension2.sessionSync)
709706
709890
  return true;
709707
709891
  if (hasPreparedCommentRefRemaps(prepared))
709708
709892
  return true;
709709
- if (extension2.trackedTextDecide || prepared.source.kind !== "trackedChangeDecide")
709710
- return false;
709711
- return prepared.source.targets.some((target) => target.formatting !== undefined || target.structural !== undefined || target.derivedStructural !== undefined);
709893
+ if (!extension2.trackedTextDecide) {
709894
+ if (prepared.source.kind !== "trackedChangeDecide")
709895
+ return false;
709896
+ return prepared.source.targets.some((target) => target.formatting !== undefined || target.structural !== undefined || target.derivedStructural !== undefined);
709897
+ }
709898
+ return extension2.trackedTextDecide.targets.some((target) => {
709899
+ const doc2 = options.resolveStoryShard(target.storyId);
709900
+ if (!doc2)
709901
+ return false;
709902
+ const liveSpans = collectLiveTrackedTextSpans(doc2, target.rsid, target.trackedKind, [target.blockId]);
709903
+ if (liveSpans.length > 1)
709904
+ return true;
709905
+ if (!hasTrackedDecisionLedgerEntry(doc2, target.rsid) || findPreparedLiveTrackedTextSpans(doc2, target).length > 0) {
709906
+ return false;
709907
+ }
709908
+ return liveSpans.length > 0;
709909
+ });
709712
709910
  }
709713
709911
  function tryMirrorStoryText(prepared, extension2, options, admitted) {
709714
709912
  const validation = admitted ?? validateDirectStoryText(prepared, extension2, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc/mcp",
3
- "version": "1.0.0-next.8",
3
+ "version": "1.0.0-next.9",
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.13.0-next.10",
27
+ "@superdoc/sdk": "2.13.0-next.11",
28
28
  "debug": "^4.4.3",
29
29
  "zod": "^4.3.6"
30
30
  },
31
31
  "devDependencies": {
32
- "superdoc": "2.16.0-next.8",
33
- "@superdoc/docx-engine": "0.15.0-next.8",
32
+ "superdoc": "2.16.0-next.9",
33
+ "@superdoc/docx-engine": "0.15.0-next.9",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",