@superdoc/mcp 1.3.0-next.6 → 1.3.0-next.8

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 +134 -40
  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.6";
31321
+ var SDK_VERSION = "2.16.0-next.8";
31322
31322
 
31323
31323
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31324
31324
  import { chmodSync, existsSync } from "node:fs";
@@ -200600,7 +200600,7 @@ function isolateSimpleTextRangeInParagraphXml(input) {
200600
200600
  if (input.rangeStart < 0 || input.rangeEnd <= input.rangeStart) {
200601
200601
  return { ok: false, reason: "invalid-range" };
200602
200602
  }
200603
- const contextualRejection = rejectSimpleTextRangeContext(input.paragraphXml, input.rangeStart, input.rangeEnd);
200603
+ const contextualRejection = rejectSimpleTextRangeContext(input.paragraphXml, input.rangeStart, input.rangeEnd, input.allowDisjointTracked ?? false);
200604
200604
  if (contextualRejection)
200605
200605
  return { ok: false, reason: contextualRejection };
200606
200606
  const paragraphOpen = /^<([\w.-]+):p\b[^>]*>/.exec(input.paragraphXml);
@@ -200613,10 +200613,21 @@ function isolateSimpleTextRangeInParagraphXml(input) {
200613
200613
  }
200614
200614
  const runs = [];
200615
200615
  const runRe = /<([\w.-]+):r\b[^>]*>[\s\S]*?<\/\1:r>/g;
200616
+ const ordinaryRunStarts = input.allowDisjointTracked ? new Map : null;
200617
+ if (ordinaryRunStarts) {
200618
+ for (const piece of parseParagraphInlineMap(input.paragraphXml).leaves()) {
200619
+ if (piece.kind === "text" && piece.textRole === "visible" && piece.containerStack.length === 0 && !ordinaryRunStarts.has(piece.runCharStart)) {
200620
+ ordinaryRunStarts.set(piece.runCharStart, piece.visibleStart);
200621
+ }
200622
+ }
200623
+ }
200616
200624
  let visibleCursor = 0;
200617
200625
  let match;
200618
200626
  while ((match = runRe.exec(input.paragraphXml)) != null) {
200619
- const parsed = parseSimpleTextRunForRange(match[0], match.index, visibleCursor);
200627
+ const textStart = ordinaryRunStarts?.get(match.index) ?? visibleCursor;
200628
+ if (ordinaryRunStarts && !ordinaryRunStarts.has(match.index))
200629
+ continue;
200630
+ const parsed = parseSimpleTextRunForRange(match[0], match.index, textStart);
200620
200631
  if (!parsed)
200621
200632
  return { ok: false, reason: "unsupported-context" };
200622
200633
  runs.push(parsed);
@@ -200677,14 +200688,17 @@ function renderSimpleTextRunSlice(slice, options = {}) {
200677
200688
  }).join("");
200678
200689
  return `${slice.runOpenTag}${options.rPrXml ?? slice.rPrXml}${textXml}${slice.runCloseTag}`;
200679
200690
  }
