Merge main into stable - #3857
Conversation
Moving a demo or example directory breaks every GitHub link already published, because GitHub only leaves redirects behind for repository renames, not for paths inside a repository. Today the only fix is a stub README left at the old path, and seven of those already exist. This adds a `slug` field to catalog entries: the permanent public name a demo is reachable by at go.superdoc.dev, independent of where its source currently lives. It stays separate from `id` because `id` is the internal catalog key and should stay free to follow section renames, while a public slug cannot move without breaking links we do not control. Slugs are opt-in, so nothing is published until it has earned a permanent name, and 26 entries are named here to start. The validator rejects duplicates, non-kebab-case names, names that would shadow a service route, and slugs on entries we have deliberately withdrawn. The service that serves those URLs is superdoc/linkkeeper, a separate project. It reads these manifests directly, so publishing an example is just the slug edit and there is no second list to keep in sync. The workflow added here only tells it when the catalog changed, and it lives in the public repo rather than in Orbit's export pipeline: the export pushes straight to public main, so by then the manifests are already public and the SHA is the exported one. The catalog had no CI gate on this branch, so metadata validation now runs in its own fast workflow rather than inside the demo build. Note: this ports only the public subtree changes from a mixed source commit (12 public paths, 2 non-public paths ignored). Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: ef3e82021629254753918e6b0ad8d9c3d54c0d4f Ported-Public-Prefix: superdoc/public
The first production deploy built all 26 links and verified every destination, then failed on the upload: npm error Unsupported URL Type "catalog:": catalog: The Cloudflare action installs wrangler with `npm i wrangler@4`. Run from `go-links/`, which had no `package.json`, npm walked up to the repository root and tried to read a pnpm workspace manifest full of `catalog:` versions it cannot parse. A minimal private `package.json` in `go-links/` stops that walk. It declares no dependencies and matches no `pnpm-workspace.yaml` glob, so pnpm ignores it and the workspace is unaffected. Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 49026202fad233ec13ec3cfe3a16ed037e479ac6 Ported-Public-Prefix: superdoc/public
* feat(catalog): add permanent slugs for demos and examples Moving a demo or example directory breaks every GitHub link already published, because GitHub only leaves redirects behind for repository renames, not for paths inside a repository. Today the only fix is a stub README left at the old path, and seven of those already exist. This adds a `slug` field to catalog entries: the permanent public name a demo is reachable by at go.superdoc.dev, independent of where its source currently lives. It stays separate from `id` because `id` is the internal catalog key and should stay free to follow section renames, while a public slug cannot move without breaking links we do not control. Slugs are opt-in, so nothing is published until it has earned a permanent name, and 26 entries are named here to start. The validator rejects duplicates, non-kebab-case names, names that would shadow a service route, and slugs on entries we have deliberately withdrawn. The service that serves those URLs is superdoc/linkkeeper, a separate project. It reads these manifests directly, so publishing an example is just the slug edit and there is no second list to keep in sync. The workflow added here only tells it when the catalog changed, and it lives in the public repo rather than in Orbit's export pipeline: the export pushes straight to public main, so by then the manifests are already public and the SHA is the exported one. The catalog had no CI gate on this branch, so metadata validation now runs in its own fast workflow rather than inside the demo build. * docs(superdoc): link examples through their stable URLs Points the documentation at go.superdoc.dev for the 17 links whose targets now have a published slug. These survive the next reorganization of the examples tree; the raw GitHub paths they replace would not. Links to examples that do not have a slug yet are left alone rather than invented, so nothing here points at a URL that does not resolve. They can move over as those examples are named. Nothing else changes: same destinations, one redirect in front of them. Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 258268f8ec8ab14bb439a51ed9ec5da03279e726 Ported-Public-Prefix: superdoc/public
Renaming a published slug passed CI. The previous check was a count floor, and a rename leaves the count at 26 while the old URL stops resolving, which is exactly the failure the whole project exists to prevent. go-links/published-slugs.json now records every slug that has shipped, and the validator compares against that set: removing or renaming one is a build failure naming the slug. Publishing a new one adds a line to the same file, so the baseline cannot drift from reality unnoticed. `workflow_dispatch` let a caller choose any ref, and that job holds the credentials that publish go.superdoc.dev. A branch that had not been reviewed could have deployed redirects. The job is now fail-closed on `refs/heads/main`. Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: c8652db7afe9c17dee632804c1fa4ffc3530caa8 Ported-Public-Prefix: superdoc/public
…1023) The published-slug baseline is half of the permanence rule, but no workflow watched it. A PR touching only go-links/published-slugs.json ran no catalog validation at all, so an entry could be removed from the baseline without review, and a later PR could then drop the matching manifest slug against an already weakened baseline. Each step looks harmless; together they retire a live URL. The validator does catch the mismatch, so this is not a hole in the check. It is a check that never fired. A test asserts the workflow triggers on every file the slug rule depends on, since a missing path filter has no symptom until the day it matters. Note: this ports only the public subtree changes from a mixed source commit (2 public paths, 1 non-public path ignored). Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: bf054b4534c053b9cf03d2cbbf01adbb8c6bd274 Ported-Public-Prefix: superdoc/public
…#1024) * fix(catalog): run slug validation when the baseline itself changes The published-slug baseline is half of the permanence rule, but no workflow watched it. A PR touching only go-links/published-slugs.json ran no catalog validation at all, so an entry could be removed from the baseline without review, and a later PR could then drop the matching manifest slug against an already weakened baseline. Each step looks harmless; together they retire a live URL. The validator does catch the mismatch, so this is not a hole in the check. It is a check that never fired. A test asserts the workflow triggers on every file the slug rule depends on, since a missing path filter has no symptom until the day it matters. * feat(catalog): make slug validation a required, locally runnable lane The slug baseline only protects public URLs if the check that reads it actually runs. It was not a required check, so a pull request touching a manifest could merge without it, which made the whole permanence contract advisory. Adding it to the rulesets alone would have made things worse. The workflow filtered on `on.paths`, so it never reported on unrelated changes, and a required check that never reports blocks the pull request forever. It now runs on every pull request and in the merge queue, with a `detect` job deciding whether the real work is needed and a `validate` job that reports either way. That is the pattern ci-examples and ci-document-api already use, for the same reason. The policy also refuses `branchProtection` without a local lane, which is a good rule: a check people cannot reproduce locally is one they can only argue with. So there is now a `ci-catalog` lane, reachable through `pnpm superdoc:gate --lane ci-catalog`. It is the cheapest lane here -- reads JSON, compares it, no build or network -- so local and CI results cannot diverge, and it runs first because it fails fastest. Two lane rosters in the tests were hardcoded and are updated. Adding the context to require-ci and require-ci-v2 is the remaining step, and is a repository settings change. * refactor(catalog): drop the dependency install the lane never needed The lane described itself as network-free while its first stage ran `pnpm install --frozen-lockfile`, which is the one step in it that touches the network and can differ between machines. Both commands import only `node:` builtins, and both were verified to run with `node_modules` absent, so the install was doing nothing. Removed from the lane and from the workflow together: a lane that diverges from its CI counterpart is worse than no lane, because it teaches people the wrong thing about what CI will do. The environment note now says what is actually true rather than claiming local and CI cannot diverge, which was stronger than the evidence. Note: this ports only the public subtree changes from a mixed source commit (1 public path, 5 non-public paths ignored). Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 1d19965b10036f51bc2c3553f2ceda61a0d18132 Ported-Public-Prefix: superdoc/public
* fix(v1): preserve nested content-control parent topology * test(v1): strengthen nested SDT round-trip coverage Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 5a7401384e0d2dc0a6bdfd1375bb45614b2eb91b Ported-Public-Prefix: superdoc/public
* docs(docs): pin archived v1 packages * fix(docs): pin v1 React dependencies * fix(docs): cover scoped v1 browser URLs Ported-From-Source-Repo: superdoc/orbit Ported-From-Source-Commit: 51aac5061ce267da83581c911945950ebee7f2d7 Ported-Public-Prefix: superdoc/public
Agent docs auditFound deterministic findings on 2 changed agent-doc item(s).
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
🎉 This PR is included in superdoc-cli v0.22.1 The release is available on GitHub release |
|
🎉 This PR is included in superdoc-sdk v1.21.2 |
|
🎉 This PR is included in @superdoc-dev/mcp v0.17.2 The release is available on GitHub release |
|
🎉 This PR is included in superdoc v1.45.1 The release is available on GitHub release |
|
🎉 This PR is included in @superdoc-dev/react v1.16.1 The release is available on GitHub release |
|
🎉 This PR is included in vscode-ext v2.17.1 |
Summary
merge/main-into-stable-2026-07-30fromstablemaininto the candidate branchstableAuto-created by promote-stable workflow.