Module Graph: Refactor from StoryDependencyService to open service-based ModuleGraphService#35048
Module Graph: Refactor from StoryDependencyService to open service-based ModuleGraphService#35048JReinhold wants to merge 11 commits into
Conversation
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Package BenchmarksCommit: The following packages have significant changes to their size or dependencies:
|
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 74 | 74 | 0 |
| Self size | 20.43 MB | 20.44 MB | 🚨 +13 KB 🚨 |
| Dependency size | 36.65 MB | 36.65 MB | 0 B |
| Bundle Size Analyzer | Link | Link |
@storybook/cli
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 205 | 205 | 0 |
| Self size | 908 KB | 908 KB | 🎉 -144 B 🎉 |
| Dependency size | 89.16 MB | 89.17 MB | 🚨 +13 KB 🚨 |
| Bundle Size Analyzer | Link | Link |
@storybook/codemod
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 198 | 198 | 0 |
| Self size | 32 KB | 32 KB | 🚨 +36 B 🚨 |
| Dependency size | 87.65 MB | 87.66 MB | 🚨 +13 KB 🚨 |
| Bundle Size Analyzer | Link | Link |
create-storybook
| Before | After | Difference | |
|---|---|---|---|
| Dependency count | 75 | 75 | 0 |
| Self size | 1.08 MB | 1.08 MB | 0 B |
| Dependency size | 57.08 MB | 57.09 MB | 🚨 +13 KB 🚨 |
| Bundle Size Analyzer | node | node |
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
📝 WalkthroughWalkthroughThis PR refactors change-detection to use a new ChangesModule-Graph Open-Service Implementation
ModuleGraphEngine Refactor
ChangeDetectionService Refactor
Remove Barrel Exports and Consolidate Module Structure
Dev-Server, Preset, and Docgen Integration
Normalize Import Paths and Documentation
Documentation Update
Estimated code review effort🎯 4 (Complex) | ⏱️ ~65 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
code/core/src/core-server/change-detection/change-detection.test-helpers.ts (1)
41-48: 💤 Low valueHardcoded
/repopath in test helper may cause path mismatch.The
toStoryIndexPath(storyFile, '/repo')uses a hardcoded working directory. If a test provides a differentworkingDirtocreateWiredChangeDetection, the mock's path conversion won't match the service's expectations.♻️ Consider parameterizing the workingDir
The
installModuleGraphQueryMockcould accept an optionalworkingDirparameter to align with the test's working directory, though the current approach works for existing test fixtures using/repo.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@code/core/src/core-server/change-detection/change-detection.test-helpers.ts` around lines 41 - 48, getStoriesForFiles uses a hardcoded workingDir when calling toStoryIndexPath, causing mismatches if tests call createWiredChangeDetection with a different workingDir; update the installModuleGraphQueryMock (or the helper that provides getStoriesForFiles) to accept an optional workingDir parameter and pass that through to getStoriesForFiles so toStoryIndexPath(storyFile, workingDir) is used instead of '/repo', and update any callers of installModuleGraphQueryMock in tests to forward their createWiredChangeDetection workingDir where needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@code/core/src/shared/open-service/services/module-graph/definition.ts`:
- Around line 171-176: The handlers that set or bump graphRevision (e.g., the
anonymous handler shown, applyGraphSnapshot, and bumpGraphRevision) update
state.graphRevision but do not clear state.latestChangedStoryFiles, causing
getLatestStoryChanges to return stale files; update each place that increments
or replaces the revision (the handler that sets status='ready',
applyGraphSnapshot, and bumpGraphRevision) to also reset
state.latestChangedStoryFiles to an empty collection (e.g., [] or {}) inside the
same ctx.self.setState callback so the newest revision has no leftover
changed-file entries.
In
`@code/core/src/shared/open-service/services/module-graph/engine/module-graph-engine.ts`:
- Around line 99-117: mirrorUpdate currently only uses the post-patch
reverseIndex lookup and can miss stories whose edges were removed by the patch;
change mirrorUpdate to accept (or obtain) the pre-patch dependents and union
them with the post-patch lookup results before computing bumpedStoryFiles.
Specifically, update the mirrorUpdate signature to accept an extra
prePatchDependents (Set<string> or string[]), or capture lookup(normalized)
before applying the patch in the caller and pass it in; then merge that set with
the current this.reverseIndex.lookup(normalized) results plus this.storyFiles
into bumpedStoryFiles, and keep the rest of the logic (options.onUpdate,
reverseIndexToStoriesByFile, toStoryIndexPath) unchanged so both pre- and
post-patch dependents are included.
- Around line 237-239: Register the adapter.onStartupFailure handler before
performing any async startup work so early failures aren't missed: move the
attachment of adapter.onStartupFailure?.(...) to occur before calling
getResolveConfig(), getIndex(), or build(), and ensure it forwards event.reason
and event.error to this.options.onUnavailable so any startup error during those
async calls will be emitted.
---
Nitpick comments:
In `@code/core/src/core-server/change-detection/change-detection.test-helpers.ts`:
- Around line 41-48: getStoriesForFiles uses a hardcoded workingDir when calling
toStoryIndexPath, causing mismatches if tests call createWiredChangeDetection
with a different workingDir; update the installModuleGraphQueryMock (or the
helper that provides getStoriesForFiles) to accept an optional workingDir
parameter and pass that through to getStoriesForFiles so
toStoryIndexPath(storyFile, workingDir) is used instead of '/repo', and update
any callers of installModuleGraphQueryMock in tests to forward their
createWiredChangeDetection workingDir where needed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f503b29f-7eea-4d79-b10d-fd9b95ebf43f
📒 Files selected for processing (47)
code/core/src/core-server/change-detection/active-service-registry.tscode/core/src/core-server/change-detection/adapters/index.tscode/core/src/core-server/change-detection/change-detection-service.test.tscode/core/src/core-server/change-detection/change-detection-service.tscode/core/src/core-server/change-detection/change-detection.test-helpers.tscode/core/src/core-server/change-detection/dependency-graph/index.tscode/core/src/core-server/change-detection/index.tscode/core/src/core-server/change-detection/parser-registry/index.tscode/core/src/core-server/dev-server.tscode/core/src/core-server/index.tscode/core/src/core-server/presets/common-preset.tscode/core/src/core-server/utils/index-json.test.tscode/core/src/core-server/utils/index-json.tscode/core/src/shared/open-service/README.mdcode/core/src/shared/open-service/services/docgen/server.test.tscode/core/src/shared/open-service/services/docgen/server.tscode/core/src/shared/open-service/services/module-graph/definition.tscode/core/src/shared/open-service/services/module-graph/engine/adapters/types.test.tscode/core/src/shared/open-service/services/module-graph/engine/adapters/types.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/dependency-graph-builder.test.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/dependency-graph-builder.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/incremental-patch.test.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/incremental-patcher.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/parse-resolve-cache.test.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/parse-resolve-cache.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/resolver-factory.test.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/resolver-factory.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/reverse-index.test.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/reverse-index.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/scope.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/types.tscode/core/src/shared/open-service/services/module-graph/engine/dependency-graph/walk-from-story.tscode/core/src/shared/open-service/services/module-graph/engine/module-graph-engine.test.tscode/core/src/shared/open-service/services/module-graph/engine/module-graph-engine.tscode/core/src/shared/open-service/services/module-graph/engine/parser-registry/builtins.test.tscode/core/src/shared/open-service/services/module-graph/engine/parser-registry/builtins.tscode/core/src/shared/open-service/services/module-graph/engine/parser-registry/mdx-parse.tscode/core/src/shared/open-service/services/module-graph/engine/parser-registry/parser-registry.test.tscode/core/src/shared/open-service/services/module-graph/engine/parser-registry/parser-registry.tscode/core/src/shared/open-service/services/module-graph/engine/parser-registry/types.tscode/core/src/shared/open-service/services/module-graph/errors.tscode/core/src/shared/open-service/services/module-graph/module-graph.test-helpers.tscode/core/src/shared/open-service/services/module-graph/server.test.tscode/core/src/shared/open-service/services/module-graph/server.tscode/core/src/shared/open-service/services/module-graph/story-files.tscode/core/src/shared/open-service/services/module-graph/types.tscode/core/src/types/modules/core-common.ts
💤 Files with no reviewable changes (7)
- code/core/src/core-server/utils/index-json.ts
- code/core/src/core-server/change-detection/adapters/index.ts
- code/core/src/core-server/change-detection/parser-registry/index.ts
- code/core/src/core-server/change-detection/active-service-registry.ts
- code/core/src/core-server/utils/index-json.test.ts
- code/core/src/core-server/change-detection/dependency-graph/index.ts
- code/core/src/core-server/change-detection/index.ts
| handler: async (input, ctx) => { | ||
| ctx.self.setState((state) => { | ||
| state.status = { value: 'ready' }; | ||
| state.storiesByFile = input.storiesByFile; | ||
| state.graphRevision += 1; | ||
| }); |
There was a problem hiding this comment.
Clear stale latestChangedStoryFiles when emitting non-update revisions.
applyGraphSnapshot and bumpGraphRevision increase graphRevision without resetting latestChangedStoryFiles, so getLatestStoryChanges can return old files for a newer revision.
🔧 Proposed fix
handler: async (input, ctx) => {
ctx.self.setState((state) => {
state.status = { value: 'ready' };
state.storiesByFile = input.storiesByFile;
state.graphRevision += 1;
+ state.latestChangedStoryFiles = [];
});
},
...
handler: async (_input, ctx) => {
ctx.self.setState((state) => {
state.graphRevision += 1;
+ state.latestChangedStoryFiles = [];
});
},Also applies to: 210-213
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@code/core/src/shared/open-service/services/module-graph/definition.ts` around
lines 171 - 176, The handlers that set or bump graphRevision (e.g., the
anonymous handler shown, applyGraphSnapshot, and bumpGraphRevision) update
state.graphRevision but do not clear state.latestChangedStoryFiles, causing
getLatestStoryChanges to return stale files; update each place that increments
or replaces the revision (the handler that sets status='ready',
applyGraphSnapshot, and bumpGraphRevision) to also reset
state.latestChangedStoryFiles to an empty collection (e.g., [] or {}) inside the
same ctx.self.setState callback so the newest revision has no leftover
changed-file entries.
| private mirrorUpdate(changedFile: string): void { | ||
| if (!this.reverseIndex) { | ||
| return; | ||
| } | ||
| const normalized = normalize(changedFile); | ||
| const bumpedStoryFiles = new Set<string>(); | ||
| for (const [storyFile] of this.reverseIndex.lookup(normalized)) { | ||
| bumpedStoryFiles.add(storyFile); | ||
| } | ||
| if (this.storyFiles.has(normalized)) { | ||
| bumpedStoryFiles.add(normalized); | ||
| } | ||
| this.options.onUpdate?.({ | ||
| storiesByFile: reverseIndexToStoriesByFile(this.reverseIndex.asMap(), this.workingDir), | ||
| bumpedStoryFiles: Array.from(bumpedStoryFiles, (storyFile) => | ||
| toStoryIndexPath(storyFile, this.workingDir) | ||
| ), | ||
| }); | ||
| } |
There was a problem hiding this comment.
Include pre-patch dependents when computing bumpedStoryFiles.
mirrorUpdate currently derives bumps from the post-patch index only. When a patch removes edges for event.path, affected stories can disappear from lookup and never get bumped.
💡 Proposed fix
@@
- private mirrorUpdate(changedFile: string): void {
+ private mirrorUpdate(changedFile: string, prePatchBumped = new Set<string>()): void {
@@
- const bumpedStoryFiles = new Set<string>();
+ const bumpedStoryFiles = new Set<string>(prePatchBumped);
@@
private async handleFileChange(event: FileChangeEvent): Promise<void> {
if (!this.incrementalPatcher) {
return;
}
+ const normalized = normalize(event.path);
+ const prePatchBumped = new Set<string>();
+ if (this.reverseIndex) {
+ for (const [storyFile] of this.reverseIndex.lookup(normalized)) {
+ prePatchBumped.add(storyFile);
+ }
+ }
+ if (this.storyFiles.has(normalized)) {
+ prePatchBumped.add(normalized);
+ }
try {
await this.incrementalPatcher.patch(event);
} catch (error) {
@@
}
- this.mirrorUpdate(event.path);
+ this.mirrorUpdate(event.path, prePatchBumped);
}Also applies to: 370-382
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@code/core/src/shared/open-service/services/module-graph/engine/module-graph-engine.ts`
around lines 99 - 117, mirrorUpdate currently only uses the post-patch
reverseIndex lookup and can miss stories whose edges were removed by the patch;
change mirrorUpdate to accept (or obtain) the pre-patch dependents and union
them with the post-patch lookup results before computing bumpedStoryFiles.
Specifically, update the mirrorUpdate signature to accept an extra
prePatchDependents (Set<string> or string[]), or capture lookup(normalized)
before applying the patch in the caller and pass it in; then merge that set with
the current this.reverseIndex.lookup(normalized) results plus this.storyFiles
into bumpedStoryFiles, and keep the rest of the logic (options.onUpdate,
reverseIndexToStoriesByFile, toStoryIndexPath) unchanged so both pre- and
post-patch dependents are included.
| adapter.onStartupFailure?.((event) => { | ||
| this.options.onUnavailable?.(event.reason, event.error); | ||
| }); |
There was a problem hiding this comment.
Register onStartupFailure before async startup to avoid missing early failure events.
The handler is attached only after getResolveConfig(), getIndex(), and build(). If startup failure fires during that window, onUnavailable is never emitted.
💡 Proposed fix
@@
- // Subscribe BEFORE build — buffer events until patcher is ready
+ // Subscribe BEFORE build — buffer events until patcher is ready
const eventBuffer: FileChangeEvent[] = [];
const unsubscribeBuffer = adapter.onFileChange((event) => {
eventBuffer.push(event);
});
+ adapter.onStartupFailure?.((event) => {
+ this.options.onUnavailable?.(event.reason, event.error);
+ });
@@
- adapter.onStartupFailure?.((event) => {
- this.options.onUnavailable?.(event.reason, event.error);
- });
-
this.mirrorSnapshot();🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@code/core/src/shared/open-service/services/module-graph/engine/module-graph-engine.ts`
around lines 237 - 239, Register the adapter.onStartupFailure handler before
performing any async startup work so early failures aren't missed: move the
attachment of adapter.onStartupFailure?.(...) to occur before calling
getResolveConfig(), getIndex(), or build(), and ensure it forwards event.reason
and event.error to this.options.onUnavailable so any startup error during those
async calls will be emitted.
Keep selectComponentEntriesByComponentId from the docgen phase-3 base while preserving module-graph subscription reactivity in docgen. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/core/src/core-server/presets/common-preset.ts (1)
333-367:⚠️ Potential issue | 🟠 Major | ⚡ Quick winKeep story-index resolution lazy in
services.
options.presets.apply('storyIndexGenerator')initializes the full generator immediately, so manager-only /ignorePreviewruns still build the story index before the guard on Lines 345-348 is checked. That defeats the skip documented there and can bring back unnecessary work or preview-side failures in flows that intentionally avoid preview output.Suggested change
- // `presets.apply` flattens the generator preset's returned promise, so this is the resolved - // generator, not a promise. - const storyIndexGenerator = - await options.presets.apply<StoryIndexGenerator>('storyIndexGenerator'); + const getIndex = async () => { + const storyIndexGenerator = + await options.presets.apply<StoryIndexGenerator>('storyIndexGenerator'); + return storyIndexGenerator.getIndex(); + }; registerModuleGraphService({ channel: options.channel, - getIndex: () => storyIndexGenerator.getIndex(), + getIndex, workingDir: process.cwd(), presets: options.presets, }); @@ registerDocgenService({ - getIndex: () => storyIndexGenerator.getIndex(), + getIndex, provider, workingDir: process.cwd(), });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@code/core/src/core-server/presets/common-preset.ts` around lines 333 - 367, The code eagerly calls options.presets.apply('storyIndexGenerator') (symbol: storyIndexGenerator) which forces full story-index init even when preview is skipped; instead make resolution lazy: remove the top-level await and replace it with a lazily-resolving accessor (e.g. a getStoryIndex or storyIndexGeneratorPromise resolver) that only calls options.presets.apply('storyIndexGenerator') the first time getIndex is invoked, cache the resolved generator, and then have registerModuleGraphService and registerDocgenService use that accessor (replace getIndex: () => storyIndexGenerator.getIndex() with getIndex: () => getStoryIndex().then(g => g.getIndex()) or a sync wrapper that awaits internally) so the generator is only created when needed and the features/ignorePreview guard can skip creating it entirely.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@code/core/src/core-server/presets/common-preset.ts`:
- Around line 333-367: The code eagerly calls
options.presets.apply('storyIndexGenerator') (symbol: storyIndexGenerator) which
forces full story-index init even when preview is skipped; instead make
resolution lazy: remove the top-level await and replace it with a
lazily-resolving accessor (e.g. a getStoryIndex or storyIndexGeneratorPromise
resolver) that only calls options.presets.apply('storyIndexGenerator') the first
time getIndex is invoked, cache the resolved generator, and then have
registerModuleGraphService and registerDocgenService use that accessor (replace
getIndex: () => storyIndexGenerator.getIndex() with getIndex: () =>
getStoryIndex().then(g => g.getIndex()) or a sync wrapper that awaits
internally) so the generator is only created when needed and the
features/ignorePreview guard can skip creating it entirely.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 19e86824-5cc1-46b4-8e11-ed112a32806c
📒 Files selected for processing (4)
code/core/src/core-server/presets/common-preset.tscode/core/src/shared/open-service/services/docgen/server.test.tscode/core/src/shared/open-service/services/docgen/server.tscode/core/src/types/modules/core-common.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- code/core/src/shared/open-service/services/docgen/server.ts
- code/core/src/shared/open-service/services/docgen/server.test.ts
- code/core/src/types/modules/core-common.ts







Closes #
What I did
This PR moves Storybook's story module graph out of change detection and into a new
core/module-graphopen service.Concretely, it:
shared/open-service/services/module-graph.core/module-graphas the single service boundary for module graph consumers../src/Button.stories.tsx, so future static snapshots do not leak absolute filesystem paths.getStatus— lifecycle state (booting,ready,error,unavailable) with serializableErrorLikeerrors.getStoriesForFiles— maps source files to affected story files and graph distance.getGraphRevision— monotonic graph/index revision for consumers that need to rescan derived state.getLatestStoryChanges— latest changed story files plus revision, used by DocGen reactivity.StoryDependencyGraphService/active-registry compatibility path; current consumers must use the open service.ChangeDetectionServiceconsume module graph data through open-service queries/subscriptions instead of engine callbacks.getLatestStoryChangesand proactively refreshing already-extracted docgen for affected component ids.Follow-up prompt: migrate addon-mcp to
core/module-graphChecklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Focused validation run locally after resolving conflicts with
claude/docgen-phase-3-rcm-provider:npx vitest run --config code/core/vitest.config.ts code/core/src/shared/open-service/services/module-graph code/core/src/shared/open-service/services/docgen/server.test.ts code/core/src/core-server/change-detection/change-detection-service.test.ts(12files,150tests)FORCE_COLOR=0 yarn exec jiti ./scripts/check/check-package.ts --cwd code/coreyarn --cwd code lint:js:cmd core/src/shared/open-service/services/docgen/server.ts core/src/shared/open-service/services/docgen/server.test.ts core/src/shared/open-service/services/module-graph/definition.ts core/src/shared/open-service/services/module-graph/server.ts core/src/shared/open-service/services/module-graph/server.test.ts core/src/shared/open-service/services/module-graph/types.ts core/src/core-server/change-detection/change-detection-service.ts core/src/core-server/change-detection/change-detection.test-helpers.ts core/src/core-server/dev-server.ts --fixManual testing
Please QA the change detection path in a Storybook project using a builder that supports change detection, such as a React Vite Storybook.
Start from a clean git working tree in a Storybook project with at least one component story, for example a
Button.tsxcomponent andButton.stories.tsxstory.Enable the change detection feature flag in
.storybook/main.ts:If the project already has a
featuresobject, addchangeDetection: trueto it.Start Storybook in dev mode.
Open the manager UI and confirm the initial sidebar has no unexpected change-detection statuses for the clean working tree.
Edit the component file imported by the story, for example
Button.tsx, without committing the change.Confirm the related story receives the expected changed/modified status in the Storybook sidebar.
Edit a transitive dependency of that story, for example a helper/module imported by
Button.tsx, and confirm the dependent story receives the expected affected status.Add or rename a story file, then trigger story index regeneration by saving the file or requesting
index.json; confirm the story list and change-detection status update without restarting Storybook.Revert the edited files back to the clean git state and confirm the change-detection statuses clear after Storybook processes the file changes.
While Storybook is still running, make one more source-file edit and confirm the status updates again, verifying the module graph continues to process incremental changes after the initial build.
Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsDeclare whether manual QA will be needed for this PR during the next release, through
qa:neededorqa:skipMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This pull request has been released as version
0.0.0-pr-35048-sha-7c1a3349. Try it out in a new sandbox by runningnpx storybook@0.0.0-pr-35048-sha-7c1a3349 sandboxor in an existing project withnpx storybook@0.0.0-pr-35048-sha-7c1a3349 upgrade.More information
0.0.0-pr-35048-sha-7c1a3349jeppe-cursor/4b72cdff7c1a33491780573859)To request a new release of this pull request, mention the
@storybookjs/coreteam.core team members can create a new canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=35048Made with Cursor
Summary by CodeRabbit
Refactor
New Features
Bug Fixes