200680
- function rejectSimpleTextRangeContext(paragraphXml, rangeStart, rangeEnd) {
200691
+ function rejectSimpleTextRangeContext(paragraphXml, rangeStart, rangeEnd, allowDisjointTracked) {
200681
200692
  if (/<[\w.-]+:(?:fldSimple|fldChar|instrText|delInstrText)\b/.test(paragraphXml))
200682
200693
  return "field";
200683
200694
  if (/<[\w.-]+:(?:commentRangeStart|commentRangeEnd|commentReference)\b/.test(paragraphXml)) {
200684
200695
  return "comment";
200685
200696
  }
200686
- if (/<[\w.-]+:(?:ins|del|moveFrom|moveTo)\b/.test(paragraphXml))
200687
- return "tracked";
200697
+ if (/<[\w.-]+:(?:ins|del|moveFrom|moveTo)\b/.test(paragraphXml)) {
200698
+ if (!allowDisjointTracked || hasTrackedOverlap(parseParagraphInlineMap(paragraphXml).pieces, rangeStart, rangeEnd)) {
200699
+ return "tracked";
200700
+ }
200701
+ }
200688
200702
  if (/<[\w.-]+:hyperlink\b/.test(paragraphXml)) {
200689
200703
  const hyperlinkRange = inspectHyperlinkRange(parseParagraphInlineMap(paragraphXml).pieces, rangeStart, rangeEnd);
200690
200704
  if (!hyperlinkRange.found || hyperlinkRange.overlaps)
@@ -200698,6 +200712,16 @@ function rejectSimpleTextRangeContext(paragraphXml, rangeStart, rangeEnd) {
200698
200712
  return "drawing";
200699
200713
  return null;
200700
200714
  }
200715
+ function hasTrackedOverlap(pieces, rangeStart, rangeEnd) {
200716
+ for (const piece of pieces) {
200717
+ if (piece.kind === "tracked" && rangeStart < piece.visibleEnd && rangeEnd > piece.visibleStart) {
200718
+ return true;
200719
+ }
200720
+ if ((piece.kind === "tracked" || piece.kind === "container") && hasTrackedOverlap(piece.children, rangeStart, rangeEnd))
200721
+ return true;
200722
+ }
200723
+ return false;
200724
+ }
200701
200725
  function inspectHyperlinkRange(pieces, rangeStart, rangeEnd) {
200702
200726
  let found = false;
200703
200727
  for (const piece of pieces) {
@@ -238505,7 +238529,8 @@ function runHyperlinkWrapCommit(input) {
238505
238529
  const isolated = isolateSimpleTextRangeInParagraphXml({
238506
238530
  paragraphXml: paraXml,
238507
238531
  rangeStart: op.on.startOffset,
238508
- rangeEnd: op.on.endOffset
238532
+ rangeEnd: op.on.endOffset,
238533
+ allowDisjointTracked: true
238509
238534
  });
238510
238535
  if (!isolated.ok) {
238511
238536
  return rejected19(input.txId, mapSimpleTextRangeIsolationReason(isolated.reason));
@@ -413754,7 +413779,35 @@ async function bootstrapV2Room(input) {
413754
413779
  diagnostics
413755
413780
  };
413756
413781
  }
413782
+ let supersededClaim = null;
413783
+ if (input.supersedeClaim) {
413784
+ const active = readBootstrapClaims(input.rootDoc).filter((claim) => claim.status === "pending");
413785
+ if (classification.classification !== ROOM_CLASSIFICATION.v2Pending || active.length !== 1 || active[0]?.claimerId !== input.supersedeClaim.claimerId || active[0]?.claimedAt !== input.supersedeClaim.claimedAt || active[0]?.sha256Zip !== seed.sha256Zip || input.supersedeClaim.claimerId === input.claimerId) {
413786
+ diagnostics.push({
413787
+ code: COLLAB_V2_DIAGNOSTICS.COLLAB_V2_BOOTSTRAP_CLAIM_LOST,
413788
+ message: "expired bootstrap claim changed before retry could take over"
413789
+ });
413790
+ return {
413791
+ classification: ROOM_CLASSIFICATION.v2Pending,
413792
+ committed: false,
413793
+ snapshot: readRoomManifest(input.rootDoc).snapshot,
413794
+ survivorClaimerId: active[0]?.claimerId ?? null,
413795
+ diagnostics
413796
+ };
413797
+ }
413798
+ supersededClaim = active[0] ?? null;
413799
+ }
413757
413800
  const publishPendingBootstrap = () => {
413801
+ if (supersededClaim) {
413802
+ writeBootstrapClaim({
413803
+ rootDoc: input.rootDoc,
413804
+ claimerId: supersededClaim.claimerId,
413805
+ claimedAt: supersededClaim.claimedAt,
413806
+ sha256Zip: supersededClaim.sha256Zip,
413807
+ byteLength: supersededClaim.byteLength,
413808
+ status: "aborted"
413809
+ });
413810
+ }
413758
413811
  writeBootstrapClaim({
413759
413812
  rootDoc: input.rootDoc,
413760
413813
  claimerId: input.claimerId,
@@ -413763,22 +413816,24 @@ async function bootstrapV2Room(input) {
413763
413816
  byteLength: seed.byteLength,
413764
413817
  status: "pending"
413765
413818
  });
413766
- writeRoomManifestMeta({
413767
- rootDoc: input.rootDoc,
413768
- roomDocumentId: rootId,
413769
- createdAt,
413770
- createdBy: input.createdBy ?? null,
413771
- createdFrom: {
413772
- kind: "docx",
413773
- sha256Zip: seed.sha256Zip,
413774
- byteLength: seed.byteLength,
413775
- filename: input.filename ?? null,
413776
- migration: input.migration ?? null
413777
- },
413778
- bootstrapState: BOOTSTRAP_STATE.pending,
413779
- compatibilityPolicy: input.compatibilityPolicy ?? DEFAULT_COMPATIBILITY_POLICY,
413780
- schemaVersion
413781
- });
413819
+ if (classification.classification !== ROOM_CLASSIFICATION.v2Pending) {
413820
+ writeRoomManifestMeta({
413821
+ rootDoc: input.rootDoc,
413822
+ roomDocumentId: rootId,
413823
+ createdAt,
413824
+ createdBy: input.createdBy ?? null,
413825
+ createdFrom: {
413826
+ kind: "docx",
413827
+ sha256Zip: seed.sha256Zip,
413828
+ byteLength: seed.byteLength,
413829
+ filename: input.filename ?? null,
413830
+ migration: input.migration ?? null
413831
+ },
413832
+ bootstrapState: BOOTSTRAP_STATE.pending,
413833
+ compatibilityPolicy: input.compatibilityPolicy ?? DEFAULT_COMPATIBILITY_POLICY,
413834
+ schemaVersion
413835
+ });
413836
+ }
413782
413837
  };
413783
413838
  if (replacingExistingRoom) {
413784
413839
  input.rootDoc.transact(() => {
@@ -413786,7 +413841,7 @@ async function bootstrapV2Room(input) {
413786
413841
  publishPendingBootstrap();
413787
413842
  }, "collab-v2:replace:prepare-bootstrap");
413788
413843
  } else {
413789
- publishPendingBootstrap();
413844
+ input.rootDoc.transact(publishPendingBootstrap, "collab-v2:create:prepare-bootstrap");
413790
413845
  }
413791
413846
  const waitForSettling = input.waitForSettling ?? DEFAULT_SETTLING_RESOLVER;
413792
413847
  await waitForSettling();
@@ -436119,6 +436174,8 @@ function createCollabV2SessionProjectionController(options) {
436119
436174
  subscription.unsubscribe();
436120
436175
  }
436121
436176
  for (const handle of options.projectionRegistry.listStories()) {
436177
+ if (handle.rootDoc && handle.scope && getUnitScope(handle.rootDoc, handle.shardId) !== handle.scope)
436178
+ continue;
436122
436179
  disposeStoryBlockIndex(shardReadTarget(handle));
436123
436180
  }
436124
436181
  if (SESSION_PROJECTION_CONTROLLERS.get(options.session) === controller) {
@@ -436727,6 +436784,7 @@ var init_session_controller = __esm(() => {
436727
436784
  init_runtime5();
436728
436785
  init_barrier();
436729
436786
  init_diagnostics2();
436787
+ init_content3();
436730
436788
  init_story_para_id_allocator();
436731
436789
  init_revision_wid_allocator2();
436732
436790
  init_session_controller_origin();
@@ -437093,6 +437151,7 @@ async function bootstrapV2RoomFromDocx(input) {
437093
437151
  docxBytes: input.docxBytes,
437094
437152
  filename: input.filename ?? null,
437095
437153
  claimerId: input.claimerId,
437154
+ ...input.supersedeClaim ? { supersedeClaim: input.supersedeClaim } : {},
437096
437155
  ...input.createdBy ? { createdBy: input.createdBy } : {},
437097
437156
  ...input.createdAt ? { createdAt: input.createdAt } : {},
437098
437157
  ...input.migration ? { migration: input.migration } : {},
@@ -437239,6 +437298,7 @@ async function bootstrapV2RoomFromDocxSingleDoc(input) {
437239
437298
  docxBytes: input.docxBytes,
437240
437299
  filename: input.filename ?? null,
437241
437300
  claimerId: input.claimerId,
437301
+ ...input.supersedeClaim ? { supersedeClaim: input.supersedeClaim } : {},
437242
437302
  ...input.createdBy ? { createdBy: input.createdBy } : {},
437243
437303
  ...input.createdAt ? { createdAt: input.createdAt } : {},
437244
437304
  ...input.migration ? { migration: input.migration } : {},
@@ -437516,7 +437576,8 @@ function createHeadlessCollabRoomCoordinator(options) {
437516
437576
  const manifestObserver = () => {
437517
437577
  if (disposed)
437518
437578
  return;
437519
- if (observeReplacementCommits())
437579
+ const replacementCommitted = observeReplacementCommits();
437580
+ if (replacementCommitted)
437520
437581
  pruneReplacedRoomOrphans(options.rootDoc);
437521
437582
  const nextParts = getPackagePartsMap(options.rootDoc);
437522
437583
  const generationChanged = nextParts !== packageParts;
@@ -437526,7 +437587,7 @@ function createHeadlessCollabRoomCoordinator(options) {
437526
437587
  packageParts = nextParts;
437527
437588
  packageParts.observe(manifestObserver);
437528
437589
  meta3.observe(manifestObserver);
437529
- packageReplacementPending = true;
437590
+ packageReplacementPending || (packageReplacementPending = replacementCommitted || Array.from(lock.entries()).some(([key2, value2]) => key2.startsWith("replaceFile:") && value2 != null && typeof value2 === "object" && (value2.state === "pending" || value2.state === "applying")));
437530
437591
  }
437531
437592
  syncCommittedRoomSourceIdentity();
437532
437593
  if (generationChanged)
@@ -441211,6 +441272,7 @@ function createHeadlessV2CollaborationRuntimeSkeleton(options) {
441211
441272
  docxBytes: request.docxBytes,
441212
441273
  filename: request.filename ?? null,
441213
441274
  claimerId: request.claimerId,
441275
+ ...request.supersedeClaim ? { supersedeClaim: request.supersedeClaim } : {},
441214
441276
  ...request.createdBy ? { createdBy: request.createdBy } : {},
441215
441277
  ...request.createdAt ? { createdAt: request.createdAt } : {},
441216
441278
  ...request.migration ? { migration: request.migration } : {},
@@ -441293,6 +441355,7 @@ function createHeadlessV2SingleDocCollaborationRuntimeSkeleton(options) {
441293
441355
  docxBytes: request.docxBytes,
441294
441356
  filename: request.filename ?? null,
441295
441357
  claimerId: request.claimerId,
441358
+ ...request.supersedeClaim ? { supersedeClaim: request.supersedeClaim } : {},
441296
441359
  ...request.createdBy ? { createdBy: request.createdBy } : {},
441297
441360
  ...request.createdAt ? { createdAt: request.createdAt } : {},
441298
441361
  ...request.migration ? { migration: request.migration } : {},
@@ -441411,6 +441474,7 @@ async function openV2CollaborativeDocumentSession(options) {
441411
441474
  const trace = createOpenTrace(options.runtime.rootId);
441412
441475
  const blobStore = runtimeBlobStore(options.runtime);
441413
441476
  const rootConn = options.runtime.connectRoot();
441477
+ const bootstrapClaimerId = options.claimerId ?? `headless-open-${crypto.randomUUID()}`;
441414
441478
  await rootConn.waitForSync();
441415
441479
  await waitForDocUpdateSettling(rootConn.ydoc, settleMaxMs);
441416
441480
  trace.mark("root-sync");
@@ -441483,7 +441547,10 @@ async function openV2CollaborativeDocumentSession(options) {
441483
441547
  }
441484
441548
  const pendingCreate = openIntent.mode === "create" && validation.classification.classification === ROOM_CLASSIFICATION.v2Pending;
441485
441549
  const pendingRoomStalled = validation.classification.classification === ROOM_CLASSIFICATION.v2Pending && isPendingRoomStalled(rootConn.ydoc);
441486
- if (openIntent.mode === "join" || pendingCreate && !canResumePendingBootstrap(rootConn.ydoc, options.claimerId ?? DEFAULT_CLAIMER_ID, sha256Hex2(resolveBootstrapBytes(openIntent, options.buffer)))) {
441550
+ const bootstrapSourceSha256 = openIntent.mode === "create" && pendingCreate ? sha256Hex2(resolveBootstrapBytes(openIntent, options.buffer)) : null;
441551
+ const resumableClaim = bootstrapSourceSha256 !== null ? resumablePendingBootstrapClaim(rootConn.ydoc, bootstrapSourceSha256) : null;
441552
+ const supersedeClaim = resumableClaim && options.profile === "browser" && options.claimerId === undefined ? { claimerId: resumableClaim.claimerId, claimedAt: resumableClaim.claimedAt } : null;
441553
+ if (openIntent.mode === "join" || pendingCreate && resumableClaim?.claimerId !== bootstrapClaimerId && !supersedeClaim) {
441487
441554
  const isPending = validation.classification.classification === ROOM_CLASSIFICATION.v2Pending;
441488
441555
  throw new CollabV2DiagnosticError(isPending ? pendingRoomStalled ? COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_BOOTSTRAP_STALLED : COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_INITIALIZING : COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_NOT_FOUND, isPending ? pendingRoomStalled ? "v2 collaboration room bootstrap appears stalled; this open did not modify the room" : "v2 collaboration room bootstrap is incomplete; open will not write into a pending room" : "no committed v2 collaboration room exists for join intent", redactForDiagnostics({
441489
441556
  classification: validation.classification.classification,
@@ -441492,17 +441559,22 @@ async function openV2CollaborativeDocumentSession(options) {
441492
441559
  }));
441493
441560
  }
441494
441561
  if (openIntent.mode === "create") {
441495
- stopBootstrapHeartbeat = startBootstrapHeartbeat(rootConn.ydoc, options.claimerId ?? DEFAULT_CLAIMER_ID, () => rootConn.state);
441562
+ stopBootstrapHeartbeat = startBootstrapHeartbeat(rootConn.ydoc, bootstrapClaimerId, () => rootConn.state);
441496
441563
  }
441497
441564
  const bootstrapBytes = resolveBootstrapBytes(openIntent, options.buffer);
441498
441565
  bootstrap = await options.runtime.bootstrapFromDocx({
441499
441566
  docxBytes: bootstrapBytes,
441500
441567
  filename: options.filename ?? null,
441501
- claimerId: options.claimerId ?? DEFAULT_CLAIMER_ID,
441568
+ claimerId: bootstrapClaimerId,
441569
+ ...supersedeClaim ? { supersedeClaim } : {},
441502
441570
  ...options.createdBy ? { createdBy: options.createdBy } : {},
441503
441571
  ...options.createdAt ? { createdAt: options.createdAt } : {},
441504
441572
  ...options.migration ? { migration: options.migration } : {}
441505
441573
  });
441574
+ if (bootstrap.bootstrap.diagnostics.some((diagnostic2) => diagnostic2.code === COLLAB_V2_DIAGNOSTICS.COLLAB_V2_BOOTSTRAP_CLAIM_LOST)) {
441575
+ const roomCommitted = readRoomManifest(rootConn.ydoc).snapshot?.meta.bootstrapState === "committed";
441576
+ throw new CollabV2DiagnosticError(roomCommitted ? COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_ALREADY_EXISTS : COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_INITIALIZING, roomCommitted ? "create intent targeted an already-committed v2 collaboration room" : "another creator is initializing this v2 collaboration room", { rootId: options.runtime.rootId });
441577
+ }
441506
441578
  trace.mark("bootstrap");
441507
441579
  validation = options.runtime.validateLateJoin({
441508
441580
  compatibility: { supports: COLLAB_V2_ROOM_SCHEMA_VERSION },
@@ -441510,7 +441582,7 @@ async function openV2CollaborativeDocumentSession(options) {
441510
441582
  });
441511
441583
  trace.mark("post-bootstrap-validation");
441512
441584
  }
441513
- const expectedClaimerId = options.claimerId ?? DEFAULT_CLAIMER_ID;
441585
+ const expectedClaimerId = bootstrapClaimerId;
441514
441586
  const ownsPreparedBootstrap = bootstrap?.bootstrap.prepared === true && bootstrap.bootstrap.survivorClaimerId === expectedClaimerId;
441515
441587
  if (!validation.ok && !ownsPreparedBootstrap) {
441516
441588
  throwLateJoinValidationFailure(validation, options.runtime.rootId);
@@ -441551,6 +441623,13 @@ async function openV2CollaborativeDocumentSession(options) {
441551
441623
  trace,
441552
441624
  retainImportedStorySources: options.retainImportedStorySources
441553
441625
  });
441626
+ const assertCurrentRoomScopes = () => {
441627
+ for (const handle of [...canonical.storyHandles.values(), ...canonical.projectionHandles.values()]) {
441628
+ if (handle.scope && getUnitScope(rootConn.ydoc, handle.shardId) !== handle.scope) {
441629
+ throw new CollabV2DiagnosticError(COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_INITIALIZING, "room content changed during this open; check the committed room and reopen with join", { rootId: options.runtime.rootId });
441630
+ }
441631
+ }
441632
+ };
441554
441633
  if (bootstrap?.bootstrap.prepared === true) {
441555
441634
  const finalized = finalizeV2RoomBootstrap({
441556
441635
  rootDoc: rootConn.ydoc,
@@ -441558,6 +441637,9 @@ async function openV2CollaborativeDocumentSession(options) {
441558
441637
  contentUnitIds: Array.from(canonical.contentUnitIds)
441559
441638
  });
441560
441639
  if (!finalized.committed) {
441640
+ if (finalized.diagnostics.some((diagnostic2) => diagnostic2.code === COLLAB_V2_DIAGNOSTICS.COLLAB_V2_BOOTSTRAP_CLAIM_LOST)) {
441641
+ throw new CollabV2DiagnosticError(COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_INITIALIZING, "another creator is initializing this v2 collaboration room", { rootId: options.runtime.rootId });
441642
+ }
441561
441643
  throw new CollabV2DiagnosticError(COLLAB_V2_DIAGNOSTICS.COLLAB_V2_ROOM_MANIFEST_CORRUPT, "single-doc collaboration bootstrap could not prove complete content before commit", redactForDiagnostics({
441562
441644
  rootId: options.runtime.rootId,
441563
441645
  diagnostics: finalized.diagnostics
@@ -441593,7 +441675,7 @@ async function openV2CollaborativeDocumentSession(options) {
441593
441675
  session,
441594
441676
  rootDoc: rootConn.ydoc,
441595
441677
  beforeBarrier() {
441596
- return coordinator?.waitForManifestSettled();
441678
+ return coordinator?.waitForManifestSettled().then(assertCurrentRoomScopes);
441597
441679
  },
441598
441680
  packageMutationSync(prepared) {
441599
441681
  coordinator?.syncPreparedPackageMutation(prepared);
@@ -441663,6 +441745,7 @@ async function openV2CollaborativeDocumentSession(options) {
441663
441745
  await waitForProjectionDocsSettling(rootConn.ydoc, canonical, settleMaxMs);
441664
441746
  trace.mark("post-attach-settle");
441665
441747
  }
441748
+ assertCurrentRoomScopes();
441666
441749
  const refreshed = collab.refresh();
441667
441750
  trace.mark("initial-refresh");
441668
441751
  trace.sessionSnapshot("after-initial-refresh", session);
@@ -441742,7 +441825,7 @@ async function openV2CollaborativeDocumentSession(options) {
441742
441825
  try {
441743
441826
  coordinator?.dispose();
441744
441827
  } catch {}
441745
- if (bootstrap?.bootstrap.prepared === true)
441828
+ if (bootstrap?.bootstrap.prepared === true && bootstrap.bootstrap.survivorClaimerId === bootstrapClaimerId && readRoomManifest(rootConn.ydoc).snapshot?.meta.bootstrapState === "pending" && readBootstrapClaims(rootConn.ydoc).filter((claim) => claim.status === "pending").every((claim) => claim.claimerId === bootstrapClaimerId))
441746
441829
  abortBootstrapState(rootConn.ydoc);
441747
441830
  setLocalSelectionStoryHandles(options.runtime, null);
441748
441831
  await session?.dispose().catch(() => {
@@ -441848,24 +441931,35 @@ async function applyPreparedRoomReplacement(input) {
441848
441931
  function createReplacementOperationId(rootDoc) {
441849
441932
  return `${rootDoc.clientID.toString(36)}-${Date.now().toString(36)}-${(replacementSequence++).toString(36)}`;
441850
441933
  }
441851
- function canResumePendingBootstrap(rootDoc, claimerId, sourceSha256) {
441934
+ function resumablePendingBootstrapClaim(rootDoc, sourceSha256) {
441852
441935
  const activeClaims = readBootstrapClaims(rootDoc).filter((claim) => claim.status === "pending");
441853
- if (activeClaims.length !== 1 || activeClaims[0]?.claimerId !== claimerId || activeClaims[0].sha256Zip !== sourceSha256) {
441854
- return false;
441936
+ if (activeClaims.length !== 1 || activeClaims[0]?.sha256Zip !== sourceSha256) {
441937
+ return null;
441855
441938
  }
441856
441939
  if (!isBootstrapLeaseExpired(rootDoc, activeClaims[0]))
441857
- return false;
441940
+ return null;
441858
441941
  const content3 = rootDoc.getMap(ROOT_MAP.content);
441859
441942
  for (const [shardId, scope] of content3.entries()) {
441860
441943
  if (!(scope instanceof YMap))
441861
- return false;
441862
- if (scope.size === 0)
441944
+ return null;
441945
+ if (scope.size === 0 || isUntouchedPackagePartScope(scope))
441863
441946
  continue;
441864
441947
  const meta3 = scope.get("meta");
441865
441948
  if (!(meta3 instanceof YMap) || meta3.get("shardId") !== shardId || meta3.get(CONTENT_UNIT_META_KEY.seedComplete) !== true)
441949
+ return null;
441950
+ }
441951
+ return activeClaims[0];
441952
+ }
441953
+ function isUntouchedPackagePartScope(scope) {
441954
+ if (scope.size !== 5)
441955
+ return false;
441956
+ for (const key2 of [PACKAGE_PART_ROOT.meta, PACKAGE_PART_ROOT.records, PACKAGE_PART_ROOT.index, PACKAGE_PART_ROOT.opaque]) {
441957
+ const child = scope.get(key2);
441958
+ if (!(child instanceof YMap) || child.size !== 0)
441866
441959
  return false;
441867
441960
  }
441868
- return true;
441961
+ const diagnostics = scope.get(PACKAGE_PART_ROOT.diagnostics);
441962
+ return diagnostics instanceof YArray && diagnostics.length === 0;
441869
441963
  }
441870
441964
  function isPendingRoomStalled(rootDoc) {
441871
441965
  const claims = readBootstrapClaims(rootDoc).filter((claim) => claim.status === "pending");
@@ -442865,7 +442959,7 @@ function formatLateJoinValidationFailure(validation) {
442865
442959
  const diagnostics = validation.diagnostics.length > 0 ? validation.diagnostics.map((diagnostic2) => `${diagnostic2.code}: ${diagnostic2.message}`).join("; ") : "no diagnostics reported";
442866
442960
  return `v2 collaboration late-join validation failed (${validation.classification.classification}, ${readiness}): ${diagnostics}`;
442867
442961
  }
442868
- var TEXT_DECODER11, DEFAULT_CLAIMER_ID = "headless-open", REPLACEMENT_REQUEST_KEY_PREFIX = "replaceFile:", REPLACEMENT_HEARTBEAT_INTERVAL_MS = 5000, REPLACEMENT_LEASE_TIMEOUT_MS = 30000, BOOTSTRAP_HEARTBEAT_INTERVAL_MS = 5000, BOOTSTRAP_LEASE_TIMEOUT_MS = 30000, BOOTSTRAP_LEASE_KEY_PREFIX = "bootstrapSeed:", SETTINGS_PART_URI7 = "/word/settings.xml", WEB_SETTINGS_PART_URI2 = "/word/webSettings.xml", COMMENTS_PART_URI6 = "/word/comments.xml", COMMENTS_EXTENDED_PART_URI6 = "/word/commentsExtended.xml", COMMENTS_IDS_PART_URI6 = "/word/commentsIds.xml", PEOPLE_PART_URI2 = "/word/people.xml", MEDIA_OWNER_URI2 = "/word/media", INLINE_BINARY_FAMILIES, OPAQUE_PART_FAMILIES, DEFAULT_OPEN_INTENT, POST_SYNC_SETTLE_MAX_MS = 1000, POST_SYNC_QUIET_WINDOW_MS = 20, replacementSequence = 0, replacementHeartbeatObservations;
442962
+ var TEXT_DECODER11, REPLACEMENT_REQUEST_KEY_PREFIX = "replaceFile:", REPLACEMENT_HEARTBEAT_INTERVAL_MS = 5000, REPLACEMENT_LEASE_TIMEOUT_MS = 30000, BOOTSTRAP_HEARTBEAT_INTERVAL_MS = 5000, BOOTSTRAP_LEASE_TIMEOUT_MS = 30000, BOOTSTRAP_LEASE_KEY_PREFIX = "bootstrapSeed:", SETTINGS_PART_URI7 = "/word/settings.xml", WEB_SETTINGS_PART_URI2 = "/word/webSettings.xml", COMMENTS_PART_URI6 = "/word/comments.xml", COMMENTS_EXTENDED_PART_URI6 = "/word/commentsExtended.xml", COMMENTS_IDS_PART_URI6 = "/word/commentsIds.xml", PEOPLE_PART_URI2 = "/word/people.xml", MEDIA_OWNER_URI2 = "/word/media", INLINE_BINARY_FAMILIES, OPAQUE_PART_FAMILIES, DEFAULT_OPEN_INTENT, POST_SYNC_SETTLE_MAX_MS = 1000, POST_SYNC_QUIET_WINDOW_MS = 20, replacementSequence = 0, replacementHeartbeatObservations;
442869
442963
  var init_collaboration_v2_open = __esm(() => {
442870
442964
  init_dist9();
442871
442965
  init_setup();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc/mcp",
3
- "version": "1.3.0-next.6",
3
+ "version": "1.3.0-next.8",
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.6",
27
+ "@superdoc/sdk": "2.16.0-next.8",
28
28
  "debug": "^4.4.3",
29
29
  "zod": "^4.3.6"
30
30
  },
31
31
  "devDependencies": {
32
- "superdoc": "2.19.0-next.5",
33
- "@superdoc/docx-engine": "0.18.0-next.5",
32
+ "superdoc": "2.19.0-next.7",
33
+ "@superdoc/docx-engine": "0.18.0-next.7",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",