Skip to content

Merge main into stable - #3859

Merged
caio-pizzol merged 4 commits into
stablefrom
merge/main-into-stable-2026-08-02
Aug 2, 2026
Merged

Merge main into stable#3859
caio-pizzol merged 4 commits into
stablefrom
merge/main-into-stable-2026-08-02

Conversation

@superdoc-orbit

@superdoc-orbit superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown

Summary

  • creates merge/main-into-stable-2026-08-02 from stable
  • merges main into the candidate branch
  • opens the promotion PR to stable

Auto-created by promote-stable workflow.

Review in cubic

caio-pizzol and others added 4 commits July 31, 2026 10:55
Ported-From-Source-Repo: superdoc/orbit
Ported-From-Source-Commit: 02cc77b458655080bfeb4863c0ef55bd8373a200
Ported-Public-Prefix: superdoc/public
…hen (#1139)

Co-authored-by: Artem Nistuley <artem@superdoc.dev>

Ported-From-Source-Repo: superdoc/orbit
Ported-From-Source-Commit: d91ef133c6e77551d777df5007250be7d5e846c0
Ported-Public-Prefix: superdoc/public
* fix(release): stop V1 claiming the npm dist-tags owned by V2

`superdoc` is published to one npm package name by two release lines that
do not coordinate. Both claimed `latest` and `next`, and npm dist-tags are
last-write-wins, so whichever line published most recently owned them. V1
publishes more often, so V1 won: it took `latest` back on 30 Jul via a
stable release, and `next` on 31 Jul via a push to main, 24 minutes after
V2 had published there.

Tag ownership is now explicit. V2 keeps `latest` and `next`; V1 becomes a
maintenance line under `legacy`. The V1 stable lane stays automatic, so
maintenance releases still ship without manual work — only the tag they
land on changes.

Three separate paths could reach npm, and all three had to agree. The
release config sets the channel, the stable orchestrator's recovery derives
a tag from the version string alone, and the release workflow ran
semantic-release on every push to main. Removing the push trigger alone
would have left a manual dispatch able to cut a real release, so that
workflow now publishes `pr-<number>` previews and nothing else.

The guard encodes all five invariants and fails closed in the mirror-check
lane that already runs on every PR. It rejects the pre-fix state on all six
counts, so it would have caught this before it reached the registry.

* fix(release): close three false-pass gaps in the tag-ownership guard

Each invariant checked that some text existed rather than that the
behaviour was right, so three configurations passed the guard while still
publishing V1 to a tag V2 owns.

The stable channel check looked for `legacy` anywhere in the config, so a
config mapping stable to `canary` while some maintenance branch carried
`legacy` passed. It now parses branch objects and asserts the mapping.

The preview workflow check rejected push triggers and semantic-release but
never required a dist-tag. `publish-superdoc.cjs` defaults to `latest`, so
a dispatch-only workflow running it bare would have taken `latest` on the
next preview. Every invocation must now carry an explicit
`pr-${{ inputs.pr_number }}`, and pr_number must be required and numeric.

The recovery check only looked for `stableDistTag: 'legacy'` in the
descriptor, which proves nothing on its own: dropping the `pkg` argument at
a call site restores the `latest` fallback and leaves the descriptor
untouched. The resolver moves to its own module so it can be imported and
tested directly — release-local-stable.mjs runs the release loop at import
time and cannot be — and the guard now asserts both call sites forward the
package and that the shared module is used rather than a local copy.

All three are covered by regression tests built from the configurations
that reproduced them. The guard now reports nine violations against pre-fix
main, up from six.

Both new test files run in the mirror-check lane. release-local.test.mjs is
not wired into CI, which is how its five pre-existing failures went unseen;
that is left alone here rather than widened into this change.

* fix(release): keep the scoped mirror on latest and close four guard bypasses

The scoped mirror was collateral damage from the tag split. Codex caught it:
`publish-superdoc.cjs` passed one dist-tag to both `superdoc` and
`@harbour-enterprises/superdoc`, so routing V1 stable to `legacy` would have
taken the scoped package's `latest` with it. That package is V1-only —
nothing else advances it — so its `latest` would have frozen at 1.45.1 and
default installs would have silently stopped updating. The two names now
resolve their stable tag independently; previews and prereleases still match
under both.

Writing that test surfaced a temporal dead zone: `scopedTagFor` sat below the
`require.main` block that `parseArgs` runs from, so every direct invocation
threw "Cannot access before initialization" — the path release recovery uses.
Moved above its first reference and covered by a test.

Four guard bypasses, each reproduced before fixing. `pr_number` validation
matched `required:`/`type:` anywhere in the trigger block, so a required
numeric sibling input satisfied an optional string `pr_number`; it now parses
that input's own block. The recovery audit accepted any number of safe calls,
so one site could hardcode `latest` while the other vouched for it; it now
asserts both named assignments resolve through the shared helper. The branch
parser scanned to the next `name:` token rather than the object boundary, so
a later object's channel was read as stable's; it now matches braces. And the
workflow audit inventoried only `publish-superdoc.cjs`, so a direct
`dist-tag add` could reclaim a tag beside a correctly tagged preview.

Guard now reports ten violations against pre-fix main, up from nine.

Qodo also flagged `superdoc` in the workflow title as a naming violation.
Not taken: the sibling release workflows use the lowercase package name the
same way, and it refers to the npm package rather than the product.

Note: this ports only the public subtree changes from a mixed source commit (8 public paths, 5 non-public paths ignored).

Ported-From-Source-Repo: superdoc/orbit
Ported-From-Source-Commit: c4447f0b00bc324edb5e39cfe0cb557bd6796e8c
Ported-Public-Prefix: superdoc/public
@superdoc-orbit
superdoc-orbit Bot requested a review from a team as a code owner August 2, 2026 22:44
@mintlify

mintlify Bot commented Aug 2, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
SuperDoc 🟢 Ready View Preview Aug 2, 2026, 10:45 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

I wasn't able to get the ecma-spec MCP tools authorized in this session (each call returned a pending-permission error), so I verified the relevant elements against ECMA-376 from knowledge. Here's the review.


Status: PASS

This PR is a behavior fix on the import (XML → ProseMirror) side of the w:ins/w:del handlers, and it doesn't touch OOXML element or attribute vocabulary at all — no new attributes are emitted, no defaults changed, and no element names invented.

What it actually changes: previously the tracked-change mark (trackInsert/trackDelete) was only stamped onto content[0] of each encoded run, and only if that first child was text. A run that begins with an inline atom (e.g. <w:noBreakHyphen/>) before its text lost tracking on the atom and everything after it. The new applyTrackedMarkToRunContent helper walks every content child and marks each one whose type is in a whitelist.

On spec grounds this all checks out:

  • w:noBreakHyphen and w:t — the two members of the new TRACKABLE_RUN_CONTENT_TYPES whitelist — are both legal run inner-content children (EG_RunInnerContent), so widening the marking to cover a leading noBreakHyphen is faithful to what a run can legitimately contain. See https://ooxml.dev/spec?q=noBreakHyphen.
  • w:ins / w:del (CT_RunTrackChange) attributes (id, author, date) are untouched — the code just threads through the already-parsed encodedAttrs. No required attribute is dropped and no phantom attribute is added. See https://ooxml.dev/spec?q=ins and https://ooxml.dev/spec?q=del.
  • The conservative whitelist (deliberately excluding tab etc., with a test asserting tab stays unmarked) is the right call: it avoids attaching track-change marks to content children whose decode/export path doesn't yet consult those marks, which would otherwise risk dropping tracked metadata on round-trip. The doc comment tying the whitelist to the decode-side branches is good hygiene.

One thing worth flagging as a non-blocking note rather than a violation: the w:del fixture derives deleted runs by converting inserts to <w:del>/<w:delText>. That's correct — deleted run text must use w:delText, not w:t — but that concern lives on the export/decode side, which this PR doesn't modify. The import whitelist keying on the PM text node type is agnostic to whether the source was w:t or w:delText, so it's fine.

The rest of the diff (release workflow / dist-tag plumbing, docs pin regex) is unrelated to OOXML.

If you want the spec assertions machine-verified rather than knowledge-based, grant the mcp__ecma-spec__* tool permissions and I'll re-run the EG_RunInnerContent children and w:ins/w:del attribute lookups to confirm.

@caio-pizzol
caio-pizzol merged commit 3a07e45 into stable Aug 2, 2026
61 checks passed
@caio-pizzol
caio-pizzol deleted the merge/main-into-stable-2026-08-02 branch August 2, 2026 23:10
@superdoc-orbit

superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown
Author

🎉 This PR is included in superdoc-cli v0.22.2

The release is available on GitHub release

@superdoc-orbit

superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown
Author

🎉 This PR is included in superdoc-sdk v1.21.3

@superdoc-orbit

superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown
Author

🎉 This PR is included in @superdoc-dev/mcp v0.17.3

The release is available on GitHub release

@superdoc-orbit

superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown
Author

🎉 This PR is included in superdoc v1.45.2

The release is available on GitHub release

@superdoc-orbit

superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown
Author

🎉 This PR is included in @superdoc-dev/react v1.16.2

The release is available on GitHub release

@superdoc-orbit

superdoc-orbit Bot commented Aug 2, 2026

Copy link
Copy Markdown
Author

🎉 This PR is included in vscode-ext v2.17.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants