Sync stable into main#3349
Conversation
* docs(intro): tighten installation card copy * chore: retrigger docs preview workflow
* ci(release): gate production docs on stable release success Mintlify currently deploys from main, so docs ship as soon as a doc commit lands, often weeks before the underlying packages reach npm via the weekly stable release. Move production docs onto a `docs-stable` branch that the release workflow only advances after every publish step succeeds, so docs and packages move together. - release-stable.yml pushes stable -> docs-stable as its final step, only reachable on full success - new preview-stable-docs.yml triggers a Mintlify preview for any PR targeting stable so the promote-stable PR shows reviewers the exact docs that will go live - requires manual setup before this can take effect: create the docs-stable branch from current stable, switch Mintlify's deployment branch in the dashboard, and add MINTLIFY_API_KEY / MINTLIFY_PROJECT_ID repo secrets (preview workflow no-ops without them) * fix(release): gate docs-stable promote on verified release SHA Address review on PR 2989. Two issues: - The promote step refetched `origin/stable` and pushed it, so a newer commit landing on stable while the release was still publishing would be promoted to docs-stable before the next run actually published it. The orchestrator now emits `promote_sha` (current HEAD) only when no package failed and no deferral happened; the workflow gates the push on that output and pushes the explicit SHA instead of refetching. - The preview workflow called `gh pr comment` without checking out the repo, so gh had no repo context. Added `--repo "$GITHUB_REPOSITORY"`.
Doc authors who PR against main currently get no hosted preview because Mintlify's automatic previews only fire on PRs targeting the deployment branch (docs-stable) and our preview workflow only fired on PRs targeting stable. They'd only see a preview when their work reached the promote-stable PR, days later. Add main as a trigger branch so doc-touching PRs to main get an instant preview URL. Path filter on apps/docs, document-api contract, and the generator script keeps the 5 req/min Mintlify API quota from being spent on unrelated code PRs. The path filter also applies to stable PRs but that's fine: promote-stable PRs always include docs, and code-only stable hotfixes don't need a docs preview.
The previous gate `action == 'opened'` skipped the comment whenever the workflow first ran on a `synchronize` event, which happens whenever the workflow file didn't exist on the base branch when the PR was opened (or on reopens). Replace it with an idempotency check that lists existing PR comments and only posts if none starts with the `📖 Docs preview:` marker.
Add a workflow that fires on docs-touching pushes to main and re-triggers Mintlify's preview for the main branch. Gives the team a persistent superdoc-main.mintlify.app URL that always reflects the current state of main, without anyone needing to open a draft PR. Production docs continue to come from docs-stable so this is purely additive.
Rename `preview-stable-docs.yml` to `docs-preview-pr.yml` (the file covered both main and stable PRs since #2992, so the old name was misleading) and `refresh-main-docs-preview.yml` to `docs-preview-main.yml`. Both now share the `docs-preview-` prefix so they sort together in the Actions UI, with display names "📖 Docs preview (PR)" and "📖 Docs preview (main)". Production promotion stays as a step inside release-stable.yml since it's gated on the orchestrator's `promote_sha` output and benefits from sharing a job with the release steps.
Based on the detailed commit messages and code exploration, here are the release notes for v2.6.0: ### What's New - **Tracked changes in headers and footers** — Track insertions, deletions, and formatting changes across all document parts; story-aware operations let agents accept or reject changes in headers and footers via `trackChanges.get()` and `trackChanges.decide()` with a `story` parameter. - **Bookmark rendering and navigation** — Opt-in visual indicators (`[` and `]` brackets) for bookmark positions; auto-generated bookmarks (`_Toc…`, `_Ref…`) remain hidden; toggle via `setShowBookmarks()` at runtime. - **Cross-reference import and navigation** — REF, NOTEREF, STYLEREF, and PAGEREF fields import as clickable cross-references; PAGEREF with `\h` switch generates hyperlinks that navigate to the referenced bookmark on click. - **Paragraph property tracked changes** — Full support for `w:pPrChange` translator to track changes to alignment, indentation, borders, and other paragraph formatting; round-trip preserves empty `w:pPr` elements correctly. - **Document extract API returns tables as blocks** — `doc.extract()` emits one block per paragraph inside table cells instead of flattening tables to text; blocks tagged with `tableContext` (rowIndex, columnIndex, rowspan, colspan) so consumers can reconstruct cells, rows, or tables; enables RAG chunking and `scrollToElement()` citations on table content. ### Fixes - TOC and document-part section breaks now emit correctly on page boundaries. - Header and footer undo history persists across story editing sessions. - Tracked changes render correctly in headers and footers even when decoration items are omitted. - Section breaks for empty inline newlines no longer drop breaks or shift ProseMirror positions downstream. - Footnote editing lag eliminated; active note sessions flush before DOCX export. - Paragraph list rendering no longer crashes when `listRendering` is null. - Header and footer formatting now applies correctly. - DOCX export corruption prevented for legacy `w:pict` VML rect content. - Toolbar responsiveness improved with correct resize-observer breakpoints. - Fragment geometry changes trigger rebuild correctly. ### Improvements - Painter refactored to read exclusively from resolved layout data, removing legacy block lookup fallback and reducing paint-time surface area. - TOC handling unified via `processTocChildren` — direct `tableOfContents` nodes and `documentPartObject` TOC gallery now share the same code path. - Header and footer resolution data preserved per-page. - Paragraph and list-item block/measure data pre-computed in resolved layout stage. - Anchor navigation (TOC clicks and cross-reference navigation) scrolls to the correct scroll container, not just the visible host.
### What's New - **Tracked changes in headers and footers** — Story-aware operations let you track insertions, deletions, and formatting changes across all document parts. Accept or reject changes in any header, footer, or body section with one API call. - **Bookmark rendering and navigation** — Visual indicators mark bookmark positions (`[` and `]` brackets, matching Word's show-bookmarks behavior). Auto-generated bookmarks stay hidden. Toggle at runtime via `setShowBookmarks()`. - **Cross-reference import and navigation** — REF, NOTEREF, STYLEREF, and PAGEREF fields now import as clickable cross-references. PAGEREF with `\h` switch generates hyperlinks; clicks navigate to the referenced bookmark. - **Paragraph property tracked changes** — w:pPrChange translator fully supports tracked changes to alignment, indentation, borders, and other paragraph properties. Round-trip preserves empty w:pPr elements correctly. - **Document extract API returns tables as blocks** — `doc.extract()` now emits one block per paragraph inside table cells instead of flattening to text. Blocks carry `tableContext` so you can group back to cell, row, or table. RAG chunking and `scrollToElement` citations work on table content. - **Math equation converters** — Full OMML-to-MathML support for radical/sqrt, group character, phantom, n-ary operators, equation arrays, accents, pre-subscripts, limit operators, matrices, and bordered boxes. Word mathematical expressions render as web-standard MathML. - **CDN IIFE bundle** — Distribute superdoc.min.js with `window.SuperDoc` global. Bundle size reduced 44%: 8.8 MB unminified → 4.9 MB minified (1.46 MB gzipped). Yjs and Hocuspocus inlined; pdfjs-dist stays external. - **Document API enhancements** — `doc.extract()` returns all content with stable IDs for RAG workflows. `contentControls.create()` accepts `at` field to wrap arbitrary text ranges. Every extracted ID works with `scrollToElement()` for citation navigation. - **Toolbar headless API** — Unified `state()` and `execute()` methods for headless toolbar. Toolbar automatically synchronizes with document-mode changes. - **Odd/even header-footer support** — Full w:evenAndOddHeaders support. Paginator selects correct header/footer variant per page. Margin calculation respects different odd and even page heights. - **Track changes revision models** — Add `replacements: 'paired' | 'independent'` to `modules.trackChanges`. Paired (Google Docs–like) groups insertion+deletion as one change. Independent (Word–like) treats each as separate, independently resolvable. - **Column line separators** — Render separator lines between columns. Handles continuous section breaks that change column layout mid-page. - **Word-level text diffing** — Granular change representation during editing. Track changes now show exactly which words changed. - **Tab character handling in text insertion** — Text insert now converts tab characters to tab nodes during insertion. Tab nodes skip when parent disallows them (e.g., total-page-number); raw tab text is preserved instead. ### Improvements - **Painter refactored to resolved layout** — Painter reads exclusively from resolved layout data, removing legacy block lookup fallback and reducing paint-time surface area. - **TOC handling unified** — Direct `tableOfContents` nodes and `documentPartObject` TOC gallery now share the same code path via `processTocChildren`. Section-range counting stays consistent across both paths. - **Header and footer resolution data** — Per-page resolution data preserved, enabling correct rendering when decoration items are omitted. - **Paragraph and list-item pre-computation** — Block/measure data pre-computed in resolved layout stage instead of at paint time. - **Text layout and selection parity** — availableWidth now calculated consistently across resolver, painter, selection, and hit-testing. Justified paragraphs with first-line/hanging indents no longer show overlapping text. Centered and right-aligned inline images in indented paragraphs render at correct positions. - **CSS isolation** — Wrap all bundled SuperDoc CSS in `@layer superdoc` cascade layer. Consumer CSS always wins over SuperDoc styles regardless of import order. - **Type system narrowing** — `exportDocx()` default return type narrowed — browser consumers get `Promise<Blob>` automatically; Node headless consumers opt in with `exportDocx<Buffer>()`. - **Toolbar responsiveness** — Resize observer and container-aware overflow cutoffs now function at correct breakpoints. ### Fixes - TOC and document-part-object section breaks emit correctly on page boundaries — section properties stored inside or before a TOC SDT no longer shift content to the wrong page. - Header and footer undo history persists across story editing sessions. - Tracked changes render correctly in headers and footers even when decoration items are omitted. - Section breaks for empty inline newlines no longer drop breaks or shift ProseMirror positions downstream. - Footnote editing lag eliminated; active note sessions flush before DOCX export. - Paragraph list rendering no longer crashes when `listRendering` is null. - Header and footer formatting now applies correctly. - DOCX export corruption prevented for legacy w:pict VML rect content. - Footnote fragments stay within reserved band — multiple footnotes on a single page no longer render past the bottom page margin. - Centered image positioning now accounts for paragraph indents. - Table cell hit-testing works correctly for multi-block cells spanning pages. - List marker width adjustments use consistent measured text width signal. - Documents opened in collaboration no longer corrupt after export. - settings.xml and custom XML parts now persist after export on collaborative sessions. - Endnotes round-trip correctly on export. - Watermark layout and imported comment metadata handled correctly. - Comment bubble text replacement displays correctly in tracked changes. - Selection rectangles render correctly in headers and footers. - Math character splitting matches Word — multi-character runs split per-character; operators and digits group correctly. Italic preserved on variables inside function-wrapped limits. - Tab stops in TOC styles compute and align correctly. - React prop stabilization prevents re-init flicker when consumers pass inline object literals. - Serif fallback works for serif-like fonts. - Table cell selection with context menu works in collaboration mode. - Images are contained within table cells. - Cross-reference and PAGEREF clicks navigate to bookmarks correctly. - Even/odd header variants select based on document page number (not section-relative). - Cursor placement works correctly inside tracked change regions. - Track change bubbles resync correctly on peer undo/redo in collaboration.
### What's New - **Tracked changes in headers and footers** — Story-aware operations track insertions, deletions, and formatting changes across all document parts. Agents can now manipulate tracked changes in headers and footers the same way they work with body content. - **Bookmark rendering and navigation** — Opt-in visual indicators show bookmark positions with `[` and `]` brackets (matching Word's behavior). Auto-generated bookmarks stay hidden. Toggle at runtime via `setShowBookmarks()`. - **Cross-reference fields import as clickable links** — REF, NOTEREF, STYLEREF, and PAGEREF fields now import as interactive cross-references. PAGEREF with `\h` switch generates navigable hyperlinks. - **Paragraph property tracked changes** — Full support for `w:pPrChange` translator. Round-trips preserve empty `w:pPr` elements correctly. Track alignment, indentation, borders, and other paragraph properties. - **Document extract API returns tables as blocks** — `doc.extract()` now emits one block per paragraph inside table cells instead of flattening tables to text. Blocks tagged with `tableContext` so you can reconstruct cell, row, or table grouping. RAG chunking and `scrollToElement` citations now work on table content. ### Fixes - TOC and section breaks now emit correctly on page boundaries — section properties no longer shift content to the wrong page. - Header and footer undo history persists across story editing sessions. - Tracked changes render correctly in headers and footers even when decoration items are omitted. - Section breaks for empty inline newlines no longer drop breaks or shift ProseMirror positions downstream. - Footnote editing lag eliminated — active note sessions flush before DOCX export. - Paragraph list rendering no longer crashes when `listRendering` is null. - Header and footer formatting applies correctly during export. - DOCX export corruption prevented for legacy `w:pict` VML rect content. - Toolbar resize observer and container-aware overflow cutoffs now function at correct breakpoints. - Fragment geometry changes trigger rebuild correctly. ### Improvements - Painter refactored to read exclusively from resolved layout data — removes legacy block lookup fallback, reducing paint-time surface area. - TOC handling unified via `processTocChildren` — direct `tableOfContents` nodes and `documentPartObject` TOC gallery now share the same code path. - Header and footer resolution data preserved per-page. - Paragraph and list-item block and measure data pre-computed in resolved layout stage.
vscode-ext's webview imports `superdoc`, which esbuild resolves through `node_modules/superdoc/dist/`. The main release flow builds that via the root `pnpm run build` step before any per-package work runs, but the recovery path runs `pnpm install` in a temp worktree and never builds the workspace, so `vsce package` fails to bundle the webview ("Could not resolve 'superdoc/style.css'"). Mirror the main flow by running a workspace build before the recovery package step when not at REPO_ROOT.
Co-authored-by: Artem Nistuley <artem@superdoc.dev>
…le_stable fix: sdt field style (SD-2744)
### Fixes - **Structured Document Tag styling** — SDT field wrappers now stay synced with text font size, keeping borders and padding correct as document text changes.
### Fixes - **Structured Document Tag field styling** — SDT field wrappers now stay synced with text font size changes, keeping borders and padding correct as document text is edited.
### Fixes - **Structured Document Tag field styling** — SDT field wrappers now stay synced with text font size, so borders and padding remain correct when document text size changes.
### Fixes - **Structured Document Tag field wrapper styling** — SDT field borders and padding now stay synced with text font size as document text changes, maintaining proper visual alignment through typography edits.
Co-authored-by: Artem Nistuley <artem@superdoc.dev> Co-authored-by: Caio Pizzol <97641911+caio-pizzol@users.noreply.github.com>
…-template-builder_stable feat: add presetContent for template builder (SD-2548)
### What's New - **presetContent for block fields** — Prefill block fields with structured content using HTML or ProseMirror JSON. Insert a field configured with a sample table, checklist, or custom layout in a single action. Useful for templates that need consistent structure across instances.
Merge main into stable
### What's New
**UI Controller** — `createSuperDocUI({ superdoc })` gives you a browser-side state controller for building custom sidebars, toolbars, and selection-driven UIs without reaching into editor internals. Select any slice of state (selection, toolbar, comments, tracked changes, viewport geometry) and subscribe.
**React hooks** — `SuperDocUIProvider`, `useSuperDocUI`, `useSuperDocSlice`, `useSuperDocSelection`, `useSuperDocComments`, `useSuperDocReview`, `useSuperDocToolbar`, and `useSuperDocCommand` eliminate per-project glue code. Provider creates one controller per app, handles cleanup, no stale-closure bugs.
**Selection primitives** — `editor.doc.selection.current()` returns `SelectionInfo` with the active range, activeMarks, activeCommentIds, activeChangeIds — everything a floating toolbar needs. `editor.doc.selection.onChange()` subscribes to changes. No ProseMirror internals required.
**Multi-block comments** — `comments.create` now accepts `TextTarget` with multiple segments, so drag-selecting across paragraphs anchors a comment across all of them instead of silently collapsing.
**Comment reopen** — Implements the inverse of resolve. `comments.patch({ status: 'active' })` re-inserts the comment mark and removes anchor nodes, round-tripping through DOCX.
**Custom toolbar commands** — `ui.commands.register({ id, execute, getState })` adds custom buttons (AI rewrite, insert mention, internal workflows) to the same surface as built-ins. Custom state binds to external app signals via `invalidate()`.
**Tracked change anchors** — `extract()` now includes `block.textSpans` mapping each change to exact text, plus `blockIds` and `wordRevisionIds` for navigation — no more ambiguous excerpts when words repeat.
**Selection.capture()** — Freeze addressable selection when a composer opens (before focus shifts). Pass the captured target directly to `comments.create` on submit.
**ui.viewport.getRect()** — Get rects for sticky cards anchored to comments or changes. Returns success/failure with reason (not-ready, invalid-target, unresolved, not-mounted).
**Extra bullet styles** — Square and circle bullets alongside disc (default).
### Improvements
**Selection in state** — `ui.select(s => s.selection, ...)` now exposes `target`, `activeMarks`, `activeCommentIds`, `activeChangeIds` alongside `empty` and `quotedText`. One subscription covers floating-menu, format-toolbar, and mention-popover needs.
**Per-command observables** — `ui.commands.bold.observe(({ active, disabled }) => ...)` lets a 50-button toolbar re-render only the changed button instead of the whole bar.
**Toolbar command routing** — All dispatch paths (per-id, per-command, aggregate) use the same resolver so custom overrides (`register({ override: true })`) apply everywhere.
**Viewport scrolling** — `editor.doc.ranges.scrollIntoView({ target, block?, behavior? })` handles paginated/virtualized layouts, mounts pages on demand, works for text or entity targets (comment/change by id).
**Host-routed decisions** — Tracked change accept/reject routes through the document host editor (not child editors), so decisions apply document-wide.
**Story-aware scroll** — `ui.comments.scrollTo()` and `ui.review.scrollTo()` preserve story metadata so non-body comments (headers, footers, notes) anchor correctly.
**Reviewer merge & split** — Lists can merge adjacent items or split at a selected position via `lists.merge()` / `lists.split()`.
**Child editor telemetry** — Story editors (headers, footers, footnotes) skip document-open telemetry; only the primary editor reports.
### Fixes
**Comment activation** — Non-collapsed selections no longer flicker the active comment. Clicks on tracked changes inside comments preserve the activation.
**Line break rendering** — Manual line breaks now render faithfully in all contexts.
**Table clicks** — Clicks in table gaps no longer jump the cursor to a different page or select the wrong paragraph.
**Footer alignment** — Page numbers and footer content align correctly even with malformed spacing metadata.
**Floating textboxes** — DrawingML shapes that re-prefix namespaces (e.g. `ns6:graphic` instead of `a:graphic`) now render.
**Bullet style export** — Picking square/circle styles exports to DOCX with matching `w:lvlText` markers.
**Comments export** — Comments from Word-native range-based files export in the correct format instead of being merged incorrectly.
**Symbol font stripping** — Transitioning from bullet to ordered lists strips symbol fonts so numbered markers render without interference.
`ui.review` shipped a merged comments + tracked-changes feed with `accept` / `reject` verbs, but the merged-feed concept was speculative. No customer asked for it, and consumers building review sidebars can compose `ui.comments.items` and `ui.trackChanges.items` themselves (roughly 30 LOC, demonstrated in the BYO-UI demo's ActivitySidebar). Mirroring `editor.doc.trackChanges` keeps the controller surface tight and the layering predictable: each `ui.<domain>` namespace tracks one doc-API namespace. - `TrackChangesItem` carries only tracked changes (no `kind` discriminator) - `TrackChangesSlice` exposes `items` / `total` / `activeId` - `TrackChangesHandle` keeps `accept` / `reject` / `acceptAll` / `rejectAll` / `next` / `previous` / `scrollTo` - `useSuperDocReview` becomes `useSuperDocTrackChanges` - Demo's ActivitySidebar merges the two slices locally
### Fixes - **Formatting marks button** — now hidden by default. Set `modules.toolbar.showFormattingMarksButton: true` to show it. This gives you tighter control over toolbar layout, separate from the `layoutEngineOptions.showFormattingMarks` setting that controls whether marks render in the document.
…l-crash fix(ci): tolerate ATTW internal package-shape crash
…-stable Install SuperDoc from template-builder and eSign
### Features - install superdoc from wrapper packages ### Changes - Merge branch 'main' into nick/merge-main-stable - Merge branch 'stable' ### Chores - merge stable into main (#2997) - remove accidental breaking change wording from triggering sem rel as breaking ### CI - align release and CI triggers with package impact map (#2938)
…able fix(ci): gate stable sync on release completion
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18d6c21045
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
🎉 This PR is included in superdoc-sdk v1.10.0 |
|
🎉 This PR is included in @superdoc-dev/mcp v0.6.0 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.34.0 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.5.0 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.6.0 |
|
🎉 This PR is included in template-builder v1.11.1 The release is available on GitHub release |
|
🎉 This PR is included in esign v2.7.1 The release is available on GitHub release |
What changed
This is a manual recovery merge from
stableintomainafter thesync-patches.ymlworkflow correctly failed on real conflicts instead of opening a broken PR.The merge commit preserves stable history and tag ancestry. That is the important part for semantic-release:
origin/stableis now an ancestor of this branch, andv1.33.0/v1.33.1are reachable from the merge commit.Conflict resolution
superdoc/uiexports.comments-store.jsconflict so stable's tracked-change story metadata is included while main's unchanged-payload guard stays intact.Merge requirement
Merge this PR with Create a merge commit. Do not squash or rebase it, or the stable tag ancestry repair is lost.
Validation
git diff --cached --check.github,packages,apps,scripts,demos, andtestsnode --checkfor the resolved JS filesnode --test --test-name-pattern "stable-to-main sync|release configs suppress|stable recovery ignores|stable release workflows serialize" scripts/__tests__/release-local.test.mjsgit merge-base --is-ancestor origin/stable HEADgit tag --merged HEAD --list 'v1.33.*'returnsv1.33.0andv1.33.1I did not run a semantic-release dry-run in this worktree because it does not have
node_modulesinstalled.