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

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 +462 -60
  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.3";
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: {
@@ -182155,6 +182170,14 @@ function readResidentParagraphNamespaces(state, blockId) {
182155
182170
  return null;
182156
182171
  return store.paragraphs.get(blockId)?.namespaceBindings ?? store.readOnlyNamespaces.get(blockId)?.namespaceBindings ?? null;
182157
182172
  }
182173
+ function readResidentParagraphNamespaceScope(state, blockId) {
182174
+ const namespaceBindings = readResidentParagraphNamespaces(state, blockId);
182175
+ if (!namespaceBindings)
182176
+ return null;
182177
+ const store = stores.get(state);
182178
+ const parentNamespaceBindings = store.paragraphs.get(blockId)?.parentNamespaceBindings ?? store.readOnlyNamespaces.get(blockId)?.parentNamespaceBindings;
182179
+ return parentNamespaceBindings ? Object.freeze({ namespaceBindings, parentNamespaceBindings }) : null;
182180
+ }
182158
182181
  function prepareResidentParagraphOwnershipPublication(state, group) {
182159
182182
  const store = stores.get(state);
182160
182183
  if (!store)
@@ -196553,7 +196576,7 @@ function resolveEditScope(pieces, start, end, collapsedInlineAffinity, collapsed
196553
196576
  let emptySdt;
196554
196577
  let requiresCollaborationSessionSync = false;
196555
196578
  for (;; ) {
196556
- const container = current.find((piece) => piece.kind === "container" && containerContainsRange(piece, start, end)) ?? (start === end ? findCollapsedEdgeContainer(current, start, collapsedInlineAffinity, collapsedOutsideContentControl) : undefined);
196579
+ const container = start === end ? findCaretContainer(current, start, collapsedInlineAffinity, collapsedOutsideContentControl) : current.find((piece) => piece.kind === "container" && containerContainsRange(piece, start, end));
196557
196580
  if (!container) {
196558
196581
  if (start === end) {
196559
196582
  return {
@@ -196656,6 +196679,9 @@ function containerContainsRange(piece, start, end) {
196656
196679
  return piece.visibleStart < start && start < piece.visibleEnd;
196657
196680
  return piece.visibleStart <= start && end <= piece.visibleEnd;
196658
196681
  }
196682
+ function findCaretContainer(pieces, at, collapsedInlineAffinity, collapsedOutsideContentControl = false) {
196683
+ return pieces.find((piece) => piece.kind === "container" && containerContainsRange(piece, at, at)) ?? findCollapsedEdgeContainer(pieces, at, collapsedInlineAffinity, collapsedOutsideContentControl);
196684
+ }
196659
196685
  function findCollapsedEdgeContainer(pieces, at, collapsedInlineAffinity, collapsedOutsideContentControl = false) {
196660
196686
  const emptySdtsAtPoint = pieces.filter((piece) => piece.kind === "container" && piece.containerKind === "sdt" && piece.visibleStart === at && piece.visibleEnd === at);
196661
196687
  return pieces.find((piece) => {
@@ -214884,7 +214910,8 @@ function commitTracked(input, view) {
214884
214910
  bytes: TE19.encode(ownLinkedRefinement.xml),
214885
214911
  emittedBothSides: false,
214886
214912
  foldedInsRsid: ownLinkedRefinement.rsid,
214887
- requiresCollaborationSessionSync: true
214913
+ requiresCollaborationSessionSync: true,
214914
+ createdVisibleTextSpan: compileOp.on.coordinateSpace !== "tracked" ? ownLinkedRefinement.createdVisibleTextSpan : undefined
214888
214915
  };
214889
214916
  }
214890
214917
  const canSpanningDelete = compileOp.on.coordinateSpace !== "tracked" && op.newText.length === 0 && compileOp.on.startOffset < compileOp.on.endOffset;
@@ -215144,6 +215171,7 @@ function commitTracked(input, view) {
215144
215171
  author: stamping.author,
215145
215172
  date: stamping.date
215146
215173
  }, compiledCarrier("ins", wId)) : undefined;
215174
+ const createdVisibleTextSpan = localized.createdVisibleTextSpan ?? (isPureTrackedInsert(compileOp) && compileOp.on.coordinateSpace !== "tracked" && (overlapEmittedRsids === null || emittedRsids.includes(insRsid)) ? resolveCreatedTrackedCarrierSpan(localized.bytes, compileOp, wId, insRsid, namespaceBindings) : undefined);
215147
215175
  const shiftParagraphXml = op.on.coordinateSpace === "tracked" ? TD45.decode(bytes.subarray(window2.byteStart, window2.byteEnd)) : null;
215148
215176
  const visibleStartOffset = shiftParagraphXml !== null ? projectTrackedParagraphOffsetToVisible(shiftParagraphXml, op.on.startOffset, inlineModel) : op.on.startOffset;
215149
215177
  const visibleEndOffset = shiftParagraphXml !== null ? projectTrackedParagraphOffsetToVisible(shiftParagraphXml, op.on.endOffset, inlineModel) : op.on.endOffset;
@@ -215255,7 +215283,7 @@ function commitTracked(input, view) {
215255
215283
  }))),
215256
215284
  resyncFromSession,
215257
215285
  requiresCollaborationSessionSync: localized.requiresCollaborationSessionSync,
215258
- createdVisibleTextSpan: localized.createdVisibleTextSpan,
215286
+ createdVisibleTextSpan,
215259
215287
  pushHistory: input.pushHistory,
215260
215288
  paragraphWindow: counterpartPlan?.ownerParagraphWindow ?? {
215261
215289
  byteStart: byteBase + window2.byteStart,
@@ -216034,6 +216062,27 @@ function isPureTrackedInsert(op) {
216034
216062
  function isCollapsedInsert(op) {
216035
216063
  return op.on.startBlockId === op.on.endBlockId && op.on.startOffset === op.on.endOffset && op.newText.length > 0;
216036
216064
  }
216065
+ function resolveCreatedTrackedCarrierSpan(bytes, op, wId, rsid, namespaceBindings = { w: NS_W }) {
216066
+ const model = parseParagraphInlineMap(TD45.decode(bytes), namespaceBindings);
216067
+ const pending2 = [...model.pieces];
216068
+ const carriers = [];
216069
+ while (pending2.length > 0) {
216070
+ const piece = pending2.pop();
216071
+ if (piece.kind === "tracked" && piece.trackedKind === "ins" && piece.revisionId === String(wId) && piece.rsid === rsid)
216072
+ carriers.push(piece);
216073
+ if (piece.kind === "tracked" || piece.kind === "container")
216074
+ pending2.push(...piece.children);
216075
+ }
216076
+ const carrier = carriers.length === 1 ? carriers[0] : undefined;
216077
+ if (!carrier || carrier.visibleStart !== op.on.startOffset || carrier.visibleEnd - carrier.visibleStart !== op.newText.length || model.visibleText().slice(carrier.visibleStart, carrier.visibleEnd) !== op.newText)
216078
+ return;
216079
+ return {
216080
+ startOffset: carrier.visibleStart,
216081
+ endOffset: carrier.visibleEnd,
216082
+ insertedTextLength: carrier.visibleEnd - carrier.visibleStart,
216083
+ source: "new-tracked-carrier"
216084
+ };
216085
+ }
216037
216086
  function createCompiledTrackedCarrierReader(bytes, namespaceBindings = { w: NS_W }) {
216038
216087
  let xml;
216039
216088
  let scan;
@@ -218504,7 +218553,9 @@ function refineOwnLinkedInsertion(model, start, end, newText, author, state) {
218504
218553
  if (start === end) {
218505
218554
  const ordinary = selected.find((piece) => !fieldFor(piece));
218506
218555
  const interior = selected.find((piece) => piece.visibleStart < start && piece.visibleEnd > start);
218507
- const chosen = ordinary ?? interior;
218556
+ const boundaryField = selected.length > 1 ? fieldFor(selected[0]) : undefined;
218557
+ 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;
218558
+ const chosen = ordinary ?? interior ?? boundary;
218508
218559
  if (!chosen)
218509
218560
  return null;
218510
218561
  selected.splice(0, selected.length, chosen);
@@ -218533,7 +218584,16 @@ function refineOwnLinkedInsertion(model, start, end, newText, author, state) {
218533
218584
  let rewritten = paragraphXml;
218534
218585
  for (const patch of patches.reverse())
218535
218586
  rewritten = rewritten.slice(0, patch.start) + patch.xml + rewritten.slice(patch.end);
218536
- return { xml: rewritten, rsid: wrapper.rsid };
218587
+ return {
218588
+ xml: rewritten,
218589
+ rsid: wrapper.rsid,
218590
+ ...start === end && newText.length > 0 ? { createdVisibleTextSpan: {
218591
+ startOffset: start,
218592
+ endOffset: start + newText.length,
218593
+ insertedTextLength: newText.length,
218594
+ source: "same-author-refinement"
218595
+ } } : {}
218596
+ };
218537
218597
  }
218538
218598
  function spliceWithinSameAuthorInsertion(paragraphXml, startOffset, endOffset, newText, author) {
218539
218599
  const createdVisibleTextSpan = startOffset === endOffset && newText.length > 0 ? {
@@ -221785,13 +221845,57 @@ function resolveCaretRunPropertiesForInsertion(paragraphXml, charOffset, inherit
221785
221845
  }
221786
221846
  return cloneAdjacentRunPropertiesForInsert(paragraphXml, "before", paragraphMarkRunPropertiesXml, inheritedNamespaceBindings, charOffset, replaceToOffset, collapsedInlineAffinity, collapsedObjectBoundary);
221787
221847
  }
221788
- function adjacentFormattingCarrierRun(paragraphXml, placement2, inheritedNamespaceBindings = {}, charOffset, replaceToOffset, collapsedInlineAffinity, collapsedObjectBoundary) {
221848
+ function readCaretRunProperties(paragraphXml, charOffset, inheritedNamespaceBindings = {}, collapsedInlineAffinity, collapsedObjectBoundary) {
221849
+ const sourceXml = stripElements(paragraphXml, "txbxContent");
221850
+ const model = parseParagraphInlineMap(sourceXml, inheritedNamespaceBindings);
221851
+ let source;
221852
+ let properties2;
221853
+ if (!collapsedObjectBoundary && (model.visibleLength === 0 || collapsedOutsideContainerAt(model.pieces, charOffset, collapsedInlineAffinity))) {
221854
+ source = findFirstElement(sourceXml, "pPr") ?? undefined;
221855
+ properties2 = source ? extractParagraphMarkRunProperties(source.xml) : "";
221856
+ if (properties2 === null)
221857
+ return { ok: false, reason: "unsupported-context" };
221858
+ } else {
221859
+ let caretPieces = model.pieces;
221860
+ if (!collapsedObjectBoundary) {
221861
+ for (;; ) {
221862
+ const container = findCaretContainer(caretPieces, charOffset, collapsedInlineAffinity);
221863
+ if (!container)
221864
+ break;
221865
+ if (container.policy === "atomic" || container.policy === "fail-closed") {
221866
+ return { ok: false, reason: "unsupported-context" };
221867
+ }
221868
+ caretPieces = container.children;
221869
+ }
221870
+ caretPieces = caretPieces.filter((piece) => piece.kind !== "container" || piece.policy === "fail-closed");
221871
+ }
221872
+ const carrier = adjacentFormattingCarrierRun(sourceXml, "before", inheritedNamespaceBindings, charOffset, undefined, collapsedInlineAffinity, collapsedObjectBoundary, caretPieces);
221873
+ if (!carrier.ok)
221874
+ return carrier;
221875
+ source = carrier.run;
221876
+ properties2 = source ? readRunPropertiesXml(source.xml) : null;
221877
+ }
221878
+ if (!source || !properties2)
221879
+ return { ok: true, runPropertiesXml: null };
221880
+ const node2 = readXmlNodeAt(properties2, 0);
221881
+ if (!node2 || node2.kind !== "element")
221882
+ return { ok: false, reason: "unsupported-context" };
221883
+ if (node2.selfClosing)
221884
+ return { ok: true, runPropertiesXml: null };
221885
+ const namespaces = namespaceSourceForRunProperties(sourceXml, source, properties2, inheritedNamespaceBindings);
221886
+ if (!namespaces || runPropertiesContainForeignRevisionLikeElement(properties2, namespaces.openTag) !== false) {
221887
+ return { ok: false, reason: "unsupported-context" };
221888
+ }
221889
+ const liveProperties = normalizeClonedRunProperties(properties2);
221890
+ return { ok: true, runPropertiesXml: liveProperties ? namespaces.openTag + liveProperties.slice(node2.openEnd) : null };
221891
+ }
221892
+ function adjacentFormattingCarrierRun(paragraphXml, placement2, inheritedNamespaceBindings = {}, charOffset, replaceToOffset, collapsedInlineAffinity, collapsedObjectBoundary, resolvedPieces) {
221789
221893
  const paragraphPrefix = /^<(?:(?<prefix>[\w.-]+):)?p\b/.exec(paragraphXml)?.groups?.prefix ?? "";
221790
221894
  const additionalNamespaces = xmlFragmentAdditionalNamespaces(paragraphXml, new Map(Object.entries(inheritedNamespaceBindings)), { w: NS_W, [paragraphPrefix]: NS_W });
221791
221895
  const parsed = collectXmlElementRanges(paragraphXml, { additionalNamespaces });
221792
221896
  if (parsed.errors.length > 0)
221793
221897
  return { ok: true, run: undefined };
221794
- const pieces = parseParagraphInlineMap(paragraphXml, inheritedNamespaceBindings).pieces;
221898
+ const pieces = resolvedPieces ?? parseParagraphInlineMap(paragraphXml, inheritedNamespaceBindings).pieces;
221795
221899
  const downstream = charOffset !== undefined && (replaceToOffset ?? charOffset) === charOffset && collapsedInlineAffinity === "downstream" ? findDownstreamVisibleCarrierAfterHiddenRun(paragraphXml, pieces, charOffset, inheritedNamespaceBindings) : null;
221796
221900
  const carrier = collapsedObjectBoundary && charOffset !== undefined ? { ok: true, piece: visibleTextBesideObjectAt(pieces, charOffset, collapsedObjectBoundary) ?? undefined } : downstream ? { ok: true, piece: downstream } : charOffset === undefined ? adjacentFormattingCarrierPiece(pieces, placement2) : formattingCarrierPieceAtOffset(pieces, charOffset, replaceToOffset);
221797
221901
  if (!carrier.ok)
@@ -281316,6 +281420,74 @@ function getSDDocumentSessionInternalMainRelationshipsPartUri(session) {
281316
281420
  throw new Error("internal: unknown SDDocumentSession instance");
281317
281421
  return internal.state.mainStoryId ? relsUriFor(storyPartUriFromStoryId(internal.state.mainStoryId)) : null;
281318
281422
  }
281423
+ function readSDDocumentSessionInternalParagraphNamespaceScope(session, storyId, blockId, storyByteRange) {
281424
+ const internal = INTERNALS.get(session);
281425
+ if (!internal)
281426
+ throw new Error("internal: unknown SDDocumentSession instance");
281427
+ const state = internal.state;
281428
+ const index = getStoryParagraphIndexFromState(state, storyId);
281429
+ const candidates = storyByteRange ? index?.entries.filter((entry2) => entry2.blockId === blockId && entry2.byteStart >= storyByteRange[0] && entry2.byteEnd <= storyByteRange[1]) : null;
281430
+ const entry = candidates ? candidates.length === 1 ? candidates[0] : null : index?.byParaId(blockId);
281431
+ if (!entry || !storyByteRange && index.duplicateParaIds.has(blockId))
281432
+ return null;
281433
+ const canonical = !storyByteRange ? peekSDCanonicalResidentParagraph(state, storyId, blockId) : null;
281434
+ if (canonical)
281435
+ return canonical.scope;
281436
+ const ownership = storyId === state.mainStoryId ? readResidentParagraphOwnership(state, blockId) : null;
281437
+ let scope = ownership ? Object.freeze({
281438
+ namespaceBindings: ownership.namespaceBindings,
281439
+ parentNamespaceBindings: ownership.parentNamespaceBindings
281440
+ }) : storyId === state.mainStoryId ? readResidentParagraphNamespaceScope(state, blockId) : null;
281441
+ if (!ownership && entry.hasNonEditableBlockSdtContent && storyId === state.mainStoryId) {
281442
+ const namespaces = readResidentParagraphNamespaces(state, blockId);
281443
+ if (namespaces) {
281444
+ return { namespaceBindings: namespaces, parentNamespaceBindings: namespaces };
281445
+ }
281446
+ }
281447
+ let cached2 = state.paragraphNamespaceCache.get(entry.partUri);
281448
+ if (cached2?.revision !== entry.partRevision) {
281449
+ cached2 = { revision: entry.partRevision, bindingsByByteStart: new Map };
281450
+ state.paragraphNamespaceCache.set(entry.partUri, cached2);
281451
+ }
281452
+ scope ?? (scope = cached2.bindingsByByteStart.get(entry.byteStart) ?? null);
281453
+ if (!scope) {
281454
+ const prefix2 = readPartRangeFromStateSync(state, entry.partUri, 0, entry.byteEnd);
281455
+ if (!prefix2)
281456
+ return null;
281457
+ const xml = new TextDecoder().decode(prefix2);
281458
+ const expectedStart = new TextDecoder().decode(prefix2.subarray(0, entry.byteStart)).length;
281459
+ const parser = createXmlSaxParser({ namespaceAware: true, position: true });
281460
+ const namespaceStack = [CANONICAL_XML_EMPTY_NAMESPACE_BINDINGS];
281461
+ let malformed2 = false;
281462
+ parser.on("error", () => {
281463
+ malformed2 = true;
281464
+ });
281465
+ parser.on("opentag", (tag) => {
281466
+ const parentNamespaceBindings = namespaceStack[namespaceStack.length - 1];
281467
+ const namespaceBindings = Object.keys(tag.namespaceBindings).length > 0 ? { ...parentNamespaceBindings, ...tag.namespaceBindings } : parentNamespaceBindings;
281468
+ namespaceStack.push(namespaceBindings);
281469
+ if (scope || malformed2 || tag.localName !== "p" || tag.namespaceUri !== NS_W)
281470
+ return;
281471
+ const charStart = xml.lastIndexOf("<", parser.position - 1);
281472
+ if (charStart === expectedStart)
281473
+ scope = Object.freeze({
281474
+ namespaceBindings: createCanonicalXmlNamespaceBindings(Object.entries(namespaceBindings)),
281475
+ parentNamespaceBindings: createCanonicalXmlNamespaceBindings(Object.entries(parentNamespaceBindings))
281476
+ });
281477
+ });
281478
+ parser.on("closetag", () => {
281479
+ if (namespaceStack.length > 1)
281480
+ namespaceStack.pop();
281481
+ });
281482
+ parser.write(xml);
281483
+ if (!scope)
281484
+ return null;
281485
+ if (cached2.bindingsByByteStart.size >= 2048)
281486
+ cached2.bindingsByByteStart.clear();
281487
+ cached2.bindingsByByteStart.set(entry.byteStart, scope);
281488
+ }
281489
+ return scope;
281490
+ }
281319
281491
  function getSDDocumentSessionInternalResidentMainStructureIdentity(session) {
281320
281492
  const internal = INTERNALS.get(session);
281321
281493
  if (!internal)
@@ -283006,6 +283178,7 @@ function applySDDocumentSessionInternalPatchGroup(session, input) {
283006
283178
  internal.onMutationCommitted();
283007
283179
  return receipt3;
283008
283180
  }
283181
+ const historyOwner = input.history ? captureHistoryTextOwner(internal.state, input.forwardPatchGroup) : null;
283009
283182
  const applyResult = applyPatchGroupAtomic(internal.state, input.forwardPatchGroup);
283010
283183
  if (applyResult.status !== "committed") {
283011
283184
  return {
@@ -283027,6 +283200,7 @@ function applySDDocumentSessionInternalPatchGroup(session, input) {
283027
283200
  forwardPatchGroup: applyResult.forwardPatchGroup,
283028
283201
  inversePatchGroup: applyResult.inversePatchGroup,
283029
283202
  semanticDelta: input.history.semanticDelta,
283203
+ textReplayOwner: sealHistoryTextOwner(internal.state, historyOwner, applyResult.inversePatchGroup),
283030
283204
  revisionDeltas: {
283031
283205
  package: {
283032
283206
  previous: applyResult.previousPackageRevision,
@@ -283259,10 +283433,11 @@ function prepareSDDocumentSessionInternalAtomicReview(session, compile) {
283259
283433
  const retiredEntries = [...initialHistory].filter((id) => !state.history.entries.has(id)).map((id) => internal.state.history.entries.get(id)).filter((entry) => !!entry);
283260
283434
  if (entries2.length === 0 && retiredEntries.length === 0)
283261
283435
  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);
283436
+ const capturedEntries = [...retiredEntries, ...entries2];
283437
+ const touched = collectCapturedTouchedParts(capturedEntries);
283438
+ const finalParts = snapshotCapturedParts(staging, touched, capturedEntries, "after");
283439
+ const originals = snapshotCapturedParts(session, touched, capturedEntries, "before");
283440
+ const group = buildCapturedCompositeForwardPatchGroup(session, capturedEntries, originals, finalParts);
283266
283441
  if (Object.keys(group.perPart).length === 0)
283267
283442
  return { value, prepared: null };
283268
283443
  const storyIds = group.storiesTouched;
@@ -283332,11 +283507,15 @@ function composeSDDocumentSessionInternalCapturedHistory(session, input) {
283332
283507
  return null;
283333
283508
  const entries2 = requireCapturedHistoryEntries(session, input.txIds);
283334
283509
  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);
283510
+ let finalParts;
283511
+ try {
283512
+ finalParts = snapshotCapturedParts(session, touchedParts, entries2, "after");
283513
+ } finally {
283514
+ rollbackCapturedHistoryEntries(session, entries2);
283515
+ for (const txId of input.txIds)
283516
+ deleteSDDocumentSessionInternalHistoryEntry(session, txId);
283517
+ }
283518
+ const originalParts = snapshotCapturedParts(session, touchedParts, entries2, "before");
283340
283519
  const forwardPatchGroup = buildCapturedCompositeForwardPatchGroup(session, entries2, originalParts, finalParts);
283341
283520
  const internal = INTERNALS.get(session);
283342
283521
  const hasSessionChanges = composeSessionHyperlinkHistory(internal.state, entries2.map((entry) => entry.forwardPatchGroup), forwardPatchGroup);
@@ -283380,17 +283559,63 @@ function collectCapturedTouchedParts(entries2) {
283380
283559
  }
283381
283560
  return [...parts];
283382
283561
  }
283383
- function snapshotCapturedParts(session, partUris) {
283562
+ function snapshotCapturedParts(session, partUris, entries2, phase) {
283384
283563
  const snapshots = new Map;
283385
283564
  for (const uri of partUris) {
283386
283565
  const bytes = getSDDocumentSessionInternalPartBytes(session, uri);
283566
+ const descriptor = getSDDocumentSessionInternalPartDescriptor(session, uri);
283567
+ if (!bytes && descriptor) {
283568
+ const paragraph = capturedSourceParagraphWindow(entries2, uri, phase);
283569
+ if (!paragraph)
283570
+ throw new Error("Captured source history requires a bounded paragraph.");
283571
+ const index = getStoryParagraphIndexFromState(INTERNALS.get(session).state, paragraph.storyId);
283572
+ const current = index?.byParaId(paragraph.blockId);
283573
+ if (!current || index.duplicateParaIds.has(paragraph.blockId) || current.partUri !== uri || current.byteStart !== paragraph.startByte || current.byteEnd !== paragraph.endByte) {
283574
+ throw new Error("Captured source history requires a current bounded paragraph.");
283575
+ }
283576
+ const range = getSDDocumentSessionInternalPartRange(session, uri, paragraph.startByte, paragraph.endByte);
283577
+ if (!range)
283578
+ throw new Error("Captured source history requires readable bounded paragraph bytes.");
283579
+ snapshots.set(uri, { bytes: range.slice(), contentType: descriptor.contentType, paragraph });
283580
+ continue;
283581
+ }
283387
283582
  snapshots.set(uri, {
283388
283583
  bytes: bytes ? new Uint8Array(bytes) : null,
283389
- contentType: getSDDocumentSessionInternalPartDescriptor(session, uri)?.contentType ?? null
283584
+ contentType: descriptor?.contentType ?? null
283390
283585
  });
283391
283586
  }
283392
283587
  return snapshots;
283393
283588
  }
283589
+ function capturedSourceParagraphWindow(entries2, partUri, phase) {
283590
+ const touching = entries2.filter((entry) => entry.forwardPatchGroup.perPart[partUri]);
283591
+ const stories = uniqueCaptured(touching.flatMap((entry) => entry.forwardPatchGroup.storiesTouched));
283592
+ const first = touching[0]?.forwardPatchGroup.indexRefreshScope?.perPart[partUri];
283593
+ if (stories.length !== 1 || first?.kind !== "paragraph" || first.blockIds?.length !== 1)
283594
+ return null;
283595
+ const blockId = first.blockIds[0];
283596
+ let window2 = first.beforeWindow;
283597
+ for (const entry of touching) {
283598
+ const forward = entry.forwardPatchGroup;
283599
+ const inverse2 = entry.inversePatchGroup;
283600
+ const before = forward.indexRefreshScope?.perPart[partUri];
283601
+ const after = inverse2.indexRefreshScope?.perPart[partUri];
283602
+ for (const [group, scope] of [[forward, before], [inverse2, after]]) {
283603
+ const part2 = group.perPart[partUri];
283604
+ 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))
283605
+ return null;
283606
+ }
283607
+ if (before.beforeWindow.startByte !== window2.startByte || before.beforeWindow.endByte !== window2.endByte)
283608
+ return null;
283609
+ const part = forward.perPart[partUri];
283610
+ if (part.kind !== "modify")
283611
+ return null;
283612
+ const delta = part.patches.reduce((sum, patch) => sum + (patch.kind === "deleteBytes" ? 0 : patch.bytes.length) - (patch.kind === "insertBytes" ? 0 : patch.endByte - patch.startByte), 0);
283613
+ if (after.beforeWindow.startByte !== window2.startByte || after.beforeWindow.endByte !== window2.endByte + delta)
283614
+ return null;
283615
+ window2 = after.beforeWindow;
283616
+ }
283617
+ return { storyId: stories[0], blockId, ...phase === "before" ? first.beforeWindow : window2 };
283618
+ }
283394
283619
  function rollbackCapturedHistoryEntries(session, entries2) {
283395
283620
  const receipts = [];
283396
283621
  for (let index = entries2.length - 1;index >= 0; index -= 1) {
@@ -283411,6 +283636,7 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283411
283636
  const preconditions = [];
283412
283637
  const patchMaps = {};
283413
283638
  const perPartBaseRevision = {};
283639
+ const paragraphScopes = {};
283414
283640
  const touchedParts = new Set([...originalParts.keys(), ...finalParts.keys()]);
283415
283641
  for (const partUri of touchedParts) {
283416
283642
  const original = originalParts.get(partUri) ?? {
@@ -283418,12 +283644,32 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283418
283644
  contentType: null
283419
283645
  };
283420
283646
  const final = finalParts.get(partUri) ?? { bytes: null, contentType: null };
283421
- if (original.bytes && final.bytes) {
283647
+ if (original.paragraph || final.paragraph) {
283648
+ if (!original.bytes || !final.bytes || !original.paragraph || !final.paragraph || original.paragraph.blockId !== final.paragraph.blockId || original.paragraph.startByte !== final.paragraph.startByte) {
283649
+ throw new Error("Captured source history requires matching bounded paragraph snapshots.");
283650
+ }
283651
+ if (capturedBytesEqual(original.bytes, final.bytes))
283652
+ continue;
283653
+ const { startByte, endByte, blockId } = original.paragraph;
283654
+ perPart[partUri] = { kind: "modify", patches: [
283655
+ { kind: "replaceBytes", order: 0, startByte, endByte, bytes: final.bytes }
283656
+ ] };
283657
+ paragraphScopes[partUri] = { kind: "paragraph", beforeWindow: { startByte, endByte }, blockIds: [blockId] };
283658
+ preconditions.push({
283659
+ kind: "byteWindow",
283660
+ partUri,
283661
+ startByte,
283662
+ endByte,
283663
+ algorithm: "sha256",
283664
+ hash: sha256HexSync(original.bytes)
283665
+ });
283666
+ } else if (original.bytes && final.bytes) {
283422
283667
  if (capturedBytesEqual(original.bytes, final.bytes))
283423
283668
  continue;
283669
+ const paragraph = capturedParagraphComposite(entries2, partUri, original.bytes, final.bytes);
283424
283670
  perPart[partUri] = {
283425
283671
  kind: "modify",
283426
- patches: [
283672
+ patches: paragraph ? [paragraph.patch] : [
283427
283673
  {
283428
283674
  kind: "replaceBytes",
283429
283675
  order: 0,
@@ -283433,7 +283679,13 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283433
283679
  }
283434
283680
  ]
283435
283681
  };
283436
- preconditions.push(capturedByteWindowPrecondition(partUri, original.bytes));
283682
+ if (paragraph)
283683
+ paragraphScopes[partUri] = paragraph.scope;
283684
+ preconditions.push(paragraph ? buildLocalizedByteWindowPrecondition({
283685
+ partUri,
283686
+ bytes: original.bytes,
283687
+ patches: [paragraph.patch]
283688
+ }) : capturedByteWindowPrecondition(partUri, original.bytes));
283437
283689
  } else if (!original.bytes && final.bytes) {
283438
283690
  perPart[partUri] = {
283439
283691
  kind: "create",
@@ -283465,7 +283717,28 @@ function buildCapturedCompositeForwardPatchGroup(session, entries2, originalPart
283465
283717
  perPart,
283466
283718
  patchMaps,
283467
283719
  storiesTouched: uniqueCaptured(entries2.flatMap((entry) => entry.forwardPatchGroup.storiesTouched)),
283468
- signalLanesToRebuild: uniqueCaptured(entries2.flatMap((entry) => entry.forwardPatchGroup.signalLanesToRebuild))
283720
+ signalLanesToRebuild: uniqueCaptured(entries2.flatMap((entry) => entry.forwardPatchGroup.signalLanesToRebuild)),
283721
+ ...Object.keys(paragraphScopes).length > 0 ? { indexRefreshScope: { perPart: paragraphScopes } } : {}
283722
+ };
283723
+ }
283724
+ function capturedParagraphComposite(entries2, partUri, original, final) {
283725
+ const touching = entries2.filter((entry) => entry.forwardPatchGroup.perPart[partUri]);
283726
+ const first = touching[0]?.forwardPatchGroup.indexRefreshScope?.perPart[partUri];
283727
+ if (!first || first.kind !== "paragraph" || first.blockIds?.length !== 1)
283728
+ return null;
283729
+ const blockId = first.blockIds[0];
283730
+ if (touching.some((entry) => {
283731
+ const scope = entry.forwardPatchGroup.indexRefreshScope?.perPart[partUri];
283732
+ 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;
283733
+ }))
283734
+ return null;
283735
+ const { startByte, endByte } = first.beforeWindow;
283736
+ const finalEndByte = endByte + final.length - original.length;
283737
+ 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)))
283738
+ return null;
283739
+ return {
283740
+ patch: { kind: "replaceBytes", order: 0, startByte, endByte, bytes: final.subarray(startByte, finalEndByte) },
283741
+ scope: { kind: "paragraph", beforeWindow: { startByte, endByte }, blockIds: [blockId] }
283469
283742
  };
283470
283743
  }
283471
283744
  function invertCapturedSemanticDelta(delta) {
@@ -286145,6 +286418,7 @@ var init_sd_document_session = __esm(() => {
286145
286418
  init_hyperlink_catalog();
286146
286419
  init_field_catalog();
286147
286420
  init_remote_paragraph_publication();
286421
+ init_xml_sax();
286148
286422
  init_revision_id_export();
286149
286423
  init_resident_review();
286150
286424
  init_canonical_xml_analysis_frame();
@@ -286161,6 +286435,7 @@ var init_sd_document_session = __esm(() => {
286161
286435
  init_section_margin_update();
286162
286436
  init_session_hyperlink_metadata();
286163
286437
  init_history_text_replay();
286438
+ init_patch_substrate();
286164
286439
  init_history_part_rewrite();
286165
286440
  init_v2_open();
286166
286441
  init_package_open();
@@ -287568,6 +287843,7 @@ var init_sd_document_session_internal = __esm(() => {
287568
287843
  init_paragraph_inline_model();
287569
287844
  init_simple_text_run_split();
287570
287845
  init_compile_edit_text_inline_plan();
287846
+ init_insertion_formatting_context();
287571
287847
  init_compile_edit_text();
287572
287848
  init_tracked_inline_replacement();
287573
287849
  init_tracked_paragraph_content();
@@ -287828,9 +288104,21 @@ var init_address2 = __esm(() => {
287828
288104
  // ../../packages/document-api/src/types/track-changes.types.ts
287829
288105
  var TRACK_CHANGES_IN_ALL = "all";
287830
288106
 
288107
+ // ../../packages/document-api/src/inline-semantics/property-ids.ts
288108
+ var CORE_PROPERTY_IDS, CORE_PROPERTY_ID_SET, CORE_TOGGLE_PROPERTY_IDS, CORE_TOGGLE_PROPERTY_ID_SET;
288109
+ var init_property_ids = __esm(() => {
288110
+ CORE_PROPERTY_IDS = ["bold", "italic", "underline", "strike"];
288111
+ CORE_PROPERTY_ID_SET = new Set(CORE_PROPERTY_IDS);
288112
+ CORE_TOGGLE_PROPERTY_IDS = ["bold", "italic", "strike"];
288113
+ CORE_TOGGLE_PROPERTY_ID_SET = new Set(CORE_TOGGLE_PROPERTY_IDS);
288114
+ });
288115
+
287831
288116
  // ../../packages/document-api/src/types/style-policy.types.ts
287832
- var INLINE_DIRECTIVES2, INLINE_DIRECTIVE_SET2;
288117
+ var MARK_KEYS, MARK_KEY_SET, INLINE_DIRECTIVES2, INLINE_DIRECTIVE_SET2;
287833
288118
  var init_style_policy_types2 = __esm(() => {
288119
+ init_property_ids();
288120
+ MARK_KEYS = CORE_PROPERTY_IDS;
288121
+ MARK_KEY_SET = CORE_PROPERTY_ID_SET;
287834
288122
  INLINE_DIRECTIVES2 = ["on", "off", "clear"];
287835
288123
  INLINE_DIRECTIVE_SET2 = new Set(INLINE_DIRECTIVES2);
287836
288124
  });
@@ -288326,7 +288614,7 @@ function buildInlineRunPatchSchema2() {
288326
288614
  minProperties: 1
288327
288615
  };
288328
288616
  }
288329
- var schemaBooleanOrNull2 = () => ({
288617
+ var CLEAR_INLINE_FORMATTING_KEYS2, schemaBooleanOrNull2 = () => ({
288330
288618
  oneOf: [{ type: "boolean" }, { type: "null" }]
288331
288619
  }), schemaStringOrNull2 = () => ({
288332
288620
  oneOf: [{ type: "string", minLength: 1 }, { type: "null" }]
@@ -288380,6 +288668,21 @@ var schemaBooleanOrNull2 = () => ({
288380
288668
  }), 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
288669
  var init_inline_run_patch2 = __esm(() => {
288382
288670
  init_errors6();
288671
+ CLEAR_INLINE_FORMATTING_KEYS2 = Object.freeze([
288672
+ "bold",
288673
+ "italic",
288674
+ "underline",
288675
+ "strike",
288676
+ "color",
288677
+ "highlight",
288678
+ "fontFamily",
288679
+ "fontSize",
288680
+ "vertAlign",
288681
+ "smallCaps",
288682
+ "caps",
288683
+ "letterSpacing",
288684
+ "dstrike"
288685
+ ]);
288383
288686
  UNDERLINE_OBJECT_SCHEMA2 = {
288384
288687
  type: "object",
288385
288688
  properties: {
@@ -372200,8 +372503,13 @@ async function readAttempt(context, input, readState) {
372200
372503
  const paragraph3 = first ? await loadParagraph(context, first, model, resolveTableInfo, readState, collapsed ? input.pendingInline : undefined) : null;
372201
372504
  if (!paragraph3)
372202
372505
  recordAll("source-unavailable");
372203
- else
372204
- record3(paragraph3.runAtCaret(first.startOffset));
372506
+ else {
372507
+ const run = paragraph3.runAtCaret(first.startOffset);
372508
+ if (run)
372509
+ record3(run);
372510
+ else
372511
+ recordAll("unsupported-context");
372512
+ }
372205
372513
  }
372206
372514
  const properties2 = {};
372207
372515
  for (const key3 of input.keys) {
@@ -372232,8 +372540,7 @@ async function loadParagraph(context, range, model, resolveTableInfo, readState,
372232
372540
  const paragraphMarkFormatsBreakRuns = leaves.length > 0 && leaves.every((leaf) => leaf.kind === "control" && leaf.control !== "tab");
372233
372541
  const paragraphMarkRPrXml = extractParagraphMarkRPrXml2(paragraphXml);
372234
372542
  const readRun = (runPropertiesXml) => {
372235
- const inheritsMark = runPropertiesXml == null && paragraphMarkFormatsBreakRuns;
372236
- let sourceXml = inheritsMark ? paragraphMarkRPrXml : runPropertiesXml;
372543
+ let sourceXml = runPropertiesXml;
372237
372544
  if (pendingInline) {
372238
372545
  const patched = applyInlinePatchToRPr2(sourceXml ?? "", pendingInline);
372239
372546
  if (patched.ok)
@@ -372250,7 +372557,6 @@ async function loadParagraph(context, range, model, resolveTableInfo, readState,
372250
372557
  })
372251
372558
  };
372252
372559
  };
372253
- const paragraphMarkRun = () => readRun(paragraphMarkRPrXml);
372254
372560
  return {
372255
372561
  runsInRange(start, end) {
372256
372562
  const seen = new Set;
@@ -372261,18 +372567,16 @@ async function loadParagraph(context, range, model, resolveTableInfo, readState,
372261
372567
  if (seen.has(leaf.runCharStart))
372262
372568
  continue;
372263
372569
  seen.add(leaf.runCharStart);
372264
- runs.push(readRun(leaf.runProperties));
372570
+ runs.push(readRun(leaf.runProperties ?? (paragraphMarkFormatsBreakRuns ? paragraphMarkRPrXml : null)));
372265
372571
  }
372266
372572
  return runs;
372267
372573
  },
372268
372574
  runAtCaret(offset) {
372269
- let before;
372270
- for (const leaf of leaves) {
372271
- if (leaf.visibleStart < offset && leaf.visibleEnd >= offset)
372272
- before = leaf;
372273
- }
372274
- const chosen = before ?? leaves.find((leaf) => leaf.visibleStart >= offset && leaf.visibleEnd > leaf.visibleStart);
372275
- return chosen ? readRun(chosen.runProperties) : paragraphMarkRun();
372575
+ const scope = readSDDocumentSessionInternalParagraphNamespaceScope(context.session, range.storyId, range.startBlockId);
372576
+ if (!scope)
372577
+ return null;
372578
+ const carrier = readCaretRunProperties(paragraphXml, offset, scope.namespaceBindings, range.collapsedInlineAffinity, range.collapsedObjectBoundary);
372579
+ return carrier.ok ? readRun(carrier.runPropertiesXml) : null;
372276
372580
  }
372277
372581
  };
372278
372582
  }
@@ -412654,7 +412958,7 @@ function isSupportedMutationPlanStepOp(op) {
412654
412958
  var MUTATION_PLAN_ENGINE_SUPPORT, MUTATION_PLAN_SUPPORTED_STEP_OPS, MUTATION_PLAN_MUTATING_STEP_OPS;
412655
412959
  var init_support_contract = __esm(() => {
412656
412960
  MUTATION_PLAN_ENGINE_SUPPORT = Object.freeze({
412657
- version: "4",
412961
+ version: "5",
412658
412962
  supportedStepOps: Object.freeze([
412659
412963
  "text.rewrite",
412660
412964
  "text.delete",
@@ -412687,6 +412991,9 @@ var init_support_contract = __esm(() => {
412687
412991
  ]),
412688
412992
  unsupported: Object.freeze([
412689
412993
  { cell: "text.rewrite:args.style:custom-policy", reason: "only-native-preserve-style-policy-supported" },
412994
+ { cell: "text.insert.args.style:after-tracked-format-boundary", reason: "projected-insertion-carrier-formatting-not-supported" },
412995
+ { cell: "text.insert.args.style:tracked-formatting-carrier", reason: "direct-inserted-text-formatting-cannot-rewrite-rpr-change" },
412996
+ { cell: "text.insert.args.style:tracked-coordinate-space", reason: "style-patch-requires-visible-inserted-text-selection" },
412690
412997
  { cell: "structural.insert", reason: "structural-slice-not-yet-proven" },
412691
412998
  { cell: "structural.replace:non-block-rich-text-sdt", reason: "only-paragraph-content-block-sdt-replacement-proven" },
412692
412999
  { cell: "structural.replace:tracked", reason: "structural-sdt-replacement-direct-only" },
@@ -427897,7 +428204,7 @@ var init_adapter24 = __esm(() => {
427897
428204
  init_adapter23();
427898
428205
  V2_SUPPORTED_STEP_OPS = MUTATION_PLAN_SUPPORTED_STEP_OPS;
427899
428206
  V2_SUPPORTED_NON_UNIFORM_STRATEGIES = Object.freeze([]);
427900
- V2_SUPPORTED_SET_MARKS = Object.freeze([]);
428207
+ V2_SUPPORTED_SET_MARKS = MARK_KEYS;
427901
428208
  V2_REGEX_LIMITS = Object.freeze({
427902
428209
  maxPatternLength: SD_TEXT_SEARCH_MAX_REGEX_PATTERN_LENGTH,
427903
428210
  maxExecutionMs: 100
@@ -442935,7 +443242,7 @@ async function compilePlan(context, input) {
442935
443242
  throw error48;
442936
443243
  }
442937
443244
  }
442938
- detectTargetConflicts(context, steps, failures);
443245
+ detectTargetConflicts(context, steps, failures, changeMode);
442939
443246
  detectUnsupportedRuntimeDrift(input.steps, failures);
442940
443247
  const exactProgram = failures.length === 0 ? compileDescendingExactTargets(context, steps) : undefined;
442941
443248
  if (exactProgram) {
@@ -443505,17 +443812,30 @@ function detectUnsupportedRuntimeDrift(steps, failures) {
443505
443812
  }
443506
443813
  }
443507
443814
  }
443508
- function detectTargetConflicts(context, steps, failures) {
443815
+ function detectTargetConflicts(context, steps, failures, changeMode) {
443509
443816
  const claimedByKey = new Map;
443510
443817
  const conflicted = new Set;
443511
443818
  for (const step3 of steps) {
443512
443819
  const resolutions = step3.resolutions ?? (step3.resolution ? [step3.resolution] : []);
443820
+ const requests = step3.requests ?? (step3.request ? [step3.request] : []);
443513
443821
  const currentClaims = [];
443514
- for (const resolution of resolutions) {
443822
+ for (const [index2, resolution] of resolutions.entries()) {
443515
443823
  const target = resolution.target;
443516
443824
  const key3 = `${storyKeyForTarget(target)}::${target.blockId}`;
443517
443825
  const { from, to } = conflictRangeForResolution(context, step3, resolution);
443826
+ const request = requests[index2];
443827
+ const styledAnchor = request?.kind === "insert" && request.inline && request.text.length > 0 && request.target.start.kind === "text" ? request.target.start.offset : undefined;
443518
443828
  for (const prior of claimedByKey.get(key3) ?? []) {
443829
+ if (prior.trackedInlineFormat && styledAnchor !== undefined && (styledAnchor === prior.to || styledAnchor === 0 && prior.from === 0)) {
443830
+ failures.push({
443831
+ code: "CAPABILITY_UNSUPPORTED",
443832
+ stepId: step3.stepId,
443833
+ phase: "compile",
443834
+ message: "text.insert style changes cannot inherit a carrier formatted by an earlier tracked step."
443835
+ });
443836
+ conflicted.add(step3.stepId);
443837
+ break;
443838
+ }
443519
443839
  if (rangesOverlap12(from, to, prior.from, prior.to)) {
443520
443840
  failures.push({
443521
443841
  code: "PLAN_CONFLICT_OVERLAP",
@@ -443527,11 +443847,17 @@ function detectTargetConflicts(context, steps, failures) {
443527
443847
  break;
443528
443848
  }
443529
443849
  }
443530
- currentClaims.push({ key: key3, from, to, stepId: step3.stepId });
443850
+ currentClaims.push({
443851
+ key: key3,
443852
+ from,
443853
+ to,
443854
+ stepId: step3.stepId,
443855
+ trackedInlineFormat: changeMode === "tracked" && request?.kind === "format" && !!request.inline
443856
+ });
443531
443857
  }
443532
443858
  for (const claim of currentClaims) {
443533
443859
  const prior = claimedByKey.get(claim.key) ?? [];
443534
- prior.push({ from: claim.from, to: claim.to, stepId: claim.stepId });
443860
+ prior.push(claim);
443535
443861
  claimedByKey.set(claim.key, prior);
443536
443862
  }
443537
443863
  }
@@ -443673,7 +443999,7 @@ function resolveTargetWhereMutationStep(context, step3, where, story, changeMode
443673
443999
  }
443674
444000
  const selectionMutation = new V2SelectionMutationAdapter(context);
443675
444001
  if (step3.op === "text.insert") {
443676
- const { text: text4, position: position2 } = readInsertArgs(step3);
444002
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
443677
444003
  const point3 = position2 === "before" ? target.start : target.end;
443678
444004
  const collapsed = {
443679
444005
  kind: "selection",
@@ -443682,8 +444008,9 @@ function resolveTargetWhereMutationStep(context, step3, where, story, changeMode
443682
444008
  ...target.story ? { story: target.story } : {},
443683
444009
  ...target.coordinateSpace ? { coordinateSpace: target.coordinateSpace } : {}
443684
444010
  };
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 });
444011
+ const request = buildInsertCommitRequest(context, collapsed, text4, inline, story);
444012
+ const { inline: _inline, ...dryRunRequest } = request;
444013
+ const receipt3 = selectionMutation.execute(dryRunRequest, { changeMode, dryRun: true });
443687
444014
  if (!receipt3.success)
443688
444015
  throw new DocumentApiValidationError2(receipt3.failure.code, receipt3.failure.message);
443689
444016
  const resolution2 = {
@@ -443837,7 +444164,7 @@ function resolveRefMutationStep(context, step3, story, ref5, changeMode, cache,
443837
444164
  };
443838
444165
  }
443839
444166
  if (step3.op === "text.insert") {
443840
- const { text: text4, position: position2 } = readInsertArgs(step3);
444167
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
443841
444168
  const offset = position2 === "before" ? outcome.resolved.startOffset : outcome.resolved.endOffset;
443842
444169
  const storyLocator = outcome.storyLocator;
443843
444170
  const point3 = {
@@ -443858,7 +444185,7 @@ function resolveRefMutationStep(context, step3, story, ref5, changeMode, cache,
443858
444185
  op: "text.insert",
443859
444186
  resolution,
443860
444187
  kernelRange: outcome.resolved,
443861
- request: { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} },
444188
+ request: buildInsertCommitRequest(context, collapsed, text4, inline, story),
443862
444189
  noopEquivalentText: text4.length === 0 ? text4 : undefined,
443863
444190
  source: step3
443864
444191
  };
@@ -443971,6 +444298,7 @@ async function resolveAllSelectMutationStep(context, step3, where, story, change
443971
444298
  resolutions: coalescedEntries.map((entry) => entry.resolution),
443972
444299
  requests: coalescedEntries.map((entry) => entry.request),
443973
444300
  kernelRanges: coalescedEntries.flatMap((entry) => entry.kernelRange ? [entry.kernelRange] : []),
444301
+ ...step3.op === "text.insert" ? { noopEquivalentText: resolved[0].noopEquivalentText } : {},
443974
444302
  ...step3.op === "text.rewrite" && step3.args.caseHandling !== "preserve-match" && step3.args.replacementMode !== "regex-template" ? { noopEquivalentText: normalizeReplacement(step3.args.replacement) } : {},
443975
444303
  source: step3
443976
444304
  };
@@ -444043,7 +444371,7 @@ function resolveBlockMutationStep(context, step3, where, story) {
444043
444371
  };
444044
444372
  }
444045
444373
  if (step3.op === "text.insert") {
444046
- const { text: text4, position: position2 } = readInsertArgs(step3);
444374
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
444047
444375
  const offset = position2 === "before" ? 0 : raw.textLength;
444048
444376
  const point3 = {
444049
444377
  kind: "text",
@@ -444071,7 +444399,7 @@ function resolveBlockMutationStep(context, step3, where, story) {
444071
444399
  stepId: step3.id,
444072
444400
  op: "text.insert",
444073
444401
  resolution: collapsedResolution,
444074
- request: { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} },
444402
+ request: buildInsertCommitRequest(context, collapsed, text4, inline, story),
444075
444403
  noopEquivalentText: text4.length === 0 ? text4 : undefined,
444076
444404
  source: step3
444077
444405
  };
@@ -444141,7 +444469,7 @@ function resolveRangeRefMutationStep(context, step3, story, ref5) {
444141
444469
  };
444142
444470
  }
444143
444471
  if (step3.op === "text.insert") {
444144
- const { text: text4, position: position2 } = readInsertArgs(step3);
444472
+ const { text: text4, position: position2, inline } = readInsertArgs(step3);
444145
444473
  const offset = position2 === "before" ? target.range.start : target.range.end;
444146
444474
  const point3 = {
444147
444475
  kind: "text",
@@ -444160,7 +444488,7 @@ function resolveRangeRefMutationStep(context, step3, story, ref5) {
444160
444488
  stepId: step3.id,
444161
444489
  op: "text.insert",
444162
444490
  resolution,
444163
- request: { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} },
444491
+ request: buildInsertCommitRequest(context, collapsed, text4, inline, story),
444164
444492
  noopEquivalentText: text4.length === 0 ? text4 : undefined,
444165
444493
  source: step3
444166
444494
  };
@@ -444362,12 +444690,36 @@ function commitRequest(selectionMutation, paragraphs2, controls, request, change
444362
444690
  };
444363
444691
  }
444364
444692
  if (request.kind === "insert") {
444365
- return selectionMutation.execute({
444693
+ const receipt3 = selectionMutation.execute({
444366
444694
  kind: "replace",
444367
444695
  target: request.target,
444368
444696
  text: request.text,
444369
444697
  ...request.in ? { in: request.in } : {}
444370
444698
  }, { changeMode });
444699
+ if (!receipt3.success || !request.inline)
444700
+ return receipt3;
444701
+ const insertedText = receipt3.effects?.insertedText;
444702
+ if (!insertedText?.length || insertedText.some((effect) => !effect.selectionTarget)) {
444703
+ return {
444704
+ success: false,
444705
+ failure: {
444706
+ code: "CAPABILITY_UNSUPPORTED",
444707
+ message: "text.insert style requires an exact inserted-text selection."
444708
+ },
444709
+ resolution: receipt3.resolution
444710
+ };
444711
+ }
444712
+ for (const effect of insertedText) {
444713
+ const formatted = selectionMutation.execute({
444714
+ kind: "format",
444715
+ target: effect.selectionTarget,
444716
+ inline: request.inline,
444717
+ ...request.in ? { in: request.in } : {}
444718
+ }, { changeMode: "direct" });
444719
+ if (!formatted.success && formatted.failure.code !== "NO_OP")
444720
+ return formatted;
444721
+ }
444722
+ return receipt3;
444371
444723
  }
444372
444724
  if ("target" in request) {
444373
444725
  return selectionMutation.execute({
@@ -444534,14 +444886,64 @@ function readInsertArgs(step3) {
444534
444886
  if (position2 !== "before" && position2 !== "after") {
444535
444887
  throw new DocumentApiValidationError2("INVALID_INPUT", 'text.insert requires args.position to be "before" or "after".');
444536
444888
  }
444537
- if (step3.args?.style !== undefined) {
444538
- throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "v2 text.insert plan steps do not yet support args.style.");
444539
- }
444889
+ const inline = readInsertInlinePatch(step3.args?.style);
444540
444890
  const text4 = step3.args?.content?.text;
444541
444891
  if (typeof text4 !== "string") {
444542
444892
  throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert requires args.content.text.");
444543
444893
  }
444544
- return { text: text4, position: position2 };
444894
+ return { text: text4, position: position2, inline };
444895
+ }
444896
+ function readInsertInlinePatch(style) {
444897
+ if (style === undefined)
444898
+ return;
444899
+ if (!style || typeof style !== "object" || Array.isArray(style) || Object.keys(style).some((key3) => key3 !== "inline")) {
444900
+ throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert args.style requires an inline policy.");
444901
+ }
444902
+ const inline = style.inline;
444903
+ if (!inline || typeof inline !== "object" || Array.isArray(inline) || Object.keys(inline).some((key3) => key3 !== "mode" && key3 !== "setMarks")) {
444904
+ throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert args.style.inline requires mode and optional setMarks.");
444905
+ }
444906
+ const { mode, setMarks } = inline;
444907
+ if (mode !== "inherit" && mode !== "set" && mode !== "clear") {
444908
+ throw new DocumentApiValidationError2("INVALID_INPUT", 'text.insert args.style.inline.mode must be "inherit", "set", or "clear".');
444909
+ }
444910
+ const patch = mode === "clear" ? Object.fromEntries(CLEAR_INLINE_FORMATTING_KEYS2.map((key3) => [key3, null])) : {};
444911
+ if (setMarks !== undefined) {
444912
+ if (!setMarks || typeof setMarks !== "object" || Array.isArray(setMarks)) {
444913
+ throw new DocumentApiValidationError2("INVALID_INPUT", "text.insert args.style.inline.setMarks must be an object.");
444914
+ }
444915
+ for (const [key3, directive] of Object.entries(setMarks)) {
444916
+ if (!MARK_KEY_SET.has(key3) || typeof directive !== "string" || !INLINE_DIRECTIVE_SET2.has(directive)) {
444917
+ throw new DocumentApiValidationError2("INVALID_INPUT", `Invalid text.insert setMarks directive for "${key3}".`);
444918
+ }
444919
+ patch[key3] = directive === "on" ? true : directive === "off" ? false : null;
444920
+ }
444921
+ }
444922
+ return Object.keys(patch).length > 0 ? patch : undefined;
444923
+ }
444924
+ function buildInsertCommitRequest(context, target, text4, inline, story) {
444925
+ if (text4.length > 0 && inline && target.coordinateSpace === "tracked") {
444926
+ throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "text.insert style changes require visible coordinates for an exact inserted-text selection.");
444927
+ }
444928
+ if (text4.length > 0 && inline && target.start.kind === "text") {
444929
+ const index2 = paragraphIndexForRangeRef(context, target.story ?? story);
444930
+ const entry = index2.byParaId(target.start.blockId);
444931
+ const bytes = entry && getSDDocumentSessionInternalPartRange(context.session, entry.partUri, entry.byteStart, entry.byteEnd);
444932
+ if (!bytes) {
444933
+ throw new DocumentApiValidationError2("PRECONDITION_FAILED", "Insertion carrier bytes are unavailable.");
444934
+ }
444935
+ const paragraphXml = TD133.decode(bytes);
444936
+ if (/<(?:[\w.-]+:)?rPrChange\b/.test(paragraphXml)) {
444937
+ const namespaces = getSDDocumentSessionInternalMainStoryRootNamespaceBindings(context.session) ?? {};
444938
+ const at = target.start.offset;
444939
+ const planned = planDirectInlineEdit(bytes, at, at, text4, undefined, undefined, namespaces);
444940
+ 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 ?? ""] : []);
444941
+ if (properties2.some((value3) => /<(?:[\w.-]+:)?rPrChange\b/.test(value3))) {
444942
+ throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "text.insert style changes do not support insertion carriers with tracked formatting changes.");
444943
+ }
444944
+ }
444945
+ }
444946
+ return { kind: "insert", target, text: text4, ...inline ? { inline } : {}, ...story ? { in: story } : {} };
444545
444947
  }
444546
444948
  function normalizeReplacement(replacement2) {
444547
444949
  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.3",
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.3",
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.3",
33
+ "@superdoc/docx-engine": "0.25.1-next.3",
34
34
  "@superdoc/document-api": "0.1.0-alpha.0",
35
35
  "@types/bun": "^1.3.8",
36
36
  "@types/node": "22.19.2",