feat(workbench): rebase onto main#1110
Conversation
Co-authored-by: Josh <joshua.ellis18@gmail.com> fix(workbench): allow for a dynamic port (#830)
) * feat(dev): forward CLI config organization id to workbench runtime * chore: update auto-generated changeset for PR #905 --------- Co-authored-by: ecospark[bot] <ecospark[bot]@users.noreply.github.com>
Co-authored-by: Gustav Hansen <gustav.hansen@sanity.io>
…913) Pass `reactRefreshHost` to `@vitejs/plugin-react` so federated Studio modules connect their react-refresh preamble to the workbench host, enabling component-level HMR across the module federation boundary. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(dev): disable strict ports for applications * chore: update auto-generated changeset for PR #930 * fix: format * fix: format * chore: update tests --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(workbench): propagate staging env to workbench dev server The workbench dev server was missing the `__SANITY_STAGING__` Vite define that the app/studio dev servers receive via `getViteConfig`. This meant `SANITY_INTERNAL_ENV=staging` had no effect on the workbench client bundle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: update auto-generated changeset for PR #964 --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* fix(workbench): externalize sanity and @sanity/workbench * chore: update auto-generated changeset for PR #971 * chore: exclude .github from oxfmt format check Co-authored-by: Gustav Hansen <gu-stav@users.noreply.github.com> * fix: revert update changeset --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Gustav Hansen <gu-stav@users.noreply.github.com>
Co-authored-by: Gustav Hansen <gu-stav@users.noreply.github.com> Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
* feat(init): add promt for federation * chore: update auto-generated changeset for PR #988 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* fix: types * chore: update auto-generated changeset for PR #989 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(workbench): extend local application payloads * fix: types * fix: pr feedback * chore: improve tests * fix: concise * fix: pr feedback
* feat(init): use `workbench` dist-tag for `sanity` package * chore: update auto-generated changeset for PR #992 * test: add unit tests --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* fix(init): do not resolve dist tags * chore: update auto-generated changeset for PR #1000 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* feat(dev): extract studio manifest and pass it for local applications * chore: update auto-generated changeset for PR #997 * fix: rework to use manifests for both * chore: update auto-generated changeset for PR #997 * fix: cleanup * chore: share cache dir constant * feat: extract manifest in background * fix: path resolution on windows * fix: pr feedback * fix: pr feedback --------- Co-Authored-By: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
* fix(workbench): remove warmup for dependencies * chore: update auto-generated changeset for PR #1047 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Adds `--federation` / `--no-federation` flag to `sanity init` and wires it through `initAction` so the value is passed to `initApp` / `initStudio` alongside the federation prompt added in #988. The flag plumbing was previously part of the rebase merge that resolved feat/workbench against main, and was dropped in the latest rebase.
* fix(workbench): prune stale lock files * fix: add back * chore: update auto-generated changeset for PR #1057 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(workbench): detect PID reuse on Windows via PowerShell * chore: update auto-generated changeset for PR #1067 * chore(changeset): rewrite changeset summary as user-facing description Co-authored-by: Rune Botten <runeb@users.noreply.github.com> * chore: update auto-generated changeset for PR #1067 --------- Co-authored-by: squiggler-app[bot] <265501495+squiggler-app[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Rune Botten <runeb@users.noreply.github.com>
After rebasing onto main: - buildStudio.ts: plumb `federation` through `InternalBuildOptions` so the `!options.federation?.enabled` guard and the `federation` prop passed to `buildStaticFiles` resolve. Mirrors the same plumbing already done in buildApp.ts during the rebase. - buildStaticFiles.test.ts: `copyDir`/`writeFavicons` moved to `@sanity/cli-build/_internal` in main's #1062 refactor — point the mock at the new path. - startStudioDevServer.test.ts: `checkStudioDependencyVersions` moved to `@sanity/cli-build/_internal`; `getLocalPackageVersion` moved to `@sanity/cli-core` (main's #1062 and #1053). Update mocks accordingly.
|
Claude finished @gu-stav's task in 5m 59s —— View job ReviewBoth Bugbot findings are real. A couple of additional items below. 1.
|
📦 Bundle Stats —
|
| Metric | Value | vs main (5b4d3c0) |
|---|---|---|
| Internal (raw) | 2.1 KB | - |
| Internal (gzip) | 799 B | - |
| Bundled (raw) | 10.97 MB | -28 B, -0.0% |
| Bundled (gzip) | 2.06 MB | -8 B, -0.0% |
| Import time | 798ms | +16ms, +2.0% |
bin:sanity
| Metric | Value | vs main (5b4d3c0) |
|---|---|---|
| Internal (raw) | 1023 B | - |
| Internal (gzip) | 486 B | - |
| Bundled (raw) | 9.84 MB | - |
| Bundled (gzip) | 1.77 MB | - |
| Import time | 2.26s | +400ms, +21.5% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-core
Compared against main (5b4d3c08)
| Metric | Value | vs main (5b4d3c0) |
|---|---|---|
| Internal (raw) | 97.9 KB | +1.8 KB, +1.8% |
| Internal (gzip) | 23.1 KB | +634 B, +2.7% |
| Bundled (raw) | 21.63 MB | +1.5 KB, +0.0% |
| Bundled (gzip) | 3.43 MB | +594 B, +0.0% |
| Import time | 752ms | -1ms, -0.2% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — create-sanity
Compared against main (5b4d3c08)
| Metric | Value | vs main (5b4d3c0) |
|---|---|---|
| Internal (raw) | 908 B | - |
| Internal (gzip) | 483 B | - |
| Bundled (raw) | 931 B | - |
| Bundled (gzip) | 491 B | - |
| Import time | ❌ ChildProcess denied: node | - |
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 007a278. Configure here.
| - name: Publish snapshot packages | ||
| if: ${{ inputs.forceBump == 'false' }} | ||
| run: pnpm changeset publish --tag "$DIST_TAG" 2>&1 | tee publish-output.txt | ||
| run: pnpm changeset publish --tag "workbench" 2>&1 | tee publish-output.txt |
There was a problem hiding this comment.
Snapshot publish ignores user-provided dist-tag input
Medium Severity
The pnpm changeset publish command hardcodes --tag "workbench" instead of using the $DIST_TAG environment variable (which is still set from inputs.tag on the next line). Any workflow_dispatch invocation with a custom tag value will be silently ignored, and packages will always be published under the workbench dist-tag. The forceBump input definition also remains but all steps that referenced it were removed, making it dead configuration.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 007a278. Configure here.
| outputDir, | ||
| reactCompiler, | ||
| sourceMap, | ||
| }) |
There was a problem hiding this comment.
Federation build path omits typegen config from vite
Low Severity
When federation?.enabled is true, the call to getViteConfig omits schemaExtraction and typegen options. Inside getViteConfig, these are part of sharedPlugins and are conditionally included based on ?.enabled. Since they default to undefined, the plugins are silently excluded from federation builds even when the user has enabled them in their CLI config. The non-federation path correctly forwards both options.
Reviewed by Cursor Bugbot for commit 007a278. Configure here.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Coverage Delta
Comparing 40 changed files against main @ Overall Coverage
|


