@superdoc/mcp 1.0.1-next.6 → 1.0.1-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +168 -19
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -31314,7 +31314,7 @@ var init_host = __esm(() => {
|
|
|
31314
31314
|
});
|
|
31315
31315
|
|
|
31316
31316
|
// ../../packages/sdk/langs/node/src/runtime/sdk-version.generated.ts
|
|
31317
|
-
var SDK_VERSION = "2.13.1-next.
|
|
31317
|
+
var SDK_VERSION = "2.13.1-next.8";
|
|
31318
31318
|
|
|
31319
31319
|
// ../../packages/sdk/langs/node/src/runtime/embedded-platform.ts
|
|
31320
31320
|
import { chmodSync, existsSync } from "node:fs";
|
|
@@ -193399,9 +193399,10 @@ function runInsertInlineControlCommit(input) {
|
|
|
193399
193399
|
preconditions,
|
|
193400
193400
|
patchMaps,
|
|
193401
193401
|
textRangeShifts: shifts,
|
|
193402
|
-
...changeMode === "direct" && op.control === "lineBreak" && "runPropertiesXml" in rewritten ? {
|
|
193403
|
-
|
|
193404
|
-
kind: "
|
|
193402
|
+
...changeMode === "direct" && (op.control === "tab" || op.control === "lineBreak") && "runPropertiesXml" in rewritten ? {
|
|
193403
|
+
directInlineControl: {
|
|
193404
|
+
kind: "directInlineControl",
|
|
193405
|
+
control: op.control,
|
|
193405
193406
|
afterParagraphTail: "afterParagraphTail" in rewritten && rewritten.afterParagraphTail === true,
|
|
193406
193407
|
blockId: op.on.startBlockId,
|
|
193407
193408
|
startOffset: op.on.startOffset,
|
|
@@ -193708,7 +193709,7 @@ function finalizeInlineControlCommit(args) {
|
|
|
193708
193709
|
changeMode: op.changeMode ?? "direct",
|
|
193709
193710
|
targetBlockIds: [op.on.startBlockId],
|
|
193710
193711
|
atomCarrierContract: SD_DEFAULT_ATOM_CARRIER_CONTRACT,
|
|
193711
|
-
...args.
|
|
193712
|
+
...args.directInlineControl ? { directInlineControl: args.directInlineControl } : {},
|
|
193712
193713
|
...args.trackedTextInsert ? { trackedTextInsert: args.trackedTextInsert } : {},
|
|
193713
193714
|
...args.trackedTextEdit ? { trackedTextEdit: args.trackedTextEdit } : {}
|
|
193714
193715
|
};
|
|
@@ -369135,6 +369136,7 @@ async function compilePlan(context, input) {
|
|
|
369135
369136
|
}
|
|
369136
369137
|
detectTargetConflicts(context, steps, failures);
|
|
369137
369138
|
detectUnsupportedRuntimeDrift(input.steps, failures);
|
|
369139
|
+
detectTargetOffsetDriftRisk(steps, failures);
|
|
369138
369140
|
return { evaluatedRevision, steps, failures };
|
|
369139
369141
|
}
|
|
369140
369142
|
function isOrderedAtomicTextProgram(steps) {
|
|
@@ -369619,6 +369621,14 @@ function detectUnsupportedRuntimeDrift(steps, failures) {
|
|
|
369619
369621
|
message: "multi-step mutation plans cannot use revision-bound ref targets; use selector targets so the engine can re-resolve each step before commit."
|
|
369620
369622
|
});
|
|
369621
369623
|
}
|
|
369624
|
+
if (step3.where.by === "target" && step3.where.target.kind === "selection" && step3.where.target.start.kind === "text" && step3.where.target.end.kind === "text" && step3.where.target.start.blockId !== step3.where.target.end.blockId) {
|
|
369625
|
+
failures.push({
|
|
369626
|
+
code: "CAPABILITY_UNSUPPORTED",
|
|
369627
|
+
stepId: step3.id,
|
|
369628
|
+
phase: "compile",
|
|
369629
|
+
message: 'multi-step mutation plans cannot combine a cross-block by:"target" step with other mutating steps; ' + "conflict and offset-drift detection only see that step's first block. Apply it alone, or split the " + "plan so the cross-block step runs in its own mutations.apply call."
|
|
369630
|
+
});
|
|
369631
|
+
}
|
|
369622
369632
|
}
|
|
369623
369633
|
}
|
|
369624
369634
|
}
|
|
@@ -369659,6 +369669,33 @@ function detectTargetConflicts(context, steps, failures) {
|
|
|
369659
369669
|
}
|
|
369660
369670
|
}
|
|
369661
369671
|
}
|
|
369672
|
+
function detectTargetOffsetDriftRisk(steps, failures) {
|
|
369673
|
+
const textShiftingOps = new Set(["text.rewrite", "text.delete", "text.insert"]);
|
|
369674
|
+
const byBlock = new Map;
|
|
369675
|
+
for (const step3 of steps) {
|
|
369676
|
+
if (!textShiftingOps.has(step3.op) || step3.source.op === "assert" || step3.source.where?.by !== "target")
|
|
369677
|
+
continue;
|
|
369678
|
+
const resolutions = step3.resolutions ?? (step3.resolution ? [step3.resolution] : []);
|
|
369679
|
+
for (const resolution of resolutions) {
|
|
369680
|
+
const key2 = `${storyKeyForTarget(resolution.target)}::${resolution.target.blockId}`;
|
|
369681
|
+
const list2 = byBlock.get(key2) ?? [];
|
|
369682
|
+
list2.push(step3);
|
|
369683
|
+
byBlock.set(key2, list2);
|
|
369684
|
+
}
|
|
369685
|
+
}
|
|
369686
|
+
for (const blockSteps of byBlock.values()) {
|
|
369687
|
+
if (blockSteps.length <= 1)
|
|
369688
|
+
continue;
|
|
369689
|
+
for (const step3 of blockSteps) {
|
|
369690
|
+
failures.push({
|
|
369691
|
+
code: "CAPABILITY_UNSUPPORTED",
|
|
369692
|
+
stepId: step3.stepId,
|
|
369693
|
+
phase: "compile",
|
|
369694
|
+
message: `step "${step3.stepId}" shares a block with another by:"target" text-shifting step in this plan; explicit ` + "offsets are not re-derived between steps, so an earlier same-block step can shift this one's offsets. " + 'Split same-block edits into separate mutations.apply calls, or use by:"select" for later occurrences in ' + "the same block."
|
|
369695
|
+
});
|
|
369696
|
+
}
|
|
369697
|
+
}
|
|
369698
|
+
}
|
|
369662
369699
|
function conflictRangeForResolution(context, step3, resolution) {
|
|
369663
369700
|
if (step3.source.op !== "format.apply" || step3.source.args.scope !== "block" && step3.source.args.alignment === undefined) {
|
|
369664
369701
|
return resolution.range;
|
|
@@ -369713,9 +369750,117 @@ async function resolveMutationStep(context, step3, story, changeMode) {
|
|
|
369713
369750
|
const compiled = resolveRefMutationStep(context, step3, story, matches[0].ref);
|
|
369714
369751
|
return applySelectMatchReplacementPolicy(compiled, step3, matches[0].groups);
|
|
369715
369752
|
}
|
|
369753
|
+
if (step3.where.by === "target") {
|
|
369754
|
+
return resolveTargetWhereMutationStep(context, step3, step3.where, story, changeMode);
|
|
369755
|
+
}
|
|
369716
369756
|
const ref5 = resolveStepRef(step3);
|
|
369717
369757
|
return resolveRefMutationStep(context, step3, story, ref5);
|
|
369718
369758
|
}
|
|
369759
|
+
function resolveTargetWhereMutationStep(context, step3, where, story, changeMode) {
|
|
369760
|
+
const target = where.target;
|
|
369761
|
+
if (target.kind !== "selection" || target.start.kind !== "text" || target.end.kind !== "text") {
|
|
369762
|
+
throw new DocumentApiValidationError2("INVALID_TARGET", `v2 ${step3.op} target steps require a text SelectionTarget with text-kind endpoints.`);
|
|
369763
|
+
}
|
|
369764
|
+
const storyLocator = target.story ?? story;
|
|
369765
|
+
if (!isSupportedMutationStoryScope(storyLocator)) {
|
|
369766
|
+
throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", `v2 mutation plan engine supports only the body story; "${storyLocator?.storyType}" story targets are not supported.`);
|
|
369767
|
+
}
|
|
369768
|
+
if (step3.op === "text.rewrite" && step3.args.replacementMode === "regex-template") {
|
|
369769
|
+
throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", 'v2 text.rewrite target steps do not support replacementMode "regex-template"; an explicit target carries no ' + 'capture groups. Use a by:"select" step for regex-template replacements.');
|
|
369770
|
+
}
|
|
369771
|
+
const selectionMutation = new V2SelectionMutationAdapter(context);
|
|
369772
|
+
if (step3.op === "text.insert") {
|
|
369773
|
+
const { text: text4, position: position2 } = readInsertArgs(step3);
|
|
369774
|
+
const point3 = position2 === "before" ? target.start : target.end;
|
|
369775
|
+
const collapsed = {
|
|
369776
|
+
kind: "selection",
|
|
369777
|
+
start: point3,
|
|
369778
|
+
end: point3,
|
|
369779
|
+
...target.story ? { story: target.story } : {},
|
|
369780
|
+
...target.coordinateSpace ? { coordinateSpace: target.coordinateSpace } : {}
|
|
369781
|
+
};
|
|
369782
|
+
const request = { kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} };
|
|
369783
|
+
const receipt3 = selectionMutation.execute({ kind: "insert", target: collapsed, text: text4, ...story ? { in: story } : {} }, { changeMode, dryRun: true });
|
|
369784
|
+
if (!receipt3.success)
|
|
369785
|
+
throw new DocumentApiValidationError2(receipt3.failure.code, receipt3.failure.message);
|
|
369786
|
+
const resolution2 = {
|
|
369787
|
+
target: receipt3.resolution.target,
|
|
369788
|
+
range: receipt3.resolution.range,
|
|
369789
|
+
text: receipt3.resolution.text
|
|
369790
|
+
};
|
|
369791
|
+
return {
|
|
369792
|
+
stepId: step3.id,
|
|
369793
|
+
op: "text.insert",
|
|
369794
|
+
resolution: resolution2,
|
|
369795
|
+
request,
|
|
369796
|
+
noopEquivalentText: text4.length === 0 ? text4 : undefined,
|
|
369797
|
+
source: step3
|
|
369798
|
+
};
|
|
369799
|
+
}
|
|
369800
|
+
if (step3.op === "format.apply") {
|
|
369801
|
+
const crossBlock = target.start.blockId !== target.end.blockId;
|
|
369802
|
+
if (crossBlock && (step3.args.alignment !== undefined || step3.args.scope === "block")) {
|
|
369803
|
+
throw new DocumentApiValidationError2("CAPABILITY_UNSUPPORTED", "v2 format.apply target steps spanning more than one block support only an inline patch with the default " + '(non-block) scope; split a cross-block alignment or scope:"block" edit into one step per block.');
|
|
369804
|
+
}
|
|
369805
|
+
const placeholderResolution = {
|
|
369806
|
+
target: {
|
|
369807
|
+
kind: "text",
|
|
369808
|
+
blockId: target.start.blockId,
|
|
369809
|
+
range: { start: 0, end: 0 },
|
|
369810
|
+
...storyLocator ? { story: storyLocator } : {}
|
|
369811
|
+
},
|
|
369812
|
+
range: { from: 0, to: 0 },
|
|
369813
|
+
text: ""
|
|
369814
|
+
};
|
|
369815
|
+
const request = buildFormatCommitRequest(context, step3, placeholderResolution, target, story, storyLocator);
|
|
369816
|
+
if (request.kind !== "format") {
|
|
369817
|
+
throw new DocumentApiValidationError2("INVALID_TARGET", "v2 format.apply target steps require a resolvable target.");
|
|
369818
|
+
}
|
|
369819
|
+
let resolution2;
|
|
369820
|
+
if (request.inline) {
|
|
369821
|
+
const receipt3 = "target" in request ? selectionMutation.execute({ kind: "format", target: request.target, inline: request.inline, ...request.in ? { in: request.in } : {} }, { changeMode, dryRun: true, ...request.skipAtomicObjects ? { skipAtomicObjects: true } : {} }) : selectionMutation.execute({ kind: "format", ref: request.ref, inline: request.inline, ...request.in ? { in: request.in } : {} }, { changeMode, dryRun: true, ...request.skipAtomicObjects ? { skipAtomicObjects: true } : {} });
|
|
369822
|
+
if (!receipt3.success)
|
|
369823
|
+
throw new DocumentApiValidationError2(receipt3.failure.code, receipt3.failure.message);
|
|
369824
|
+
resolution2 = {
|
|
369825
|
+
target: receipt3.resolution.target,
|
|
369826
|
+
range: receipt3.resolution.range,
|
|
369827
|
+
text: receipt3.resolution.text
|
|
369828
|
+
};
|
|
369829
|
+
} else {
|
|
369830
|
+
const blockText = readBlockTargetText(context, target.start.blockId, Number.MAX_SAFE_INTEGER, storyLocator, target.coordinateSpace);
|
|
369831
|
+
resolution2 = {
|
|
369832
|
+
target: { kind: "text", blockId: target.start.blockId, range: { start: 0, end: blockText.length }, ...storyLocator ? { story: storyLocator } : {} },
|
|
369833
|
+
range: { from: 0, to: blockText.length },
|
|
369834
|
+
text: blockText
|
|
369835
|
+
};
|
|
369836
|
+
}
|
|
369837
|
+
return {
|
|
369838
|
+
stepId: step3.id,
|
|
369839
|
+
op: "format.apply",
|
|
369840
|
+
resolution: resolution2,
|
|
369841
|
+
request,
|
|
369842
|
+
source: step3
|
|
369843
|
+
};
|
|
369844
|
+
}
|
|
369845
|
+
const rewriteTemplate = step3.op === "text.delete" ? "" : normalizeReplacement(step3.args.replacement);
|
|
369846
|
+
const probeReceipt = selectionMutation.execute({ kind: "replace", target, text: rewriteTemplate, ...story ? { in: story } : {} }, { changeMode, dryRun: true });
|
|
369847
|
+
if (!probeReceipt.success)
|
|
369848
|
+
throw new DocumentApiValidationError2(probeReceipt.failure.code, probeReceipt.failure.message);
|
|
369849
|
+
const resolution = {
|
|
369850
|
+
target: probeReceipt.resolution.target,
|
|
369851
|
+
range: probeReceipt.resolution.range,
|
|
369852
|
+
text: probeReceipt.resolution.text
|
|
369853
|
+
};
|
|
369854
|
+
const replacementText = step3.op === "text.delete" ? "" : replacementTextForMatch(step3, resolution.text);
|
|
369855
|
+
return {
|
|
369856
|
+
stepId: step3.id,
|
|
369857
|
+
op: step3.op,
|
|
369858
|
+
resolution,
|
|
369859
|
+
request: { kind: "replace", target, text: replacementText, ...story ? { in: story } : {} },
|
|
369860
|
+
...step3.op === "text.rewrite" ? { noopEquivalentText: replacementText } : {},
|
|
369861
|
+
source: step3
|
|
369862
|
+
};
|
|
369863
|
+
}
|
|
369719
369864
|
function resolveRefMutationStep(context, step3, story, ref5, cache) {
|
|
369720
369865
|
if (isV2RangeRef(ref5)) {
|
|
369721
369866
|
return resolveRangeRefMutationStep(context, step3, story, ref5);
|
|
@@ -424205,8 +424350,12 @@ function tryMirrorStoryText(prepared, extension2, options, admitted) {
|
|
|
424205
424350
|
const validation = admitted ?? validateDirectStoryText(prepared, extension2, options);
|
|
424206
424351
|
if (!validation.ok)
|
|
424207
424352
|
return { mirrored: false, failureReason: validation.failureReason };
|
|
424208
|
-
const source = validation.source.kind === "insertInlineControl" ? {
|
|
424209
|
-
|
|
424353
|
+
const source = validation.source.kind === "insertInlineControl" ? {
|
|
424354
|
+
changeMode: "direct",
|
|
424355
|
+
on: validation.source.on,
|
|
424356
|
+
newText: validation.inlineControl?.control === "tab" ? "\t" : `
|
|
424357
|
+
`
|
|
424358
|
+
} : validation.source;
|
|
424210
424359
|
const target = validation.target;
|
|
424211
424360
|
try {
|
|
424212
424361
|
target.scope.doc.transact(() => {
|
|
@@ -424275,7 +424424,7 @@ function tryMirrorStoryText(prepared, extension2, options, admitted) {
|
|
|
424275
424424
|
});
|
|
424276
424425
|
}
|
|
424277
424426
|
if (source.newText.length > 0) {
|
|
424278
|
-
if (deleteLength === 0 || validation.
|
|
424427
|
+
if (deleteLength === 0 || validation.inlineControl) {
|
|
424279
424428
|
if (!validation.directInsert) {
|
|
424280
424429
|
throw new Error("direct storyText mirror missing typed insert metadata");
|
|
424281
424430
|
}
|
|
@@ -424285,7 +424434,7 @@ function tryMirrorStoryText(prepared, extension2, options, admitted) {
|
|
|
424285
424434
|
text: source.newText,
|
|
424286
424435
|
txId: prepared.txId,
|
|
424287
424436
|
directInsert: validation.directInsert,
|
|
424288
|
-
preserveZeroLengthAtOffset: validation.
|
|
424437
|
+
preserveZeroLengthAtOffset: validation.inlineControl?.afterParagraphTail,
|
|
424289
424438
|
acceptedTextInsertionSplit: validation.acceptedTextInsertionSplit
|
|
424290
424439
|
});
|
|
424291
424440
|
} else {
|
|
@@ -424405,10 +424554,10 @@ function cloneTrackedWrapperAtom(source, id2, visibleOffset) {
|
|
|
424405
424554
|
}
|
|
424406
424555
|
function validateDirectStoryText(prepared, extension2, options) {
|
|
424407
424556
|
const source = prepared.source;
|
|
424408
|
-
const
|
|
424557
|
+
const inlineControl = source.kind === "insertInlineControl" ? extension2.directInlineControl : undefined;
|
|
424409
424558
|
if (source.kind === "insertInlineControl") {
|
|
424410
|
-
if (source.control !== "lineBreak" || (source.changeMode ?? "direct") !== "direct" || !
|
|
424411
|
-
return { ok: false, failureReason: "storyText requires matching direct
|
|
424559
|
+
if (source.control !== "tab" && source.control !== "lineBreak" || (source.changeMode ?? "direct") !== "direct" || !inlineControl || inlineControl.kind !== "directInlineControl" || inlineControl.control !== source.control || typeof inlineControl.afterParagraphTail !== "boolean" || inlineControl.blockId !== source.on.startBlockId || inlineControl.startOffset !== source.on.startOffset || inlineControl.endOffset !== source.on.endOffset || parsePreparedRunAttributes(inlineControl.runPropertiesXml) === null) {
|
|
424560
|
+
return { ok: false, failureReason: "storyText requires matching direct inline-control metadata" };
|
|
424412
424561
|
}
|
|
424413
424562
|
}
|
|
424414
424563
|
if (source.kind !== "editText" && source.kind !== "insertInlineControl") {
|
|
@@ -424456,15 +424605,15 @@ function validateDirectStoryText(prepared, extension2, options) {
|
|
|
424456
424605
|
if (trackedEdit && !trackedEdit.ok) {
|
|
424457
424606
|
return { ok: false, failureReason: trackedEdit.failureReason };
|
|
424458
424607
|
}
|
|
424459
|
-
const directInsert =
|
|
424608
|
+
const directInsert = inlineControl ? {
|
|
424460
424609
|
ok: true,
|
|
424461
424610
|
directInsert: {
|
|
424462
424611
|
kind: "directTextInsert",
|
|
424463
|
-
blockId:
|
|
424464
|
-
startOffset:
|
|
424465
|
-
text: `
|
|
424612
|
+
blockId: inlineControl.blockId,
|
|
424613
|
+
startOffset: inlineControl.startOffset,
|
|
424614
|
+
text: inlineControl.control === "tab" ? "\t" : `
|
|
424466
424615
|
`,
|
|
424467
|
-
runPropertiesXml:
|
|
424616
|
+
runPropertiesXml: inlineControl.runPropertiesXml
|
|
424468
424617
|
}
|
|
424469
424618
|
} : source.kind === "editText" && source.changeMode === "direct" && isPureDirectTextInsert(source) ? validateDirectTextInsert(source, extension2) : null;
|
|
424470
424619
|
if (directInsert && !directInsert.ok) {
|
|
@@ -424502,7 +424651,7 @@ function validateDirectStoryText(prepared, extension2, options) {
|
|
|
424502
424651
|
};
|
|
424503
424652
|
}
|
|
424504
424653
|
const target = resolveStoryTextMutationTarget(doc2, source.on.startBlockId);
|
|
424505
|
-
if (lineBreak && !
|
|
424654
|
+
if (inlineControl?.control === "lineBreak" && !inlineControl.afterParagraphTail && hasStoryTextBoundaryInRange(target, source.on.startOffset, source.on.endOffset)) {
|
|
424506
424655
|
return { ok: false, failureReason: "line-break boundary placement requires typed collaboration support" };
|
|
424507
424656
|
}
|
|
424508
424657
|
let validatedTrackedRefinement;
|
|
@@ -424535,7 +424684,7 @@ function validateDirectStoryText(prepared, extension2, options) {
|
|
|
424535
424684
|
target,
|
|
424536
424685
|
...acceptedTextInsertionSplit ? { acceptedTextInsertionSplit } : {},
|
|
424537
424686
|
...directInsert?.ok ? { directInsert: directInsert.directInsert } : {},
|
|
424538
|
-
...
|
|
424687
|
+
...inlineControl ? { inlineControl: { control: inlineControl.control, afterParagraphTail: inlineControl.afterParagraphTail } } : {},
|
|
424539
424688
|
...trackedInsert?.ok ? { trackedInsert: trackedInsert.trackedInsert } : {},
|
|
424540
424689
|
...trackedInsertContinuation ? { trackedInsertContinuation: true } : {},
|
|
424541
424690
|
...validatedTrackedRefinement ? { trackedRefinement: validatedTrackedRefinement } : {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdoc/mcp",
|
|
3
|
-
"version": "1.0.1-next.
|
|
3
|
+
"version": "1.0.1-next.8",
|
|
4
4
|
"description": "Model Context Protocol server for SuperDoc, giving an AI agent tools to read and edit .docx files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
27
|
-
"@superdoc/sdk": "2.13.1-next.
|
|
27
|
+
"@superdoc/sdk": "2.13.1-next.8",
|
|
28
28
|
"debug": "^4.4.3",
|
|
29
29
|
"zod": "^4.3.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"superdoc": "2.16.1-next.
|
|
33
|
-
"@superdoc/docx-engine": "0.15.1-next.
|
|
32
|
+
"superdoc": "2.16.1-next.8",
|
|
33
|
+
"@superdoc/docx-engine": "0.15.1-next.8",
|
|
34
34
|
"@superdoc/document-api": "0.1.0-alpha.0",
|
|
35
35
|
"@types/bun": "^1.3.8",
|
|
36
36
|
"@types/node": "22.19.2",
|