Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
1e4a7bf
Merge remote-tracking branch 'origin/main' into merge/main-into-stabl…
github-actions[bot] Jun 12, 2026
999a660
Merge pull request #3720 from superdoc-dev/merge/main-into-stable-202…
caio-pizzol Jun 12, 2026
7f76d11
chore(cli): 0.17.0 [skip ci]
semantic-release-bot Jun 12, 2026
9306083
chore(sdk): 1.16.0 [skip ci]
semantic-release-bot Jun 12, 2026
bc7e216
chore(mcp): 0.12.0 [skip ci]
semantic-release-bot Jun 12, 2026
e80feb6
chore(release): 1.40.0 [skip ci]
semantic-release-bot Jun 12, 2026
550d4be
chore(react): 1.11.0 [skip ci]
semantic-release-bot Jun 12, 2026
cc4402d
chore(vscode): 2.12.0 [skip ci]
semantic-release-bot Jun 12, 2026
44aceda
chore(esign): 2.7.2 [skip ci]
semantic-release-bot Jun 12, 2026
caad8b4
Merge remote-tracking branch 'origin/main' into merge/main-into-stabl…
github-actions[bot] Jun 12, 2026
92185c2
Merge pull request #3726 from superdoc-dev/merge/main-into-stable-202…
caio-pizzol Jun 12, 2026
07de012
fix: roll back default toolbar fonts
caio-pizzol Jun 12, 2026
6681153
test: update font dropdown behavior expectations
caio-pizzol Jun 12, 2026
85c3cb4
Merge pull request #3729 from superdoc-dev/codex/stable-toolbar-font-…
caio-pizzol Jun 12, 2026
74b86bb
chore(cli): 0.17.1 [skip ci]
semantic-release-bot Jun 12, 2026
33e6b91
chore(sdk): 1.16.1 [skip ci]
semantic-release-bot Jun 12, 2026
d4de658
chore(mcp): 0.12.1 [skip ci]
semantic-release-bot Jun 12, 2026
e75e52d
chore(release): 1.40.1 [skip ci]
semantic-release-bot Jun 12, 2026
155ae82
chore(react): 1.11.1 [skip ci]
semantic-release-bot Jun 12, 2026
d9be570
chore(vscode): 2.12.1 [skip ci]
semantic-release-bot Jun 12, 2026
2d0057a
chore: merge main into stable (conflicts need resolution)
github-actions[bot] Jun 14, 2026
11cc3d1
fix: resolve stable merge conflicts
caio-pizzol Jun 14, 2026
30cd343
fix: update font dropdown behavior expectations
caio-pizzol Jun 14, 2026
90be5e8
fix: align font option tests with rich pack
caio-pizzol Jun 14, 2026
5796b6e
fix: update ui font option expectations
caio-pizzol Jun 15, 2026
e9eb179
fix: avoid contract demo rebuild on dev
caio-pizzol Jun 15, 2026
d8c70b1
fix: update react font hook expectations
caio-pizzol Jun 15, 2026
0499121
Merge pull request #3737 from superdoc-dev/merge/main-into-stable-202…
caio-pizzol Jun 15, 2026
32624be
chore(cli): 0.18.0 [skip ci]
semantic-release-bot Jun 15, 2026
74cfa3d
chore(sdk): 1.17.0 [skip ci]
semantic-release-bot Jun 15, 2026
7549a8f
chore(mcp): 0.13.0 [skip ci]
semantic-release-bot Jun 15, 2026
806dca1
chore(fonts): 0.1.1 [skip ci]
semantic-release-bot Jun 15, 2026
2f116fc
chore(release): 1.41.0 [skip ci]
semantic-release-bot Jun 15, 2026
64c6bc4
chore(react): 1.12.0 [skip ci]
semantic-release-bot Jun 15, 2026
561cbf4
chore(vscode): 2.13.0 [skip ci]
semantic-release-bot Jun 15, 2026
5b05511
Merge remote-tracking branch 'origin/main' into merge/main-into-stabl…
github-actions[bot] Jun 20, 2026
5af1a64
fix(cli): persist track-change scope across host calls
caio-pizzol Jun 20, 2026
87cfce5
Merge pull request #3761 from superdoc-dev/merge/main-into-stable-202…
caio-pizzol Jun 20, 2026
2fef807
chore(template-builder): 1.12.1 [skip ci]
semantic-release-bot Jun 20, 2026
fb0af73
chore(cli): 0.19.0 [skip ci]
semantic-release-bot Jun 20, 2026
8e7fcc1
chore(sdk): 1.18.0 [skip ci]
semantic-release-bot Jun 20, 2026
b805b7a
chore(mcp): 0.14.0 [skip ci]
semantic-release-bot Jun 20, 2026
08ea89c
chore(fonts): 0.1.2 [skip ci]
semantic-release-bot Jun 20, 2026
a0b4d65
chore(release): 1.42.0 [skip ci]
semantic-release-bot Jun 20, 2026
57c3762
chore(react): 1.13.0 [skip ci]
semantic-release-bot Jun 20, 2026
33654b7
chore(vscode): 2.14.0 [skip ci]
semantic-release-bot Jun 20, 2026
fa3ce4e
Merge remote-tracking branch 'origin/main' into merge/main-into-stabl…
github-actions[bot] Jun 23, 2026
a861374
Merge pull request #3765 from superdoc-dev/merge/main-into-stable-202…
caio-pizzol Jun 23, 2026
d9ca352
chore(cli): 0.20.0 [skip ci]
semantic-release-bot Jun 23, 2026
3467abc
chore(sdk): 1.19.0 [skip ci]
semantic-release-bot Jun 23, 2026
2dd6d26
chore(mcp): 0.15.0 [skip ci]
semantic-release-bot Jun 23, 2026
2429a51
chore(release): 1.43.0 [skip ci]
semantic-release-bot Jun 23, 2026
a584cda
chore(react): 1.14.0 [skip ci]
semantic-release-bot Jun 23, 2026
7dad40d
chore(vscode): 2.15.0 [skip ci]
semantic-release-bot Jun 23, 2026
0fb579c
fix(super-editor): keep editing-mode typing inside tracked changes pl…
caio-pizzol Jun 24, 2026
95358a7
fix(super-editor): strip only inherited marks on editing-mode insert,…
caio-pizzol Jun 24, 2026
500b970
Merge pull request #3771 from superdoc-dev/caio-pizzol/cherry-pick-sd…
caio-pizzol Jun 24, 2026
448ef10
chore(cli): 0.20.1 [skip ci]
semantic-release-bot Jun 24, 2026
1af226f
chore(sdk): 1.19.1 [skip ci]
semantic-release-bot Jun 24, 2026
9268fea
chore(mcp): 0.15.1 [skip ci]
semantic-release-bot Jun 24, 2026
ad2602a
chore(release): 1.43.1 [skip ci]
semantic-release-bot Jun 24, 2026
9694d3d
chore(react): 1.14.1 [skip ci]
semantic-release-bot Jun 24, 2026
2572bc1
chore(vscode): 2.15.1 [skip ci]
semantic-release-bot Jun 24, 2026
069ad52
chore: merge stable into main
caio-pizzol Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/cli",
"version": "0.19.0",
"version": "0.20.1",
"type": "module",
"bin": {
"superdoc": "./dist/index.js"
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/platforms/cli-darwin-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/cli-darwin-arm64",
"version": "0.19.0",
"version": "0.20.1",
"os": [
"darwin"
],
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/platforms/cli-darwin-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/cli-darwin-x64",
"version": "0.19.0",
"version": "0.20.1",
"os": [
"darwin"
],
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/platforms/cli-linux-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/cli-linux-arm64",
"version": "0.19.0",
"version": "0.20.1",
"os": [
"linux"
],
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/platforms/cli-linux-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/cli-linux-x64",
"version": "0.19.0",
"version": "0.20.1",
"os": [
"linux"
],
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/platforms/cli-windows-x64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/cli-windows-x64",
"version": "0.19.0",
"version": "0.20.1",
"os": [
"win32"
],
Expand Down
2 changes: 1 addition & 1 deletion apps/mcp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/mcp",
"version": "0.14.0",
"version": "0.15.1",
"type": "module",
"engines": {
"node": ">=20"
Expand Down
2 changes: 1 addition & 1 deletion apps/vscode-ext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "superdoc-vscode-ext",
"displayName": "SuperDoc - Word Document Editor",
"description": "Open and edit Word documents (.docx) directly in VS Code using SuperDoc",
"version": "2.14.0",
"version": "2.15.1",
"publisher": "superdoc-dev",
"icon": "logo.png",
"homepage": "https://superdoc.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/react",
"version": "1.13.0",
"version": "1.14.1",
"description": "Official React wrapper for the SuperDoc document editor",
"type": "module",
"main": "./dist/index.cjs",
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/langs/node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk",
"version": "1.18.0",
"version": "1.19.1",
"private": false,
"type": "module",
"main": "./dist/index.cjs",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk-darwin-arm64",
"version": "1.18.0",
"version": "1.19.1",
"os": [
"darwin"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk-darwin-x64",
"version": "1.18.0",
"version": "1.19.1",
"os": [
"darwin"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk-linux-arm64",
"version": "1.18.0",
"version": "1.19.1",
"os": [
"linux"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk-linux-x64",
"version": "1.18.0",
"version": "1.19.1",
"os": [
"linux"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk-windows-x64",
"version": "1.18.0",
"version": "1.19.1",
"os": [
"win32"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "superdoc-sdk-cli-darwin-arm64"
version = "1.18.0"
version = "1.19.1"
description = "SuperDoc CLI binary for macOS ARM64 (Apple Silicon)"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "superdoc-sdk-cli-darwin-x64"
version = "1.18.0"
version = "1.19.1"
description = "SuperDoc CLI binary for macOS x64 (Intel)"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "superdoc-sdk-cli-linux-arm64"
version = "1.18.0"
version = "1.19.1"
description = "SuperDoc CLI binary for Linux ARM64"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "superdoc-sdk-cli-linux-x64"
version = "1.18.0"
version = "1.19.1"
description = "SuperDoc CLI binary for Linux x64"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "superdoc-sdk-cli-windows-x64"
version = "1.18.0"
version = "1.19.1"
description = "SuperDoc CLI binary for Windows x64"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
12 changes: 6 additions & 6 deletions packages/sdk/langs/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ build-backend = "setuptools.build_meta"

[project]
name = "superdoc-sdk"
version = "1.18.0"
version = "1.19.1"
description = "SuperDoc SDK (CLI-backed)"
readme = "README.md"
requires-python = ">=3.9"
license = "AGPL-3.0"
authors = [{ name = "SuperDoc" }]
dependencies = [
"superdoc-sdk-cli-darwin-arm64==1.18.0; platform_system == 'Darwin' and (platform_machine == 'arm64' or platform_machine == 'aarch64' or platform_machine == 'ARM64')",
"superdoc-sdk-cli-darwin-x64==1.18.0; platform_system == 'Darwin' and (platform_machine == 'x86_64' or platform_machine == 'AMD64' or platform_machine == 'amd64')",
"superdoc-sdk-cli-linux-x64==1.18.0; platform_system == 'Linux' and (platform_machine == 'x86_64' or platform_machine == 'AMD64' or platform_machine == 'amd64')",
"superdoc-sdk-cli-linux-arm64==1.18.0; platform_system == 'Linux' and (platform_machine == 'arm64' or platform_machine == 'aarch64' or platform_machine == 'ARM64')",
"superdoc-sdk-cli-windows-x64==1.18.0; platform_system == 'Windows' and (platform_machine == 'x86_64' or platform_machine == 'AMD64' or platform_machine == 'amd64')",
"superdoc-sdk-cli-darwin-arm64==1.19.1; platform_system == 'Darwin' and (platform_machine == 'arm64' or platform_machine == 'aarch64' or platform_machine == 'ARM64')",
"superdoc-sdk-cli-darwin-x64==1.19.1; platform_system == 'Darwin' and (platform_machine == 'x86_64' or platform_machine == 'AMD64' or platform_machine == 'amd64')",
"superdoc-sdk-cli-linux-x64==1.19.1; platform_system == 'Linux' and (platform_machine == 'x86_64' or platform_machine == 'AMD64' or platform_machine == 'amd64')",
"superdoc-sdk-cli-linux-arm64==1.19.1; platform_system == 'Linux' and (platform_machine == 'arm64' or platform_machine == 'aarch64' or platform_machine == 'ARM64')",
"superdoc-sdk-cli-windows-x64==1.19.1; platform_system == 'Windows' and (platform_machine == 'x86_64' or platform_machine == 'AMD64' or platform_machine == 'amd64')",
]

[tool.setuptools]
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@superdoc-dev/sdk-workspace",
"version": "1.18.0",
"version": "1.19.1",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"sdkVersion": "1.18.0"
"sdkVersion": "1.19.1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,48 @@ describe('Editor dispatch tracked-change meta', () => {
expect(markEntries(editor, TrackInsertMarkName).some(({ text }) => text.includes('PASTE'))).toBe(false);
});

it('preserves review marks carried by a pasted slice inside another user tracked insertion while local track mode is off', () => {
({ editor } = initTestEditor({
mode: 'text',
content: '<p></p>',
user: BOB,
useImmediateSetTimeout: false,
}));
setDocumentWithTrackedInsertion(editor);

// Pasting a SuperDoc slice that already carries its own tracked-review marks
// (a copied suggestion) into the interior of another suggestion must keep the
// pasted marks. Only the ENCLOSING mark inherited from the neighbour is stripped;
// a blanket strip-by-type would silently drop the pasted review metadata.
const { schema } = editor;
const pastedMark = schema.marks[TrackInsertMarkName].create({
id: 'pasted-insert',
author: 'Carol Author',
authorEmail: 'carol@example.com',
date: FIXED_DATE,
});
const openSlice = new Slice(
Fragment.from(
schema.nodes.paragraph.create(
{ sdBlockId: 'paste-src' },
schema.nodes.run.create({}, schema.text('COPIED', [pastedMark])),
),
),
2,
2,
);

const insertPos = findTextRange(editor, INSERTED_TEXT).from + 4;
editor.dispatch(
editor.state.tr.replaceRange(insertPos, insertPos, openSlice).setMeta('inputType', 'insertFromPaste'),
);

// The pasted suggestion keeps its own review id (it is not the enclosing mark).
expect(textForMarkId(editor, TrackInsertMarkName, 'pasted-insert')).toBe('COPIED');
// The enclosing foreign insertion did not absorb the pasted text into its id.
expect(textForMarkId(editor, TrackInsertMarkName, FOREIGN_INSERT_ID)).toBe(INSERTED_TEXT);
});

it('inserts plain text on direct insert inside another user tracked deletion while local track mode is off', () => {
({ editor } = initTestEditor({
mode: 'text',
Expand Down
55 changes: 40 additions & 15 deletions packages/super-editor/src/editors/v1/core/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,16 +426,35 @@ const transactionTouchesTrackedReviewState = (state: EditorState, tr: Transactio
return tr.steps.some((step, index) => stepTouchesTrackedReviewState(step, docs[index] ?? state.doc));
};

// The tracked-review mark instances that ENCLOSE a collapsed position (present on
// both nodeBefore and nodeAfter). These are exactly the marks PM mark-inheritance
// copies onto text inserted strictly inside the span. Returning the specific
// instances (matched by type + attrs) lets the cleanup strip only the inherited
// marks - marks a pasted slice carries in (a different review id) are left intact.
const enclosingTrackedReviewMarksAtCollapsedPosition = (doc: PmNode, pos: number): PmMark[] => {
const boundedPos = Math.max(0, Math.min(doc.content.size, pos));
const $pos = doc.resolve(boundedPos);
const afterKeys = trackedReviewMarkKeysForNode($pos.nodeAfter);
if (!afterKeys.size) return [];
const enclosing: PmMark[] = [];
for (const mark of $pos.nodeBefore?.marks ?? []) {
const key = trackedReviewMarkKey(mark);
if (key && afterKeys.has(key)) enclosing.push(mark);
}
return enclosing;
};

// Editing-mode collapsed insert strictly inside a tracked review span: returns
// the inserted range (in the post-step doc) so the inherited suggestion mark can
// be stripped from the new text. Marks are inclusive:false, so a strictly-interior
// insert still inherits the neighbour's trackInsert/trackDelete via PM mark
// inheritance; without the strip the typed chars would silently join the
// suggestion (struck-through inside a deletion / counted as someone else's insert).
// the inserted range (in the post-step doc) plus the enclosing mark instances so
// the inherited suggestion mark can be stripped from the new text. Marks are
// inclusive:false, so a strictly-interior insert still inherits the neighbour's
// trackInsert/trackDelete via PM mark inheritance; without the strip the typed
// chars would silently join the suggestion (struck-through inside a deletion /
// counted as someone else's insert).
const collapsedInsertInsideTrackedReviewMarkRange = (
state: EditorState,
tr: Transaction,
): { from: number; to: number } | null => {
): { from: number; to: number; marks: PmMark[] } | null => {
if (!tr.docChanged || tr.steps.length !== 1) return null;

const [step] = tr.steps;
Expand All @@ -444,14 +463,15 @@ const collapsedInsertInsideTrackedReviewMarkRange = (

const docs = (tr as unknown as { docs?: PmNode[] }).docs ?? [];
const docBeforeStep = docs[0] ?? state.doc;
if (!collapsedPositionIsInsideTrackedReviewMark(docBeforeStep, step.from)) return null;
const marks = enclosingTrackedReviewMarksAtCollapsedPosition(docBeforeStep, step.from);
if (!marks.length) return null;

// Use slice.size (content.size - openStart - openEnd) - the size ProseMirror
// actually maps the inserted range to (ReplaceStep.getMap uses slice.size). For
// an open slice (a multi-paragraph / rich-HTML collapsed paste) content.size
// overshoots, so the mark cleanup would strip trackInsert/trackDelete from the
// existing suggestion text after the paste.
return { from: step.from, to: step.from + step.slice.size };
return { from: step.from, to: step.from + step.slice.size, marks };
};

// Best-effort heuristic for labeling a content-control event's `source`. A
Expand Down Expand Up @@ -3488,17 +3508,22 @@ export class Editor extends EventEmitter<EditorEventMap> {
}
// PM mark inheritance (inclusive:false) still copies the neighbour
// suggestion's trackInsert/trackDelete/trackFormat onto a strictly-interior
// insert. Strip those marks from the inserted range (and clear them from
// stored marks) so the typed chars stay plain and the existing suggestion
// is simply split around them. Composition-meta-agnostic: deferral never
// runs in editing mode, so this normalizes both IME and non-IME inserts.
// insert. Strip ONLY those enclosing mark instances from the inserted range
// (matched by type + attrs) so the typed chars stay plain and the existing
// suggestion is simply split around them. Removing by instance - not by type -
// preserves review marks a pasted SuperDoc slice carries in (a different
// review id), which a blanket type-strip would silently drop. Stored marks are
// cleared by type so continued typing stays plain; that only affects the next
// typed char, never the already-inserted content. Composition-meta-agnostic:
// deferral never runs in editing mode, so this normalizes IME and non-IME inserts.
if (plainInsertRange) {
for (const mark of plainInsertRange.marks) {
transactionToApply.removeMark(plainInsertRange.from, plainInsertRange.to, mark);
}
const schemaMarks = prevState.schema.marks;
for (const markName of [TrackInsertMarkName, TrackDeleteMarkName, TrackFormatMarkName]) {
const markType = schemaMarks[markName];
if (!markType) continue;
transactionToApply.removeMark(plainInsertRange.from, plainInsertRange.to, markType);
transactionToApply.removeStoredMark(markType);
if (markType) transactionToApply.removeStoredMark(markType);
}
}
if (shouldTrack && forceTrackChanges && !this.options.user) {
Expand Down
2 changes: 1 addition & 1 deletion packages/superdoc/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "superdoc",
"type": "module",
"version": "1.42.0",
"version": "1.43.1",
"license": "AGPL-3.0",
"repository": {
"type": "git",
Expand Down
Loading