@superdoc/mcp 1.10.1-next.1 → 1.10.1-next.2

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 +320 -44
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -31630,7 +31630,7 @@ var init_host = __esm(() => {
31630
31630
  });
31631
31631
 
31632
31632
  // ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
31633
- var SDK_VERSION = "2.23.1-next.1";
31633
+ var SDK_VERSION = "2.23.1-next.2";
31634
31634
 
31635
31635
  // ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
31636
31636
  import { accessSync, chmodSync, constants, existsSync, statSync } from "node:fs";
@@ -102156,7 +102156,7 @@ function buildInlineRunPatchSchema() {
102156
102156
  minProperties: 1
102157
102157
  };
102158
102158
  }
102159
- var schemaBooleanOrNull = () => ({
102159
+ var CLEAR_INLINE_FORMATTING_KEYS, schemaBooleanOrNull = () => ({
102160
102160
  oneOf: [{ type: "boolean" }, { type: "null" }]
102161
102161
  }), schemaStringOrNull = () => ({
102162
102162
  oneOf: [{ type: "string", minLength: 1 }, { type: "null" }]
@@ -102210,6 +102210,21 @@ var schemaBooleanOrNull = () => ({
102210
102210
  }), INLINE_PROPERTY_REGISTRY, INLINE_PROPERTY_KEY_SET, INLINE_PROPERTY_BY_KEY, INLINE_PROPERTY_KEYS_BY_STORAGE, UNDERLINE_OBJECT_ALLOWED_KEYS, SHADING_ALLOWED_KEYS, BORDER_ALLOWED_KEYS, FIT_TEXT_ALLOWED_KEYS, LANG_ALLOWED_KEYS, RFONTS_ALLOWED_KEYS, EAST_ASIAN_LAYOUT_ALLOWED_KEYS, STYLISTIC_SET_ALLOWED_KEYS, VERT_ALIGN_VALUES, PROPERTY_VALIDATOR_MAP;
102211
102211
  var init_inline_run_patch = __esm(() => {
102212
102212
  init_errors5();
102213
+ CLEAR_INLINE_FORMATTING_KEYS = Object.freeze([
102214
+ "bold",
102215
+ "italic",
102216
+ "underline",
102217
+ "strike",
102218
+ "color",
102219
+ "highlight",
102220
+ "fontFamily",
102221
+ "fontSize",
102222
+ "vertAlign",
102223
+ "smallCaps",
102224
+ "caps",
102225
+ "letterSpacing",
102226
+ "dstrike"
102227
+ ]);
102213
102228
  UNDERLINE_OBJECT_SCHEMA = {
102214
102229
  type: "object",
102215
102230
  properties: {
@@ -214884,7 +214899,8 @@ function commitTracked(input, view) {
214884
214899
  bytes: TE19.encode(ownLinkedRefinement.xml),
214885
214900
  emittedBothSides: false,
214886
214901
  foldedInsRsid: ownLinkedRefinement.rsid,
214887
- requiresCollaborationSessionSync: true
214902
+ requiresCollaborationSessionSync: true,
214903
+ createdVisibleTextSpan: compileOp.on.coordinateSpace !== "tracked" ? ownLinkedRefinement.createdVisibleTextSpan : undefined
214888
214904
  };
214889
214905
  }
214890
214906
  const canSpanningDelete = compileOp.on.coordinateSpace !== "tracked" && op.newText.length === 0 && compileOp.on.startOffset < compileOp.on.endOffset;
@@ -215144,6 +215160,7 @@ function commitTracked(input, view) {
215144
215160
  author: stamping.author,
215145
215161
  date: stamping.date
215146
215162
  }, compiledCarrier("ins", wId)) : undefined;
215163
+ const createdVisibleTextSpan = localized.createdVisibleTextSpan ?? (isPureTrackedInsert(compileOp) && compileOp.on.coordinateSpace !== "tracked" && (overlapEmittedRsids === null || emittedRsids.includes(insRsid)) ? resolveCreatedTrackedCarrierSpan(localized.bytes, compileOp, wId, insRsid, namespaceBindings) : undefined);
215147
215164
  const shiftParagraphXml = op.on.coordinateSpace === "tracked" ? TD45.decode(bytes.subarray(window2.byteStart, window2.byteEnd)) : null;
215148
215165
  const visibleStartOffset = shiftParagraphXml !== null ? projectTrackedParagraphOffsetToVisible(shiftParagraphXml, op.on.startOffset, inlineModel) : op.on.startOffset;
215149
215166
  const visibleEndOffset = shiftParagraphXml !== null ? projectTrackedParagraphOffsetToVisible(shiftParagraphXml, op.on.endOffset, inlineModel) : op.on.endOffset;
@@ -215255,7 +215272,7 @@ function commitTracked(input, view) {
215255
215272
  }))),
215256
215273
  resyncFromSession,
215257
215274
  requiresCollaborationSessionSync: localized.requiresCollaborationSessionSync,
215258
- createdVisibleTextSpan: localized.createdVisibleTextSpan,
215275
+ createdVisibleTextSpan,
215259
215276
  pushHistory: input.pushHistory,
215260
215277
  paragraphWindow: counterpartPlan?.ownerParagraphWindow ?? {
215261
215278
  byteStart: byteBase + window2.byteStart,
@@ -216034,6 +216051,27 @@ function isPureTrackedInsert(op) {
216034
216051
  function isCollapsedInsert(op) {
216035
216052
  return op.on.startBlockId === op.on.endBlockId && op.on.startOffset === op.on.endOffset && op.newText.length > 0;
216036
216053
  }
216054
+ function resolveCreatedTrackedCarrierSpan(bytes, op, wId, rsid, namespaceBindings = { w: NS_W }) {
216055
+ const model = parseParagraphInlineMap(TD45.decode(bytes), namespaceBindings);
216056
+ const pending2 = [...model.pieces];
216057
+ const carriers = [];
216058
+ while (pending2.length > 0) {
216059
+ const piece = pending2.pop();
216060
+ if (piece.kind === "tracked" && piece.trackedKind === "ins" && piece.revisionId === String(wId) && piece.rsid === rsid)
216061
+ carriers.push(piece);
216062
+ if (piece.kind === "tracked" || piece.kind === "container")
216063
+ pending2.push(...piece.children);
216064
+ }
216065
+ const carrier = carriers.length === 1 ? carriers[0] : undefined;
216066
+ if (!carrier || carrier.visibleStart !== op.on.startOffset || carrier.visibleEnd - carrier.visibleStart !== op.newText.length || model.visibleText().slice(carrier.visibleStart, carrier.visibleEnd) !== op.newText)
216067
+ return;
216068
+ return {
216069
+ startOffset: carrier.visibleStart,
216070
+ endOffset: carrier.visibleEnd,
216071
+ insertedTextLength: carrier.visibleEnd - carrier.visibleStart,
216072
+ source: "new-tracked-carrier"
216073
+ };
216074
+ }
216037
216075
  function createCompiledTrackedCarrierReader(bytes, namespaceBindings = { w: NS_W }) {
216038
216076
  let xml;
216039
216077
  let scan;
@@ -218504,7 +218542,9 @@ function refineOwnLinkedInsertion(model, start, end, newText, author, state) {
218504
218542
  if (start === end) {
218505
218543
  const ordinary = selected.find((piece) => !fieldFor(piece));
218506
218544
  const interior = selected.find((piece) => piece.visibleStart < start && piece.visibleEnd > start);
218507
- const chosen = ordinary ?? interior;
218545
+ const boundaryField = selected.length > 1 ? fieldFor(selected[0]) : undefined;
218546
+ const boundary = boundaryField && selected.every((piece) => fieldFor(piece) === boundaryField) && selected.some((piece) => piece.visibleStart === start && piece.visibleEnd > start) ? selected.find((piece) => piece.visibleStart < start && piece.visibleEnd === start) : undefined;
218547
+ const chosen = ordinary ?? interior ?? boundary;
218508
218548
  if (!chosen)
218509
218549
  return null;
218510
218550
  selected.splice(0, selected.length, chosen);
@@ -218533,7 +218573,16 @@ function refineOwnLinkedInsertion(model, start, end, newText, author, state) {
218533
218573
  let rewritten = paragraphXml;
218534
218574
  for (const patch of patches.reverse())
218535
218575
  rewritten = rewritten.slice(0, patch.start) + patch.xml + rewritten.slice(patch.end);
218536
- return { xml: rewritten, rsid: wrapper.rsid };
218576
+ return {
218577
+ xml: rewritten,
218578
+ rsid: wrapper.rsid,
218579
+ ...start === end && newText.length > 0 ? { createdVisibleTextSpan: {
218580
+ startOffset: start,
218581
+ endOffset: start + newText.length,
218582
+ insertedTextLength: newText.length,
218583
+ source: "same-author-refinement"
218584
+ } } : {}
218585
+ };
218537
218586
  }
218538
218587
  function spliceWithinSameAuthorInsertion(paragraphXml, startOffset, endOffset, newText, author) {
218539
218588
  const createdVisibleTextSpan = startOffset === endOffset && newText.length > 0 ? {
@@ -283006,6 +283055,7 @@ function applySDDocumentSessionInternalPatchGroup(session, input) {
283006
283055
  internal.onMutationCommitted();
283007
283056
  return receipt3;
283008
283057
  }
283058
+ const historyOwner = input.history ? captureHistoryTextOwner(internal.state, input.forwardPatchGroup) : null;
283009
283059
  const applyResult = applyPatchGroupAtomic(internal.state, input.forwardPatchGroup);
283010
283060
  if (applyResult.status !== "committed") {
283011
283061
  return {
@@ -283027,6 +283077,7 @@ function applySDDocumentSessionInternalPatchGroup(session, input) {
283027
283077
  forwardPatchGroup: applyResult.forwardPatchGroup,
283028
283078
  inversePatchGroup: applyResult.inversePatchGroup,
283029
283079
  semanticDelta: input.history.semanticDelta,
283080
+ textReplayOwner: sealHistoryTextOwner(internal.state, historyOwner, applyResult.inversePatchGroup),
283030
283081
  revisionDeltas: {
283031
283082
  package: {
283032
283083
  previous: applyResult.previousPackageRevision,
@@ -283259,10 +283310,11 @@ function prepareSDDocumentSessionInternalAtomicReview(session, compile) {
283259
283310
  const retiredEntries = [...initialHistory].filter((id) => !state.history.entries.has(id)).map((id) => internal.state.history.entries.get(id)).filter((entry) => !!entry);
283260
283311
  if (entries2.length === 0 && retiredEntries.length === 0)
283261
283312
  return { value, prepared: null };
283262
- const touched = collectCapturedTouchedParts([...retiredEntries, ...entries2]);
283263
- const finalParts = snapshotCapturedParts(staging, touched);
283264
- const originals = snapshotCapturedParts(session, touched);
283265
- const group = buildCapturedCompositeForwardPatchGroup(session, [...retiredEntries, ...entries2], originals, finalParts);
283313
+ const capturedEntries = [...retiredEntries, ...entries2];
283314
+ const touched = collectCapturedTouchedParts(capturedEntries);
283315
+ const finalParts = snapshotCapturedParts(staging, touched, capturedEntries, "after");
283316
+ const originals = snapshotCapturedParts(session, touched, capturedEntries, "before");
283317
+ const group = buildCapturedCompositeForwardPatchGroup(session, capturedEntries, originals, finalParts);
283266
283318
  if (Object.keys(group.perPart).length === 0)
283267
283319
  return { value, prepared: null };
283268
283320
  const storyIds = group.storiesTouched;
@@ -283332,11 +283384,15 @@ function composeSDDocumentSessionInternalCapturedHistory(session, input) {
283332
283384
  return null;
283333
283385
  const entries2 = requireCapturedHistoryEntries(session, input.txIds);
283334
283386
  const touchedParts = collectCapturedTouchedParts(entries2);
283335
- const finalParts = snapshotCapturedParts(session, touchedParts);
283336
- rollbackCapturedHistoryEntries(session, entries2);
283337
- const originalParts = snapshotCapturedParts(session, touchedParts);
283338
- for (const txId of input.txIds)
283339
- deleteSDDocumentSessionInternalHistoryEntry(session, txId);
283387
+ let finalParts;
283388
+ try {
283389
+ finalParts = snapshotCapturedParts(session, touchedParts, entries2, "after");
283390
+ } finally {
283391
+ rollbackCapturedHistoryEntries(session, entries2);
283392
+ for (const txId of input.txIds)
283393
+ deleteSDDocumentSessionInternalHistoryEntry(session, txId);
283394
+ }
283395
+ const originalParts = snapshotCapturedParts(session, touchedParts, entries2, "before");
283340
283396
  const forwardPatchGroup = buildCapturedCompositeForwardPatchGroup(session, entries2, originalParts, finalParts);
283341
283397
  const internal = INTERNALS.get(session);
283342
283398
  const hasSessionChanges = composeSessionHyperlinkHistory(internal.state, entries2.map((entry) => entry.forwardPatchGroup), forwardPatchGroup);
@@ -283380,17 +283436,63 @@ function collectCapturedTouchedParts(entries2) {
283380
283436
  }
283381
283437
  return [...parts];
283382
283438
  }
283383
- function snapshotCapturedParts(session, partUris) {
283439
+ function snapshotCapturedParts(session, partUris, entries2, phase) {
283384
283440
  const snapshots = new Map;
283385
283441
  for (const uri of partUris) {
283386
283442
  const bytes = getSDDocumentSessionInternalPartBytes(session, uri);
283443
+ const descriptor = getSDDocumentSessionInternalPartDescriptor(session, uri);
283444
+ if (!bytes && descriptor) {
283445
+ const paragraph = capturedSourceParagraphWindow(entries2, uri, phase);
283446
+ if (!paragraph)
283447
+ throw new Error("Captured source history requires a bounded paragraph.");
283448
+ const index = getStoryParagraphIndexFromState(INTERNALS.get(session).state, paragraph.storyId);
283449
+ const current = index?.byParaId(paragraph.blockId);
283450
+ if (!current || index.duplicateParaIds.has(paragraph.blockId) || current.partUri !== uri || current.byteStart !== paragraph.startByte || current.byteEnd !== paragraph.endByte) {
283451
+ throw new Error("Captured source history requires a current bounded paragraph.");
283452
+ }
283453
+ const range = getSDDocumentSessionInternalPartRange(session, uri, paragraph.startByte, paragraph.endByte);
283454
+ if (!range)
283455
+ throw new Error("Captured source history requires readable bounded paragraph bytes.");
283456
+ snapshots.set(uri, { bytes: range.slice(), contentType: descriptor.contentType, paragraph });
283457
+ continue;
283458
+ }
283387
283459
  snapshots.set(uri, {
283388
283460
  bytes: bytes ? new Uint8Array(bytes) : null,
283389
- contentType: getSDDocumentSessionInternalPartDescriptor(session, uri)?.contentType ?? null
283461
+ contentType: descriptor?.contentType ?? null
283390
283462
  });
283391
283463
  }
283392
283464
  return snapshots;
283393
283465
  }
283466
+ function capturedSourceParagraphWindow(entries2, partUri, phase) {
283467
+ const touching = entries2.filter((entry) => entry.forwardPatchGroup.perPart[partUri]);
283468
+ const stories = uniqueCaptured(touching.flatMap((entry) => entry.forwardPatchGroup.storiesTouched));
283469
+ const first = touching[0]?.forwardPatchGroup.indexRefreshScope?.perPart[partUri];
283470
+ if (stories.length !== 1 || first?.kind !== "paragraph" || first.blockIds?.length !== 1)
283471
+ return null;
283472
+ const blockId = first.blockIds[0];
283473
+ let window2 = first.beforeWindow;
283474
+ for (const entry of touching) {
283475
+ const forward = entry.forwardPatchGroup;
283476
+ const inverse2 = entry.inversePatchGroup;
283477
+ const before = forward.indexRefreshScope?.perPart[partUri];
283478
+ const after = inverse2.indexRefreshScope?.perPart[partUri];
283479
+ for (const [group, scope] of [[forward, before], [inverse2, after]]) {
283480
+ const part2 = group.perPart[partUri];
283481
+ if (scope?.kind !== "paragraph" || scope.blockIds?.length !== 1 || scope.blockIds[0] !== blockId || (scope.directBodyChildDelta ?? 0) !== 0 || (scope.nestedParagraphDelta ?? 0) !== 0 || !Number.isSafeInteger(scope.beforeWindow.startByte) || !Number.isSafeInteger(scope.beforeWindow.endByte) || scope.beforeWindow.startByte < 0 || scope.beforeWindow.endByte <= scope.beforeWindow.startByte || scope.beforeWindow.endByte - scope.beforeWindow.startByte > 512 * 1024 || part2?.kind !== "modify" || part2.patches.length === 0 || part2.patches.some((patch) => patch.kind === "insertBytes" ? patch.atByte < scope.beforeWindow.startByte || patch.atByte > scope.beforeWindow.endByte : patch.startByte < scope.beforeWindow.startByte || patch.endByte > scope.beforeWindow.endByte))
283482
+ return null;
283483
+ }
283484
+ if (before.beforeWindow.startByte !== window2.startByte || before.beforeWindow.endByte !== window2.endByte)
283485
+ return null;
283486
+ const part = forward.perPart[partUri];
283487
+ if (part.kind !== "modify")
283488
+ return null;
283489
+ const delta = part.patches.reduce((sum, patch) => sum + (patch.kind === "deleteBytes" ? 0 : patch.bytes.length) - (patch.kind === "insertBytes" ? 0 : patch.endByte - patch.startByte), 0);
283490
+ if (after.beforeWindow.startByte !== window2.startByte || after.beforeWindow.endByte !== window2.endByte + delta)
283491
+ return null;
283492
+ window2 = after.beforeWindow;
283493
+ }
283494
+ return { storyId: stories[0], blockId, ...phase === "before" ? first.beforeWindow : window2 };
283495
+ }
283394
283496
  function rollbackCapturedHistoryEntries(session, entries2) {
283395
283497
  const receipts = [];
283396
283498
  for (let index = entries2.length - 1;index >= 0; index -= 1) {
@@ -283411,6 +283513,7 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283411
283513
  const preconditions = [];
283412
283514
  const patchMaps = {};
283413
283515
  const perPartBaseRevision = {};
283516
+ const paragraphScopes = {};
283414
283517
  const touchedParts = new Set([...originalParts.keys(), ...finalParts.keys()]);
283415
283518
  for (const partUri of touchedParts) {
283416
283519
  const original = originalParts.get(partUri) ?? {
@@ -283418,12 +283521,32 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283418
283521
  contentType: null
283419
283522
  };
283420
283523
  const final = finalParts.get(partUri) ?? { bytes: null, contentType: null };
283421
- if (original.bytes && final.bytes) {
283524
+ if (original.paragraph || final.paragraph) {
283525
+ if (!original.bytes || !final.bytes || !original.paragraph || !final.paragraph || original.paragraph.blockId !== final.paragraph.blockId || original.paragraph.startByte !== final.paragraph.startByte) {
283526
+ throw new Error("Captured source history requires matching bounded paragraph snapshots.");
283527
+ }
283528
+ if (capturedBytesEqual(original.bytes, final.bytes))
283529
+ continue;
283530
+ const { startByte, endByte, blockId } = original.paragraph;
283531
+ perPart[partUri] = { kind: "modify", patches: [
283532
+ { kind: "replaceBytes", order: 0, startByte, endByte, bytes: final.bytes }
283533
+ ] };
283534
+ paragraphScopes[partUri] = { kind: "paragraph", beforeWindow: { startByte, endByte }, blockIds: [blockId] };
283535
+ preconditions.push({
283536
+ kind: "byteWindow",
283537
+ partUri,
283538
+ startByte,
283539
+ endByte,
283540
+ algorithm: "sha256",
283541
+ hash: sha256HexSync(original.bytes)
283542
+ });
283543
+ } else if (original.bytes && final.bytes) {
283422
283544
  if (capturedBytesEqual(original.bytes, final.bytes))
283423
283545
  continue;
283546
+ const paragraph = capturedParagraphComposite(entries2, partUri, original.bytes, final.bytes);
283424
283547
  perPart[partUri] = {
283425
283548
  kind: "modify",
283426
- patches: [
283549
+ patches: paragraph ? [paragraph.patch] : [
283427
283550
  {
283428
283551
  kind: "replaceBytes",
283429
283552
  order: 0,
@@ -283433,7 +283556,13 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283433
283556
  }
283434
283557
  ]
283435
283558
  };
283436
- preconditions.push(capturedByteWindowPrecondition(partUri, original.bytes));
283559
+ if (paragraph)
283560
+ paragraphScopes[partUri] = paragraph.scope;
283561
+ preconditions.push(paragraph ? buildLocalizedByteWindowPrecondition({
283562
+ partUri,
283563
+ bytes: original.bytes,
283564
+ patches: [paragraph.patch]
283565
+ }) : capturedByteWindowPrecondition(partUri, original.bytes));
283437
283566
  } else if (!original.bytes && final.bytes) {
283438
283567
  perPart[partUri] = {
283439
283568
  kind: "create",
@@ -283465,7 +283594,28 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283465
283594
  perPart,
283466
283595
  patchMaps,
283467
283596
  storiesTouched: uniqueCaptured(entries2.flatMap((entry) => entry.forwardPatchGroup.storiesTouched)),
283468
- signalLanesToRebuild: uniqueCaptured(entries2.flatMap((entry) => entry.forwardPatchGroup.signalLanesToRebuild))
283597
+ signalLanesToRebuild: uniqueCaptured(entries2.flatMap((entry) => entry.forwardPatchGroup.signalLanesToRebuild)),
283598
+ ...Object.keys(paragraphScopes).length > 0 ? { indexRefreshScope: { perPart: paragraphScopes } } : {}
283599
+ };
283600
+ }
283601
+ function capturedParagraphComposite(entries2, partUri, original, final) {
283602
+ const touching = entries2.filter((entry) => entry.forwardPatchGroup.perPart[partUri]);
283603
+ const first = touching[0]?.forwardPatchGroup.indexRefreshScope?.perPart[partUri];
283604
+ if (!first || first.kind !== "paragraph" || first.blockIds?.length !== 1)
283605
+ return null;
283606
+ const blockId = first.blockIds[0];
283607
+ if (touching.some((entry) => {
283608
+ const scope = entry.forwardPatchGroup.indexRefreshScope?.perPart[partUri];
283609
+ return entry.forwardPatchGroup.perPart[partUri]?.kind !== "modify" || scope?.kind !== "paragraph" || scope.blockIds?.length !== 1 || scope.blockIds[0] !== blockId || (scope.directBodyChildDelta ?? 0) !== 0 || (scope.nestedParagraphDelta ?? 0) !== 0;
283610
+ }))
283611
+ return null;
283612
+ const { startByte, endByte } = first.beforeWindow;
283613
+ const finalEndByte = endByte + final.length - original.length;
283614
+ if (startByte < 0 || endByte < startByte || endByte > original.length || finalEndByte < startByte || finalEndByte > final.length || !capturedBytesEqual(original.subarray(0, startByte), final.subarray(0, startByte)) || !capturedBytesEqual(original.subarray(endByte), final.subarray(finalEndByte)))
283615
+ return null;
283616
+ return {
283617
+ patch: { kind: "replaceBytes", order: 0, startByte, endByte, bytes: final.subarray(startByte, finalEndByte) },
283618
+ scope: { kind: "paragraph", beforeWindow: { startByte, endByte }, blockIds: [blockId] }
283469
283619
  };
283470
283620
  }
283471
283621
  function invertCapturedSemanticDelta(delta) {
@@ -286161,6 +286311,7 @@ var init_sd_document_session = __esm(() => {
286161
286311
  init_section_margin_update();
286162
286312
  init_session_hyperlink_metadata();
286163
286313
  init_history_text_replay();
286314
+ init_patch_substrate();
286164
286315
  init_history_part_rewrite();
286165
286316
  init_v2_open();
286166
286317
  init_package_open();
@@ -287828,9 +287979,21 @@ var init_address2 = __esm(() => {
287828
287979
  // ../../packages/document-api/src/types/track-changes.types.ts
287829
287980
  var TRACK_CHANGES_IN_ALL = "all";
287830
287981
 
287982
+ // ../../packages/document-api/src/inline-semantics/property-ids.ts
287983
+ var CORE_PROPERTY_IDS, CORE_PROPERTY_ID_SET, CORE_TOGGLE_PROPERTY_IDS, CORE_TOGGLE_PROPERTY_ID_SET;
287984
+ var init_property_ids = __esm(() => {
287985
+ CORE_PROPERTY_IDS = ["bold", "italic", "underline", "strike"];
287986
+ CORE_PROPERTY_ID_SET = new Set(CORE_PROPERTY_IDS);
287987
+ CORE_TOGGLE_PROPERTY_IDS = ["bold", "italic", "strike"];
287988
+ CORE_TOGGLE_PROPERTY_ID_SET = new Set(CORE_TOGGLE_PROPERTY_IDS);
287989
+ });
287990
+
287831
287991
  // ../../packages/document-api/src/types/style-policy.types.ts
287832
- var INLINE_DIRECTIVES2, INLINE_DIRECTIVE_SET2;
287992
+ var MARK_KEYS, MARK_KEY_SET, INLINE_DIRECTIVES2, INLINE_DIRECTIVE_SET2;
287833
287993
  var init_style_policy_types2 = __esm(() => {
287994
+ init_property_ids();
287995
+ MARK_KEYS = CORE_PROPERTY_IDS;
287996
+ MARK_KEY_SET = CORE_PROPERTY_ID_SET;
287834
287997
  INLINE_DIRECTIVES2 = ["on", "off", "clear"];
287835
287998
  INLINE_DIRECTIVE_SET2 = new Set(INLINE_DIRECTIVES2);
287836
287999
  });
@@ -288326,7 +288489,7 @@ function buildInlineRunPatchSchema2() {
288326
288489
  minProperties: 1
288327
288490
  };
288328
288491
  }
288329
- var schemaBooleanOrNull2 = () => ({
288492
+ var CLEAR_INLINE_FORMATTING_KEYS2, schemaBooleanOrNull2 = () => ({
288330
288493
  oneOf: [{ type: "boolean" }, { type: "null" }]
288331
288494
  }), schemaStringOrNull2 = () => ({
288332
288495
  oneOf: [{ type: "string", minLength: 1 }, { type: "null" }]
@@ -288380,6 +288543,21 @@ var schemaBooleanOrNull2 = () => ({
288380
288543
  }), INLINE_PROPERTY_REGISTRY2, INLINE_PROPERTY_KEY_SET2, INLINE_PROPERTY_BY_KEY2, INLINE_PROPERTY_KEYS_BY_STORAGE2, UNDERLINE_OBJECT_ALLOWED_KEYS2, SHADING_ALLOWED_KEYS2, BORDER_ALLOWED_KEYS2, FIT_TEXT_ALLOWED_KEYS2, LANG_ALLOWED_KEYS2, RFONTS_ALLOWED_KEYS2, EAST_ASIAN_LAYOUT_ALLOWED_KEYS2, STYLISTIC_SET_ALLOWED_KEYS2, VERT_ALIGN_VALUES2, PROPERTY_VALIDATOR_MAP2;
288381
288544
  var init_inline_run_patch2 = __esm(() => {
288382
288545
  init_errors6();
288546
+ CLEAR_INLINE_FORMATTING_KEYS2 = Object.freeze([
288547
+ "bold",
288548
+ "italic",
288549
+ "underline",
288550
+ "strike",
288551
+ "color",
288552
+ "highlight",
288553
+ "fontFamily",
288554
+ "fontSize",
288555
+ "vertAlign",
288556
+ "smallCaps",
288557
+ "caps",
288558
+ "letterSpacing",
288559
+ "dstrike"
288560
+ ]);
288383
288561
  UNDERLINE_OBJECT_SCHEMA2 = {
288384
288562
  type: "object",
288385
288563
  properties: {
@@ -412654,7 +412832,7 @@ function isSupportedMutationPlanStepOp(op) {
412654
412832
  var MUTATION_PLAN_ENGINE_SUPPORT, MUTATION_PLAN_SUPPORTED_STEP_OPS, MUTATION_PLAN_MUTATING_STEP_OPS;
412655
412833
  var init_support_contract = __esm(() => {
412656
412834
  MUTATION_PLAN_ENGINE_SUPPORT = Object.freeze({
412657
- version: "4",
412835
+ version: "5",
412658
412836
  supportedStepOps: Object.freeze([
412659
412837
  "text.rewrite",
412660
412838
  "text.delete",
@@ -412687,6 +412865,9 @@ var init_support_contract = __esm(() => {
412687
412865
  ]),
412688
412866
  unsupported: Object.freeze([
412689
412867
  { cell: "text.rewrite:args.style:custom-policy", reason: "only-native-preserve-style-policy-supported" },
412868
+ { cell: "text.insert.args.style:after-tracked-format-boundary", reason: "projected-insertion-carrier-formatting-not-supported" },
412869
+ { cell: "text.insert.args.style:tracked-formatting-carrier", reason: "direct-inserted-text-formatting-cannot-rewrite-rpr-change" },
412870
+ { cell: "text.insert.args.style:tracked-coordinate-space", reason: "style-patch-requires-visible-inserted-text-selection" },
412690
412871
  { cell: "structural.insert", reason: "structural-slice-not-yet-proven" },
412691
412872
  { cell: "structural.replace:non-block-rich-text-sdt", reason: "only-paragraph-content-block-sdt-replacement-proven" },
412692
412873
  { cell: "structural.replace:tracked", reason: "structural-sdt-replacement-direct-only" },
@@ -427897,7 +428078,7 @@ var init_adapter24 = __esm(() => {
427897
428078
  init_adapter23();
427898
428079
  V2_SUPPORTED_STEP_OPS = MUTATION_PLAN_SUPPORTED_STEP_OPS;
427899
428080
  V2_SUPPORTED_NON_UNIFORM_STRATEGIES = Object.freeze([]);
427900
- V2_SUPPORTED_SET_MARKS = Object.freeze([]);
428081
+ V2_SUPPORTED_SET_MARKS = MARK_KEYS;
427901
428082
  V2_REGEX_LIMITS = Object.freeze({
427902
428083
  maxPatternLength: SD_TEXT_SEARCH_MAX_REGEX_PATTERN_LENGTH,
427903
428084
  maxExecutionMs: 100
@@ -442935,7 +443116,7 @@ async function compilePlan(context, input) {
442935
443116
  throw error48;
442936
443117
  }
442937
443118
  }
442938
- detectTargetConflicts(context, steps, failures);
443119
+ detectTargetConflicts(context, steps, failures, changeMode);
442939
443120
  detectUnsupportedRuntimeDrift(input.steps, failures);
442940
443121
  const exactProgram = failures.length === 0 ? compileDescendingExactTargets(context, steps) : undefined;
442941
443122
  if (exactProgram) {
@@ -443505,17 +443686,30 @@ function detectUnsupportedRuntimeDrift(steps, failures) {
443505
443686
  }
443506
443687
  }
443507
443688
  }
443508
- function detectTargetConflicts(context, steps, failures) {
443689
+ function detectTargetConflicts(context, steps, failures, changeMode) {
443509
443690
  const claimedByKey = new Map;
443510
443691
  const conflicted = new Set;
443511
443692
  for (const step3 of steps) {
443512
443693
  const resolutions = step3.resolutions ?? (step3.resolution ? [step3.resolution] : []);
443694
+ const requests = step3.requests ?? (step3.request ? [step3.request] : []);
443513
443695
  const currentClaims = [];
443514
- for (const resolution of resolutions) {
443696
+ for (const [index2, resolution] of resolutions.entries()) {
443515
443697
  const target = resolution.target;
443516
443698
  const key3 = `${storyKeyForTarget(target)}::${target.blockId}`;
443517
443699
  const { from, to } = conflictRangeForResolution(context, step3, resolution);
443700
+ const request = requests[index2];
443701
+ const styledAnchor = request?.kind === "insert" && request.inline && request.text.length > 0 && request.target.start.kind === "text" ? request.target.start.offset : undefined;
443518
443702
  for (const prior of claimedByKey.get(key3) ?? []) {
443703
+ if (prior.trackedInlineFormat && styledAnchor !== undefined && (styledAnchor === prior.to || styledAnchor === 0 && prior.from === 0)) {
443704
+ failures.push({
443705
+ code: "CAPABILITY_UNSUPPORTED",
443706
+ stepId: step3.stepId,
443707
+ phase: "compile",
443708
+ message: "text.insert style changes cannot inherit a carrier formatted by an earlier tracked step."
443709
+ });
443710
+ conflicted.add(step3.stepId);
443711
+ break;
443712
+ }
443519
443713
  if (rangesOverlap12(from, to, prior.from, prior.to)) {
443520
443714
  failures.push({
443521
443715
  code: "PLAN_CONFLICT_OVERLAP",
@@ -443527,11 +443721,17 @@ function detectTargetConflicts(context, steps, failures) {
443527
443721
  break;
443528
443722
  }
443529
443723
  }
443530
- currentClaims.push({ key: key3, from, to, stepId: step3.stepId });
443724
+ currentClaims.push({
443725
+ key: key3,
443726
+ from,
443727
+ to,
443728
+ stepId: step3.stepId,
443729
+ trackedInlineFormat: changeMode === "tracked" && request?.kind === "format" && !!request.inline
443730
+ });
443531
443731
  }
443532
443732
  for (const claim of currentClaims) {
443533
443733
  const prior = claimedByKey.get(claim.key) ?? [];
443534
- prior.push({ from: claim.from, to: claim.to, stepId: claim.stepId });
443734
+ prior.push(claim);
443535
443735
  claimedByKey.set(claim.key, prior);
443536
443736
  }
443537
443737
  }
@@ -443673,7 +443873,7 @@ function resolveTargetWhereMutationStep(context, step3, where, story, changeMode
443673
443873
  }
443674
443874
  const selectionMutation = new V2SelectionMutationAdapter(context);
443675
443875
  if (step3.op === "text.insert") {
443676
- const { text: text4, position: position2 } = readInsertArgs(step3);
443876
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
443677
443877
  const point3 = position2 === "before" ? target.start : target.end;
443678
443878
  const collapsed = {
443679
443879
  kind: "selection",
@@ -443682,8 +443882,9 @@ function resolveTargetWhereMutationStep(context, step3, where, story, changeMode
443682
443882
  ...target.story ? { story: target.story } : {},
443683
443883
  ...target.coordinateSpace ? { coordinateSpace: target.coordinateSpace } : {}
443684
443884
  };
443685
- const request = { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} };
443686
- const receipt3 = selectionMutation.execute({ kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} }, { changeMode, dryRun: true });
443885
+ const request = buildInsertCommitRequest(context, collapsed, text4, inline, story);
443886
+ const { inline: _inline, ...dryRunRequest } = request;
443887
+ const receipt3 = selectionMutation.execute(dryRunRequest, { changeMode, dryRun: true });
443687
443888
  if (!receipt3.success)
443688
443889
  throw new DocumentApiValidationError2(receipt3.failure.code, receipt3.failure.message);
443689
443890
  const resolution2 = {
@@ -443837,7 +444038,7 @@ function resolveRefMutationStep(context, step3, story, ref5, changeMode, cache,
443837
444038
  };
443838
444039
  }
443839
444040
  if (step3.op === "text.insert") {
443840
- const { text: text4, position: position2 } = readInsertArgs(step3);
444041
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
443841
444042
  const offset = position2 === "before" ? outcome.resolved.startOffset : outcome.resolved.endOffset;
443842
444043
  const storyLocator = outcome.storyLocator;
443843
444044
  const point3 = {
@@ -443858,7 +444059,7 @@ function resolveRefMutationStep(context, step3, story, ref5, changeMode, cache,
443858
444059
  op: "text.insert",
443859
444060
  resolution,
443860
444061
  kernelRange: outcome.resolved,
443861
- request: { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} },
444062
+ request: buildInsertCommitRequest(context, collapsed, text4, inline, story),
443862
444063
  noopEquivalentText: text4.length === 0 ? text4 : undefined,
443863
444064
  source: step3
443864
444065
  };
@@ -443971,6 +444172,7 @@ async function resolveAllSelectMutationStep(context, step3, where, story, change
443971
444172
  resolutions: coalescedEntries.map((entry) => entry.resolution),
443972
444173
  requests: coalescedEntries.map((entry) => entry.request),
443973
444174
  kernelRanges: coalescedEntries.flatMap((entry) => entry.kernelRange ? [entry.kernelRange] : []),
444175
+ ...step3.op === "text.insert" ? { noopEquivalentText: resolved[0].noopEquivalentText } : {},
443974
444176
  ...step3.op === "text.rewrite" && step3.args.caseHandling !== "preserve-match" && step3.args.replacementMode !== "regex-template" ? { noopEquivalentText: normalizeReplacement(step3.args.replacement) } : {},
443975
444177
  source: step3
443976
444178
  };
@@ -444043,7 +444245,7 @@ function resolveBlockMutationStep(context, step3, where, story) {
444043
444245
  };
444044
444246
  }
444045
444247
  if (step3.op === "text.insert") {
444046
- const { text: text4, position: position2 } = readInsertArgs(step3);
444248
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
444047
444249
  const offset = position2 === "before" ? 0 : raw.textLength;
444048
444250
  const point3 = {
444049
444251
  kind: "text",
@@ -444071,7 +444273,7 @@ function resolveBlockMutationStep(context, step3, where, story) {
444071
444273
  stepId: step3.id,
444072
444274
  op: "text.insert",
444073
444275
  resolution: collapsedResolution,
444074
- request: { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} },
444276
+ request: buildInsertCommitRequest(context, collapsed, text4, inline, story),
444075
444277
  noopEquivalentText: text4.length === 0 ? text4 : undefined,
444076
444278
  source: step3
444077
444279
  };
@@ -444141,7 +444343,7 @@ function resolveRangeRefMutationStep(context, step3, story, ref5) {
444141
444343
  };
444142
444344
  }
444143
444345
  if (step3.op === "text.insert") {
444144
- const { text: text4, position: position2 } = readInsertArgs(step3);
444346
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
444145
444347
  const offset = position2 === "before" ? target.range.start : target.range.end;
444146
444348
  const point3 = {
444147
444349
  kind: "text",
@@ -444160,7 +444362,7 @@ function resolveRangeRefMutationStep(context, step3, story, ref5) {
444160
444362
  stepId: step3.id,
444161
444363
  op: "text.insert",
444162
444364
  resolution,
444163
- request: { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} },
444365
+ request: buildInsertCommitRequest(context, collapsed, text4, inline, story),
444164
444366
  noopEquivalentText: text4.length === 0 ? text4 : undefined,
444165
444367
  source: step3
444166
444368
  };
@@ -444362,12 +444564,36 @@ function commitRequest(selectionMutation, paragraphs2, controls, request, change
444362
444564
  };
444363
444565
  }
444364
444566
  if (request.kind === "insert") {
444365
- return selectionMutation.execute({
444567
+ const receipt3 = selectionMutation.execute({
444366
444568
  kind: "replace",
444367
444569
  target: request.target,
444368
444570
  text: request.text,
444369
444571
  ...request.in ? { in: request.in } : {}
444370
444572
  }, { changeMode });
444573
+ if (!receipt3.success || !request.inline)
444574
+ return receipt3;
444575
+ const insertedText = receipt3.effects?.insertedText;
444576
+ if (!insertedText?.length || insertedText.some((effect) => !effect.selectionTarget)) {
444577
+ return {
444578
+ success: false,
444579
+ failure: {
444580
+ code: "CAPABILITY_UNSUPPORTED",
444581
+ message: "text.insert style requires an exact inserted-text selection."
444582
+ },
444583
+ resolution: receipt3.resolution
444584
+ };
444585
+ }
444586
+ for (const effect of insertedText) {
444587
+ const formatted = selectionMutation.execute({
444588
+ kind: "format",
444589
+ target: effect.selectionTarget,
444590
+ inline: request.inline,
444591
+ ...request.in ? { in: request.in } : {}
444592
+ }, { changeMode: "direct" });
444593
+ if (!formatted.success && formatted.failure.code !== "NO_OP")
444594
+ return formatted;
444595
+ }
444596
+ return receipt3;
444371
444597
  }
444372
444598
  if ("target" in request) {
444373
444599
  return selectionMutation.execute({
@@ -444534,14 +444760,64 @@ function readInsertArgs(step3) {
444534
444760
  if (position2 !== "before" && position2 !== "after") {
444535
444761
  throw new DocumentApiValidationError2("INVALID_INPUT", 'text.insert requires args.position to be "before" or "after".');
444536
444762
  }
444537
- if (step3.args?.style !== undefined) {
444538
- throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "v2 text.insert plan steps do not yet support args.style.");
444539
- }
444763
+ const inline = readInsertInlinePatch(step3.args?.style);
444540
444764
  const text4 = step3.args?.content?.text;
444541
444765
  if (typeof text4 !== "string") {
444542
444766
  throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert requires args.content.text.");
444543
444767
  }
444544
- return { text: text4, position: position2 };
444768
+ return { text: text4, position: position2, inline };
444769
+ }
444770
+ function readInsertInlinePatch(style) {
444771
+ if (style === undefined)
444772
+ return;
444773
+ if (!style || typeof style !== "object" || Array.isArray(style) || Object.keys(style).some((key3) => key3 !== "inline")) {
444774
+ throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert args.style requires an inline policy.");
444775
+ }
444776
+ const inline = style.inline;
444777
+ if (!inline || typeof inline !== "object" || Array.isArray(inline) || Object.keys(inline).some((key3) => key3 !== "mode" && key3 !== "setMarks")) {
444778
+ throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert args.style.inline requires mode and optional setMarks.");
444779
+ }
444780
+ const { mode, setMarks } = inline;
444781
+ if (mode !== "inherit" && mode !== "set" && mode !== "clear") {
444782
+ throw new DocumentApiValidationError2("INVALID_INPUT", 'text.insert args.style.inline.mode must be "inherit", "set", or "clear".');
444783
+ }
444784
+ const patch = mode === "clear" ? Object.fromEntries(CLEAR_INLINE_FORMATTING_KEYS2.map((key3) => [key3, null])) : {};
444785
+ if (setMarks !== undefined) {
444786
+ if (!setMarks || typeof setMarks !== "object" || Array.isArray(setMarks)) {
444787
+ throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert args.style.inline.setMarks must be an object.");
444788
+ }
444789
+ for (const [key3, directive] of Object.entries(setMarks)) {
444790
+ if (!MARK_KEY_SET.has(key3) || typeof directive !== "string" || !INLINE_DIRECTIVE_SET2.has(directive)) {
444791
+ throw new DocumentApiValidationError2("INVALID_INPUT", `Invalid text.insert setMarks directive for "${key3}".`);
444792
+ }
444793
+ patch[key3] = directive === "on" ? true : directive === "off" ? false : null;
444794
+ }
444795
+ }
444796
+ return Object.keys(patch).length > 0 ? patch : undefined;
444797
+ }
444798
+ function buildInsertCommitRequest(context, target, text4, inline, story) {
444799
+ if (text4.length > 0 && inline && target.coordinateSpace === "tracked") {
444800
+ throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "text.insert style changes require visible coordinates for an exact inserted-text selection.");
444801
+ }
444802
+ if (text4.length > 0 && inline && target.start.kind === "text") {
444803
+ const index2 = paragraphIndexForRangeRef(context, target.story ?? story);
444804
+ const entry = index2.byParaId(target.start.blockId);
444805
+ const bytes = entry && getSDDocumentSessionInternalPartRange(context.session, entry.partUri, entry.byteStart, entry.byteEnd);
444806
+ if (!bytes) {
444807
+ throw new DocumentApiValidationError2("PRECONDITION_FAILED", "Insertion carrier bytes are unavailable.");
444808
+ }
444809
+ const paragraphXml = TD133.decode(bytes);
444810
+ if (/<(?:[\w.-]+:)?rPrChange\b/.test(paragraphXml)) {
444811
+ const namespaces = getSDDocumentSessionInternalMainStoryRootNamespaceBindings(context.session) ?? {};
444812
+ const at = target.start.offset;
444813
+ const planned = planDirectInlineEdit(bytes, at, at, text4, undefined, undefined, namespaces);
444814
+ const properties2 = planned.ok && planned.runPropertiesXml !== undefined ? [planned.runPropertiesXml] : parseParagraphInlineMap(paragraphXml, namespaces).leaves().flatMap((piece) => (piece.kind === "text" && piece.textRole === "visible" || piece.kind === "control" && !piece.deleted) && piece.visibleStart <= at && at <= piece.visibleEnd ? [piece.runProperties ?? ""] : []);
444815
+ if (properties2.some((value3) => /<(?:[\w.-]+:)?rPrChange\b/.test(value3))) {
444816
+ throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "text.insert style changes do not support insertion carriers with tracked formatting changes.");
444817
+ }
444818
+ }
444819
+ }
444820
+ return { kind: "insert", target, text: text4, ...inline ? { inline } : {}, ...story ? { in: story } : {} };
444545
444821
  }
444546
444822
  function normalizeReplacement(replacement2) {
444547
444823
  if (!replacement2 || typeof replacement2.text !== "string" && !Array.isArray(replacement2.blocks)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc/mcp",
3
- "version": "1.10.1-next.1",
3
+ "version": "1.10.1-next.2",
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.23.1-next.1",
27
+ "@superdoc/sdk": "2.23.1-next.2",
28
28
  "debug": "^4.4.3",
29
29
  "zod": "^4.3.6"
30
30
  },
31
31
  "devDependencies": {
32
- "superdoc": "2.26.1-next.1",
33
- "@superdoc/docx-engine": "0.25.1-next.1",
32
+ "superdoc": "2.26.1-next.2",
33
+ "@superdoc/docx-engine": "0.25.1-next.2",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",