Rebase of #907 (
feat/workbench) onto currentmain. Opened as a separate branch so the result is reviewable before force-pushing back tofeat/workbench.Conflicts resolved
buildApp.ts/buildStudio.ts— main splitbuildApp/buildStudiointo thin entry +internalBuild*. PlumbedfederationthroughInternalBuildOptionsso the federation guard and the prop passed tobuildStaticFilesstill work.buildStaticFiles.ts/getViteConfig.ts— dropped workbench's localwriteFavicons/readPackageUpimports; main movedwriteFavicons/copyDirto@sanity/cli-build/_internaland replacedreadPackageUpwithgetDefaultFaviconsPath.cli-core/_exports/index.ts— kept bothgetLocalPackageVersion(moved into cli-core on main, refactor: Move getLocalPackageVersion to cli-core #1053) andgetSanityConfigDir(added by workbench).getViteConfig.test.ts— rewrote the "cannot resolve sanity package" test to mockgetDefaultFaviconsPathrejecting, since the underlyingreadPackageUpcall moved to@sanity/cli-build.buildStaticFiles.test.ts/startStudioDevServer.test.ts— updated mocks to the new paths (@sanity/cli-build/_internal,@sanity/cli-core).pnpm-lock.yaml— regenerated viapnpm install.Validation
pnpm build✅pnpm check:types✅pnpm check:lint✅ (0 errors)pnpm test— only failures are the pre-existingTypeError: stream.getWindowSize is not a functionflake incheckForUpdates.test.ts/users/list.test.ts, also reproducible onorigin/main.Once approved, the result can be force-pushed back to
feat/workbench.Note
Medium Risk
Touches CLI build and
sanity devorchestration paths, including Vite config generation and process/lockfile handling, which can affect local dev startup and build output across platforms.Overview
Adds experimental federation support to the CLI config (
federation.enabled) and plumbs it throughbuild/devflows.When federation is enabled,
buildStaticFilesswitches to building the federation environment via Vite’screateBuilder(skipping runtime generation, static copies, favicons, and auto-updates import maps) while still applying user Vite config/plugins.sanity devis reworked to optionally start a singleton workbench dev server, bump the app/studio port when needed, wirereactRefreshHost, register running servers into a per-user registry/lock under~/.sanity{-staging}/, and watch config/manifests for updates (with Windows PID-reuse detection). Also updates snapshot-release workflow tagging, bumps@sanity/federation, and adds a newfederated-studiofixture plus extensive new tests.Reviewed by Cursor Bugbot for commit fcf69a8. Bugbot is set up for automated code reviews on this repo. Configure here.