Skip to content

Conversation

@kasperpeulen
Copy link
Contributor

@kasperpeulen kasperpeulen commented Nov 26, 2025

Closes #

What I did

This refactors the root of yarn monorepo from ./code to the git root ..
Sandboxes still need to be tested in isolation, so by default they now live in:
../storybook-sandboxes

To get the old behavior use SANDBOX_ROOT=./sandbox in your commands.
This is not recommended.

You will still see that the ./sandbox directory exists.
This is because NX outputs must live in the monorepo.
This directory is not used for any ci tests.
The real sandbox lives in process.env.SANDBOX_ROOT

NX improvements
Because of this new setup, we can fix a lot of issues we had with NX.
NX should now always invalidate compile and check steps correctly.
This is because NX can now take the scripts into account in the project graph.
Changes in scripts should invalidate every tasks, as every task depends on build tooling in scipts.

NX as the task runner experiment
We have implemented a custom task runner that can be used with yarn task.
I have copied our task runner to NX. This can potentially give great improvements.
For example, we can start using NX cloud agents.

This work is all experimental, and should not impact anyones workflow atm.
You can check the nx github action step though, and see if it is green.
It should be a lot faster than circle ci.
It doesn't have to be green to merge your PR though. But please let me know, so I can fix flake in nx agents.

Use NX locally
If you want try using nx locally, this is how it works:

yarn task compile -s compile --no-link
yarn nx run-many -t compile -c production

yarn task e2e-tests-dev --template react-vite/default-ts --no-link
yarn nx e2e-tests-dev react-vite/default-ts -c production
// or this, as react-vite/default-ts is the default project
yarn nx e2e-tests-dev -c production

yarn task e2e-tests-dev -s e2e-tests --template react-vite/default-ts --no-link
yarn nx e2e-tests-dev -c production --exclude-task-dependencies

All yarn task tasks, have the same name in nx.
Sandbox command can only be used with -c production.
In a feature PR, I will also allow NX to be used without verdaccio.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make 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 PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Build & Infrastructure

    • Node bumped to 22.21.1, CI caching/keying simplified, some CI jobs upgraded, and a new distributed CI workflow added.
  • Configuration

    • Storybook env flags introduced; installs now favor root-level Yarn and a streamlined workspace/sandbox layout.
  • Sandbox Management

    • Sandboxes cached/reused, faster portable setup, optional local registry support, explicit Corepack/Yarn steps, and per-task port allocation.
  • Projects & Tooling

    • Many project manifests standardized with unified targets and CI tags.
  • Docs

    • Minor snippet and formatting fixes.
  • Tests

    • Consolidated test/artifact reporting and improved e2e readiness.

✏️ Tip: You can customize this high-level summary in your review settings.

@kasperpeulen kasperpeulen added build Internal-facing build tooling & test updates ci:normal labels Nov 26, 2025
@nx-cloud
Copy link

nx-cloud bot commented Nov 26, 2025

View your CI Pipeline Execution ↗ for commit a4f5eda

Command Status Duration Result
nx run-many -t compile --parallel=3 ✅ Succeeded 45s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-28 13:59:20 UTC

@kasperpeulen kasperpeulen changed the title Build: Refactor root of yarn monorepo from code to the git root. Build: Refactor root of yarn monorepo from code to the git root Nov 26, 2025
@storybook-app-bot
Copy link

storybook-app-bot bot commented Nov 26, 2025

Package Benchmarks

Commit: a4f5eda, ran on 28 November 2025 at 13:51:17 UTC

The following packages have significant changes to their size or dependencies:

@storybook/addon-docs

Before After Difference
Dependency count 18 18 0
Self size 1.65 MB 1.80 MB 🚨 +149 KB 🚨
Dependency size 9.25 MB 9.25 MB 🎉 -280 B 🎉
Bundle Size Analyzer Link Link

@storybook/builder-vite

Before After Difference
Dependency count 17 17 0
Self size 304 KB 325 KB 🚨 +20 KB 🚨
Dependency size 2.00 MB 2.00 MB 🎉 -152 B 🎉
Bundle Size Analyzer Link Link

storybook

Before After Difference
Dependency count 39 39 0
Self size 19.64 MB 20.51 MB 🚨 +871 KB 🚨
Dependency size 16.40 MB 16.40 MB 0 B
Bundle Size Analyzer Link Link

@storybook/html-vite

Before After Difference
Dependency count 20 20 0
Self size 22 KB 22 KB 🎉 -128 B 🎉
Dependency size 2.34 MB 2.36 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/nextjs-vite

Before After Difference
Dependency count 128 128 0
Self size 1.12 MB 1.12 MB 🚨 +796 B 🚨
Dependency size 21.95 MB 21.97 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/preact-vite

Before After Difference
Dependency count 20 20 0
Self size 13 KB 13 KB 🎉 -140 B 🎉
Dependency size 2.33 MB 2.35 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react-native-web-vite

Before After Difference
Dependency count 160 160 0
Self size 30 KB 30 KB 🎉 -140 B 🎉
Dependency size 23.13 MB 23.15 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react-vite

Before After Difference
Dependency count 118 118 0
Self size 35 KB 35 KB 🎉 -140 B 🎉
Dependency size 19.75 MB 19.77 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/svelte-vite

Before After Difference
Dependency count 24 24 0
Self size 56 KB 55 KB 🎉 -152 B 🎉
Dependency size 27.00 MB 27.02 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/sveltekit

Before After Difference
Dependency count 25 25 0
Self size 56 KB 56 KB 🎉 -164 B 🎉
Dependency size 27.06 MB 27.08 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/vue3-vite

Before After Difference
Dependency count 114 114 0
Self size 35 KB 35 KB 🎉 -164 B 🎉
Dependency size 44.15 MB 44.17 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/web-components-vite

Before After Difference
Dependency count 21 21 0
Self size 19 KB 19 KB 🎉 -152 B 🎉
Dependency size 2.37 MB 2.39 MB 🚨 +20 KB 🚨
Bundle Size Analyzer Link Link

@storybook/cli

Before After Difference
Dependency count 173 173 0
Self size 773 KB 774 KB 🚨 +802 B 🚨
Dependency size 66.73 MB 67.61 MB 🚨 +871 KB 🚨
Bundle Size Analyzer Link Link

@storybook/codemod

Before After Difference
Dependency count 166 166 0
Self size 30 KB 30 KB 🎉 -140 B 🎉
Dependency size 65.31 MB 66.18 MB 🚨 +871 KB 🚨
Bundle Size Analyzer Link Link

create-storybook

Before After Difference
Dependency count 40 40 0
Self size 999 KB 999 KB 🎉 -59 B 🎉
Dependency size 36.04 MB 36.91 MB 🚨 +871 KB 🚨
Bundle Size Analyzer node node

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 26, 2025

📝 Walkthrough

Walkthrough

Widespread CI and workspace reorganization plus sandbox orchestration: CircleCI jobs and GitHub actions paths/caching adjusted; SANDBOX_DIRECTORY and related envs centralized; new prepare-sandbox and sandbox caching/copy/port handling added; many Nx/project manifests and package.json workspace/layout changes; numerous scripts reworked to use ROOT_DIRECTORY and per-template ports.

Changes

Cohort / File(s) Summary
CI & GitHub workflows
.circleci/..., .github/actions/setup-node-and-install/action.yml, .github/workflows/nx.yml
Attach workspace moved from . to /tmp, artifact/test paths moved under storybook/*, Yarn cache keys simplified, Corepack steps added to sandbox jobs, resource classes adjusted, new GitHub Actions nx workflow added.
Sandbox constants & env
scripts/utils/constants.ts, scripts/get-sandbox-dir.ts, .env
SANDBOX_DIRECTORY computed from STORYBOOK_SANDBOX_ROOT (supports absolute/relative); get-sandbox-dir now prints joined path; new env vars added (STORYBOOK_SANDBOX_ROOT, IN_STORYBOOK_SANDBOX, STORYBOOK_DISABLE_TELEMETRY).
Prepare / sandbox orchestration
scripts/prepare-sandbox.ts, scripts/ecosystem-ci/before-test.js, scripts/tasks/sandbox.ts, scripts/task.ts, scripts/sandbox/utils/getPort.ts
New prepare-sandbox script; sandbox dir option introduced; sandbox cache copy/refresh logic added (copy to/from cacheDir), sandbox paths moved to storybook-sandboxes; getPort computes per-template/task port.
Port & registry utilities
scripts/utils/port.ts, scripts/run-registry.ts, scripts/tasks/run-registry.ts
New port utilities (isPortUsed, killPort, sleep); Verdaccio/registry startup refactored to return a closeable Servers object; kill/polling behavior added; wait-on usage standardized.
Task runtimes (dev/serve/build/test-runner/etc.)
scripts/tasks/dev.ts, scripts/tasks/serve.ts, scripts/tasks/build.ts, scripts/tasks/e2e-tests-build.ts, scripts/tasks/test-runner-build.ts
Tasks accept key/selectedTask/builtSandboxDir where needed, use per-template ports via getPort, readiness waits on computed HTTP endpoints, build task supports cache refresh and rsync-style copy.
Install & workspace installs
scripts/tasks/install.ts, scripts/utils/cli-utils.ts, scripts/.yarnrc.yml (removed), code/.yarnrc.yml (removed)
Install logic centralized to ROOT_DIRECTORY; per-scripts Yarn rc files removed; ready/run signatures simplified; root-level yarn used for installs.
Nx & workspace config
nx.json (added), .nx/workflows/*.yaml, .nx/workflows/distribution-config.yaml, code/project.json, scripts/project.json
New workspace nx.json added and many .nx/workflows files introduced; per-project project.json files added/updated (including scripts/project.json).
Sandbox project manifests
code/sandbox/**/project.json (many)
Numerous sandbox manifests added/rewritten: removed $schema, added description, expanded implicitDependencies, and replaced legacy sandbox/sb:dev/sb:build with explicit dir-aware targets (prepare-sandbox, dev, build, chromatic, serve, e2e/test-runner variants).
Monorepo & package manifests
package.json, code/package.json, scripts/package.json, .gitignore, .nvmrc
Root package.json converted toward monorepo style (workspaces, private, type), scripts simplified (install → yarn), resolutions/devDependencies adjusted, .nvmrc Node version updated, .gitignore expanded.
Per-package script removals & project.json updates
code/**/package.json (many), code/**/project.json (many)
Many packages had scripts blocks removed (check/prep), and many project.json files had $schema removed and build split into compile/check with tags added.
Build toolchain & build scripts
scripts/build-package.ts, scripts/build/build-package.ts, scripts/build/utils/*, scripts/check/*, scripts/create-nx-sandbox-projects.ts
Centralized build invocation (use centralized build script), added ROOT_DIRECTORY, argument parsing with parseArgs, JSON output formatted with Prettier for generated sandbox manifests, absolute DIR_CWD usage in bundlers and type generation.
Tests & e2e updates
code/e2e-tests/*, code/e2e-tests/addon-onboarding.spec.ts, scripts/release/*, scripts/event-log-checker.ts
Tests adapted to new sandbox constants and cleanup (e.g., removing settings.json), event log test adjusted (removed hashing expectation), and CI test result paths updated to storybook/*.
Docs & snippets
docs/_snippets/*
Minor formatting and template-binding fixes (attribute interpolation, punctuation, blank lines) across multiple docs snippets.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Dev as Developer CLI
participant Task as prepare-sandbox / scripts/task
participant FS as Filesystem (storybook-sandboxes)
participant Registry as Local Registry (Verdaccio)
participant Sandbox as Storybook Server
participant Tests as Test Runner

Dev->>Task: run prepare/start (template, dir, link)
Task->>FS: compute SANDBOX_DIRECTORY (STORYBOOK_SANDBOX_ROOT)
alt cached sandbox exists
    Task->>FS: copy cache -> sandbox dir
else no cache
    Task->>FS: create sandbox dir
end
Task->>Registry: ensure local registry running (startVerdaccio)
Registry-->>Task: servers object (close)
Task->>FS: run yarn install --immutable (in sandbox)
Task->>Sandbox: start storybook --port computed by getPort(key, selectedTask)
Sandbox-->>Task: report ready when http://localhost:<port>/iframe.html available
Task->>Tests: wait-on http://localhost:<port> then run tests (playwright/vitest)
Tests->>Sandbox: execute tests against STORYBOOK_URL=http://localhost:<port>
Task->>Registry: on teardown call servers.close()

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas to focus during review:

  • scripts/utils/constants.ts and all consumers of SANDBOX_DIRECTORY / STORYBOOK_SANDBOX_ROOT for absolute vs relative path handling and permission/CI runner differences.
  • scripts/utils/port.ts killPort polling and cross-platform process termination behavior.
  • scripts/run-registry.ts and scripts/tasks/run-registry.ts: servers.close propagation and guaranteed cleanup to avoid orphan processes.
  • scripts/prepare-sandbox.ts and scripts/tasks/sandbox.ts: cache copy/remove logic and node_modules/Yarn cache exclusions.
  • CI job changes: verify CircleCI and GitHub Actions cache keys, attach_workspace root changes, and artifact/test paths under storybook/*.
  • Nx and many project.json edits: ensure tooling expects compile/check targets instead of build and updated tags.

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73841fd and a4f5eda.

📒 Files selected for processing (10)
  • .circleci/config.yml (40 hunks)
  • .circleci/src/jobs/bench-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/check-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/chromatic-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/e2e-dev.yml (2 hunks)
  • .circleci/src/jobs/e2e-production.yml (2 hunks)
  • .circleci/src/jobs/test-runner-production.yml (2 hunks)
  • .circleci/src/jobs/vitest-integration.yml (2 hunks)
  • nx.json (1 hunks)
  • scripts/tasks/dev.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • .circleci/src/jobs/chromatic-sandboxes.yml
  • .circleci/src/jobs/bench-sandboxes.yml
  • .circleci/src/jobs/e2e-production.yml
  • .circleci/src/jobs/e2e-dev.yml
  • .circleci/src/jobs/check-sandboxes.yml
  • .circleci/src/jobs/test-runner-production.yml
  • scripts/tasks/dev.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • nx.json
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • .circleci/src/jobs/vitest-integration.yml
  • nx.json
  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • .circleci/src/jobs/vitest-integration.yml
  • nx.json
  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'yarn vitest run --coverage <test-file>' to run tests with coverage reports and aim for 75%+ coverage of statements/lines

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .nvmrc : Use Node.js 22.16.0 as specified in .nvmrc

Applied to files:

  • .circleci/config.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (8)
nx.json (2)

43-50: Verify the trailing comma fix was applied.

Previous review flagged a trailing comma after the compile target's dependsOn array (line 43). Current code shows clean JSON syntax without trailing comma. Confirmed fixed.


200-218: Path references in namedInputs are correct and require no adjustment.

All paths referenced in lines 202 and 215 exist and are valid:

  • {workspaceRoot}/code/tsconfig.json ✓ exists
  • {workspaceRoot}/code/**/* globs ✓ valid directory structure
  • {workspaceRoot}/scripts/**/* ✓ exists
  • {workspaceRoot}/.github/workflows/nx.yml ✓ exists
  • {workspaceRoot}/.nx/workflows ✓ exists

The monorepo refactoring maintains the code/ subdirectory structure, so the existing glob patterns are appropriate and no changes are needed to nx.json.

.circleci/src/jobs/vitest-integration.yml (2)

19-21: Sandbox directory resolution pattern is sound.

The dynamic resolution via yarn get-sandbox-dir correctly defaults to ../storybook-sandboxes per PR objectives. Given executor working_directory: /tmp/storybook, the path resolves to /tmp/storybook-sandboxes, which aligns with the persist_to_workspace setup in create-sandboxes job. Pattern is consistent across sandbox-related jobs.


14-21: Based on my comprehensive verification, I can now provide the rewritten review comment:

The vitest-integration job configuration is correct and does not require a Verdaccio background service.

The original concern incorrectly conflated two different task systems. The CircleCI job uses the yarn task runner (yarn task --task), not Nx targets. In the yarn task system, vitest-integration depends only on the sandbox task, not prepare-sandbox. Since create-sandboxes pre-builds and persists the sandboxes to /tmp, the sandbox task is already ready when vitest-integration runs. The job simply reinstalls dependencies from yarn.lock (which contains no local registry references since create-sandboxes used --start-from=sandbox to skip registry setup) and executes the vitest tests. No Verdaccio service is needed.

.circleci/config.yml (4)

1-35: Workspace path refactoring is consistent and comprehensive.

All executors now use working_directory: /tmp/storybook (lines 54, 72, 90, 108), and all CircleCI jobs attach workspaces to /tmp with artifacts/test results persisted to storybook/* paths. This aligns with the PR's objective to move the monorepo root from ./code to repo root (.). The persisted workspace structure and path resolution are consistent across ~30 modified jobs.


226-240: I'll verify the review comment about the persist_to_workspace artifact paths and git-shallow-clone behavior. Let me start by examining the CircleCI config structure.
<function_calls>


#!/bin/bash

echo "=== Checking git-shallow-clone usage in config.yml ==="
rg -n "git-shallow-clone" .circleci/config.yml -A 3 -B 1

echo ""
echo "=== Verify executor definitions and working_directory ==="
sed -n '36,110p' .circleci/config.yml

echo ""
echo "=== Check build job structure around persist_to_workspace ==="
sed -n '195,245p' .circleci/config.yml


</function_calls>


200-210: Cache key path is correct after monorepo restructuring.

Verification confirms yarn.lock is now at the repo root (1.2M, modified Nov 28 13:39), not in the code/ directory. The cache key {{ checksum "yarn.lock" }} will correctly resolve in CircleCI's executor context with working_directory: /tmp/storybook.


313-338: Based on my verification, I can now provide the rewritten review comment. The investigation confirms the concern is valid but reveals the situation is more nuanced than initially stated.

Chromatic uses isolated ./sandbox path with explicit env var; other jobs rely on default ../storybook-sandboxes.

The chromatic-sandboxes job (lines 325-330) copies the persisted workspace artifacts from /tmp/storybook-sandboxes to /tmp/storybook/sandbox and sets STORYBOOK_SANDBOX_ROOT=./sandbox, which resolves to {repo-root}/sandbox via the path resolution logic in scripts/utils/constants.ts. In contrast, all other sandbox jobs (bench, check, e2e, test-runner, vitest) omit this env var and rely on the default ../storybook-sandboxes relative to the repository root.

While all sandbox jobs run with significant parallelism (chromatic: 36+, others: 6-34), only chromatic isolates its sandboxes via this copy+env pattern. The chromatic task code itself contains no path-dependent logic—it accepts sandboxDir as a parameter—suggesting the special handling is defensive or historical rather than functionally required.

Clarify in documentation or code comments whether this isolation is necessary for chromatic's specific requirements (e.g., artifact cleanup, token handling), or unify the approach across all sandbox jobs if both strategies are equivalent.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
scripts/knip.config.ts (1)

84-93: Workspace pattern mismatch breaks bundler-entry enrichment

With baseDir now pointing at the git root, the workspace matching logic is broken:

  • fg(rootManifest.workspaces.packages, { cwd: baseDir }) yields dirs like code/addons/a11y, code/renderers/react, etc., because the root package.json workspaces globs all start with code/ (e.g., "code/addons/*", "code/renderers/*").
  • wsDir therefore includes the code/ prefix (e.g., "code/addons/a11y").
  • match([wsDir], configKey) compares against keys like "addons/*", "renderers/*" (no code/ prefix).
  • The pattern "addons/*" does not match "code/addons/a11y", so no workspace directory matches any config key.

As a result, bundler entries from each package.json are never merged into the Knip config. Static analysis will still run, but without those enriched entrypoints.

Fix this by stripping the code/ prefix before matching:

const workspaceDirectories = workspaceDirs.map((dir) => relative(baseDir, join(baseDir, dir)).replace(/^code\//, ''));

Or update baseConfig.workspaces keys to include the code/ prefix to match the root workspace globs.

.github/copilot-instructions.md (1)

20-34: Clarify sandbox location vs new SANDBOX_ROOT behavior

The docs still talk about a root sandbox/ directory (and contrast it with code/sandbox/), but the new tooling introduces SANDBOX_ROOT (e.g., ../storybook-sandboxes for agents). It would help to explicitly call out:

  • Where sandboxes live by default for contributors running yarn task --task sandbox locally.
  • How that differs in CI (Nx agents) where SANDBOX_ROOT is overridden.
  • How to opt back into the “old” ./sandbox behavior via env.

Right now it’s easy to assume everything always lands in ./sandbox, which may not match the new defaults.

Also applies to: 193-201, 214-230

scripts/release/version.ts (1)

54-86: Guard preId validation against missing releaseType

In optionsSchema.superRefine, this condition can throw if preId is provided without releaseType:

if (schema.preId && !schema.releaseType.startsWith('pre')) {

schema.releaseType is optional, so calling .startsWith on undefined will crash before Zod can surface a helpful validation error.

A small defensive tweak avoids that:

-    if (schema.preId && !schema.releaseType.startsWith('pre')) {
+    if (schema.preId && !schema.releaseType?.startsWith('pre')) {

This preserves the intended validation while preventing a runtime TypeError for invalid option combinations.

♻️ Duplicate comments (8)
code/addons/onboarding/project.json (1)

5-8: Consistent with monorepo standardization; verify executor mappings upstream.

The changes follow the established pattern across library and addon projects in this PR. Ensure the check target executor is defined in the parent Nx configuration.

code/presets/react-webpack/project.json (1)

5-8: Consistent with preset standardization pattern.

The changes align with the monorepo-wide refactoring. Verify the check target executor is mapped in parent Nx configuration.

code/frameworks/vue3-vite/project.json (1)

5-8: Framework standardization pattern confirmed.

Changes follow the repo-wide pattern. Confirm check target executor is defined upstream in Nx configuration.

code/sandbox/react-native-web-vite-expo-ts/project.json (1)

1-27: Consistent configuration pattern.

This follows the same target structure as other sandbox projects in this PR. The empty target definitions should be verified similarly (see comment on bench-react-webpack-18-ts-test-build/project.json).

code/sandbox/nextjs-14-ts/project.json (1)

1-25: Consistent configuration pattern.

This Next.js 14 TypeScript sandbox follows the established pattern with similar target definitions and dependency structure.

.circleci/src/jobs/vitest-integration.yml (1)

18-20: Verify sandbox path resolution (same pattern as e2e-production.yml).

The sandbox/ prefix was removed. Ensure that yarn get-sandbox-dir --template $TEMPLATE returns the correct full path.

.circleci/src/jobs/bench-sandboxes.yml (1)

18-20: Verify sandbox path resolution (same pattern as other jobs).

The sandbox/ prefix was removed. Ensure that yarn get-sandbox-dir --template $TEMPLATE returns the correct full path.

.circleci/src/jobs/create-sandboxes.yml (1)

34-34: Verify sandbox path resolution (same pattern as other jobs).

The sandbox/ prefix was removed. Ensure that yarn get-sandbox-dir --template $TEMPLATE returns the correct full path so the cd and rm -rf node_modules commands work correctly.

🧹 Nitpick comments (23)
code/lib/csf-plugin/project.json (1)

4-8: Verify that empty targets are properly inherited or configured elsewhere.

The "build" and "check" targets (lines 5–6) are defined with empty configurations. Per the PR's goal of moving build/check scripts to Nx targets, please confirm these targets are either:

  1. Inheriting configuration from a base/shared Nx config (e.g., a root preset or extends field)
  2. Configured via environment-specific Nx settings or workspace plugins
  3. Intentionally empty as placeholders pending explicit wiring

The addition of "tags": ["ci:normal"] (line 8) suggests this file is part of a new CI orchestration strategy. Ensure this tag is recognized by the Nx CI pipeline and that agent routing works as intended. Also verify that the removal of $schema does not degrade IDE validation or Nx CLI introspection for developers.

To help verify the broader configuration strategy, could you confirm:

  • Which files define the actual implementation of these "check" and "build" targets (e.g., a root nx.json, base config, or workspace preset)?
  • Whether the schema reference should be retained or centralized at the workspace level for IDE support.
code/sandbox/angular-cli-default-ts/project.json (1)

4-12: Verify implicitDependencies comprehensiveness and necessity.

The list expanded significantly to include 7 packages. While these appear to be relevant storybook packages, please confirm that:

  1. All listed dependencies are actually used or transitively required by this sandbox
  2. No additional dependencies are missing (e.g., are all @storybook/* addons that this sandbox needs included?)
  3. This matches the pattern used in other sandbox configurations
docs/_snippets/addon-consume-and-update-globaltype.md (1)

17-21: Clarify the comma operator usage in documentation example.

The comma operator pattern (updateGlobals({...}), addons.getChannel().emit(...)) is valid but semantically unclear in a documentation context. Developers reading this example may question why the result of the comma expression is discarded or misunderstand the intent. For documentation clarity, use two separate statements instead.

  const refreshAndUpdateGlobal = () => {
-   (updateGlobals({
+   updateGlobals({
      ['my-param-key']: !isActive,
-   }),
-     // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh
-     addons.getChannel().emit(FORCE_RE_RENDER));
+   });
+   // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh
+   addons.getChannel().emit(FORCE_RE_RENDER);
  };
docs/_snippets/storybook-addons-api-getchannel.md (1)

16-20: Clarify the comma operator usage in documentation example (duplicate pattern).

Same issue as addon-consume-and-update-globaltype.md: the comma operator pattern is semantically unclear for documentation examples. This pattern appears across multiple snippet files and should be simplified for clarity. Use two separate statements instead.

  const refreshAndUpdateGlobal = () => {
-   (updateGlobals({
+   updateGlobals({
      ['my-param-key']: !isActive,
-   }),
-     // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh
-     addons.getChannel().emit(FORCE_RE_RENDER));
+   });
+   // Invokes Storybook's addon API method (with the FORCE_RE_RENDER) event to trigger a UI refresh
+   addons.getChannel().emit(FORCE_RE_RENDER);
  };
scripts/build/utils/generate-type-mappers.ts (1)

39-39: LGTM! Path resolution correctly updated for monorepo restructuring.

The addition of join(cwd, ...) properly makes the generated type mapper file paths absolute, which is necessary given the monorepo root is moving from the code directory to the git root. This ensures the type declaration files are written to the correct location regardless of where the build script is invoked from.

Optional: Consider more robust path transformation.

While not introduced by this PR, the string replacement pattern .replace('src', 'dist') replaces only the first occurrence of 'src', which could be fragile if entry point paths contain 'src' in multiple locations (e.g., src/source-maps/file.ts). Consider using path manipulation utilities or regex with anchors for more robust transformation in a future refactor.

code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts (1)

14-17: Avoid any on the global addons channel (use a minimal structural type instead).

Changing __STORYBOOK_ADDONS_CHANNEL__ to any weakens type safety in a template file users are likely to copy from. You can keep strictness without importing internal types by defining a small structural type for just what this story needs:

-declare global {
-  // eslint-disable-next-line no-var
-  var __STORYBOOK_ADDONS_CHANNEL__: any;
-}
+type StorybookAddonsChannel = {
+  emit: (event: string, ...args: any[]) => void;
+  once: (event: string, callback: (...args: any[]) => void) => void;
+};
+
+declare global {
+  // eslint-disable-next-line no-var
+  var __STORYBOOK_ADDONS_CHANNEL__: StorybookAddonsChannel;
+}

This preserves the looseness you likely want in a template while still aligning with the repo’s strict TypeScript guidelines.

code/sandbox/solid-vite-default-js/project.json (1)

13-22: Add vitest-integration target for consistency with TS variant.

The TypeScript counterpart includes a vitest-integration target, but this file omits it. If both variants should support the same workflows, add this target. If the JS variant genuinely does not need it, document the rationale in the PR description or add a comment explaining the divergence.

If this target should be included, apply this diff:

  "targets": {
    "sandbox": { "options": { "dir": "solid-vite-default-js" } },
    "prepared-sandbox": {},
    "dev": {},
+   "vitest-integration": {},
    "build-sandbox": { "options": { "dir": "solid-vite-default-js" } },
scripts/check/check-package.ts (1)

1-31: Cwd normalization and scoped type-checking flow look solid

Deriving normalizedCwd from the optional --cwd flag (with sensible handling of absolute vs. repo-relative paths) and using it consistently for tsconfigPath, getTSFilesAndConfig, and getTSDiagnostics gives you a clear per-package check that works from the git root without breaking existing usage when no cwd is passed. The added "no type errors" branch also makes the script’s success path explicit. As per coding guidelines, just remember to run yarn prettier --write scripts/check/check-package.ts and yarn lint:js:cmd scripts/check/check-package.ts after any further edits.

code/core/src/telemetry/anonymous-id.ts (1)

50-52: Consider logging the error for debugging purposes.

The error variable has been renamed from _ to e, but it's still unused in the catch block. Since this function is related to telemetry and project identification, consider logging the error (using the appropriate logger from storybook/internal/node-logger) to aid debugging when git command execution fails.

Apply this diff to add error logging:

-  } catch (e) {
-    //
+  } catch (e) {
+    // Silently fail if git command fails (e.g., not a git repository)
+    // Telemetry will proceed without project ID
   }

As per coding guidelines, if you choose to log the error, use the logger from storybook/internal/node-logger instead of console methods.

scripts/sandbox/utils/getPort.ts (1)

5-6: Refactor index lookups for efficiency.

The current implementation uses Object.values().indexOf() to find the index of an item you already have a key for. This is inefficient as it creates an array of all values and then searches linearly.

Apply this diff to improve the index lookup:

-  const templateIndex = Object.values(allTemplates).indexOf(allTemplates[template.key]);
-  const taskIndex = Object.values(tasks).indexOf(tasks[template.selectedTask]);
+  const templateIndex = Object.keys(allTemplates).indexOf(template.key);
+  const taskIndex = Object.keys(tasks).indexOf(template.selectedTask);

This directly searches for the key in the keys array, which is more straightforward and avoids the unnecessary value array creation.

.nx/workflows/distribution-config.yaml (2)

22-30: Clarify the commented-out e2e and test-runner targets.

The commented-out assignment rules for e2e-tests, e2e-tests-dev, test-runner, and test-runner-dev suggest these features are planned but not yet enabled. Consider adding a TODO comment explaining why these are disabled and when they should be re-enabled, or remove them if they're not part of the immediate roadmap.

Apply this diff to add clarifying context:

+  # TODO: Enable once e2e and test-runner infrastructure is ready
 #  - targets:
 #      - e2e-tests
 #      - e2e-tests-dev

35-35: Add trailing newline to YAML file.

The file is missing a trailing newline, which is a common convention for text files and can prevent issues with certain tools.

Ensure the file ends with a newline character.

scripts/get-template.ts (1)

304-306: Remove obvious comment.

The comment "Convert to integer" is unnecessary as the unary + operator's purpose is self-evident in this context.

Apply this diff:

-      // Convert to integer
       index: +CIRCLE_NODE_INDEX,
       total: +CIRCLE_NODE_TOTAL,
.github/copilot-instructions.md (1)

150-156: Tighten duplicated compile steps in “For Code Changes”

Steps 2 and 4 both compile packages, but use different working directories (yarn task --task compile vs cd code && yarn task --task compile). If only one of these is required with the new root layout, consider collapsing to a single, authoritative compile command to avoid confusion.

code/sandbox/cra-default-ts/project.json (1)

4-26: Empty tags means this sandbox is excluded from tag-based Nx CI runs

The implicitDependencies and dir: "cra-default-ts" wiring look consistent with template: "cra/default-ts" and prepare-sandbox’s template.replace('/', '-') behavior.

However, tags: [] means this project won’t be picked up by the new nx.yml workflow, which filters by tag:ci:normal, tag:ci:merged, etc. Please confirm that this sandbox is intentionally opt‑out from CI; otherwise, you likely want at least "ci:normal" here.

code/sandbox/react-native-web-vite-rn-cli-ts/project.json (1)

1-28: Validate directory slug and CI tagging for new RN Web/Vite sandbox

The name (react-native-web-vite/rn-cli-ts) and dir: "react-native-web-vite-rn-cli-ts" are consistent with the template.replace('/', '-') convention used in scripts/prepare-sandbox.ts, so path resolution should work.

As with cra-default-ts, tags: [] means this project won’t be included in tag‑filtered Nx runs (e.g., -p="tag:ci:normal" in nx.yml). If this sandbox should participate in standard CI, consider adding "ci:normal" (and optionally "ci:merged" / "ci:daily"); if it’s deliberately experimental/manual‑only, leaving it untagged is fine.

.nx/workflows/agents.yaml (1)

1-95: Align agent Node version and finalize Windows template before use

The agent templates look solid and the caching paths match the Yarn 4 monorepo layout. Two things to keep in mind:

  • Node version parity: The Linux images are ubuntu22.04-node20.19-v2, while the repo docs call out Node 22.16.0. If you rely on Node 22-specific behavior anywhere, consider switching to a Node 22 image for agents to avoid subtle discrepancies between local and remote runs.
  • windows-js template completeness: windows-js currently has no init-steps. Until those are filled in (checkout, cache, Node install, Yarn install), it’s safer not to reference this template from any workflows, otherwise tasks will likely fail immediately.

Everything else (caching keys, SANDBOX_ROOT, browser binaries cache) aligns well with the new CI model.

scripts/build-package.ts (1)

14-18: Simplify imports: consolidate path imports.

Both node:path and path are imported. Consider using only node:path for consistency.

-import { join } from 'node:path';
+import { join, resolve } from 'node:path';

 import { exec } from 'child_process';
 import { program } from 'commander';
-import { resolve } from 'path';
.circleci/src/jobs/chromatic-sandboxes.yml (1)

18-22: Align cd usage with new path-returning get-sandbox-dir and optionally quote it

Using cd $(yarn get-sandbox-dir --template $TEMPLATE) matches the new behavior of get-sandbox-dir returning a full directory path, so the functional change looks correct. To future‑proof against paths containing spaces, consider:

-        cd $(yarn get-sandbox-dir --template $TEMPLATE) && yarn
+        cd "$(yarn get-sandbox-dir --template "$TEMPLATE")" && yarn
scripts/get-sandbox-dir.ts (1)

1-16: New SANDBOX_DIRECTORY join matches sandbox path semantics; tighten template handling

Using join(SANDBOX_DIRECTORY, template.replace('/', '-')) is the right direction now that callers expect a full sandbox path rather than just a slug.

However, RunOptions still allows template to be undefined while run() assumes it’s always present:

type RunOptions = { template?: string };
// ...
console.log(join(SANDBOX_DIRECTORY, template.replace('/', '-')));

To avoid a TypeError when --template is omitted (e.g. from the CLI), consider:

-type RunOptions = {
-  template?: string;
-};
+type RunOptions = {
+  template: string;
+};

 async function run({ template }: RunOptions) {
   console.log(join(SANDBOX_DIRECTORY, template.replace('/', '-')));
 }

or defensively throwing a clear error if template is missing.

code/project.json (1)

1-30: Nx targets look correct; consider whether global build dependency is necessary

The lint, test, and knip targets are wired cleanly through nx:run-commands and correctly scoped to {projectRoot}.

Depending on [{ "projects": ["*"], "target": "build" }] for all three can make these checks quite heavy, since every project’s build must complete first. If that’s not strictly required, consider narrowing dependsOn (e.g., to dependencies of code or dropping it for lint/knip) to keep CI times in check.

scripts/task.ts (1)

441-442: Verify the necessity of optional chaining.

The optional chaining suggests tasksThatDepend.get(task) might return undefined, but based on the getTaskList function logic, every task added to tasksThatDepend should have an array value (possibly empty, but never undefined).

If tasksThatDepend.get(task) is guaranteed to return an array, consider removing the optional chaining for clarity:

-    tasksThatDepend
-      .get(task)
-      ?.filter((t) => !t.service)
-      ?.forEach(setUnready);
+    tasksThatDepend
+      .get(task)
+      .filter((t) => !t.service)
+      .forEach(setUnready);
.env (1)

1-3: Address dotenv linting issues.

The static analysis tool flagged minor style issues: key ordering and missing trailing newline. While these don't affect functionality, fixing them improves consistency.

Apply this diff:

+IN_STORYBOOK_SANDBOX=true
+SANDBOX_ROOT=../storybook-sandboxes
 STORYBOOK_DISABLE_TELEMETRY=true
-IN_STORYBOOK_SANDBOX=true
-SANDBOX_ROOT=../storybook-sandboxes
+

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
scripts/create-nx-sandbox-projects.ts (1)

76-100: Fix async forEach - promises won't be awaited.

This issue was previously flagged. Using forEach with an async callback doesn't wait for promises to resolve, which means the script could exit before all files are written.

Replace with a proper async iteration pattern:

-Object.entries(allTemplates).forEach(async ([key, value]) => {
+for (const [key, value] of Object.entries(allTemplates)) {
   const p = key.replaceAll('/', '-');
   const full = join(process.cwd(), '../code/sandbox', p, 'project.json');
 
-  console.log(full);
   const framework = value.expected.framework;
   const project = framework.includes('@storybook/')
     ? framework.replace('@storybook/', '')
     : undefined;
-  console.log(project);
-  console.log();
+
   const tags = [
     ...(normal.includes(key as any) && !value.inDevelopment ? ['ci:normal'] : []),
     ...(merged.includes(key as any) && !value.inDevelopment ? ['ci:merged'] : []),
     ...(daily.includes(key as any) && !value.inDevelopment ? ['ci:daily'] : []),
   ];
+
   ensureDirectoryExistence(full);
-  console.log(full);
 
   const data = await prettier.format(JSON.stringify(projectJson(key, project, tags, value)), {
     filepath: full,
   });
 
   writeFileSync(full, data, { encoding: 'utf-8' });
-});
+}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a26a9f7 and cc883eb.

📒 Files selected for processing (47)
  • code/addons/a11y/project.json (1 hunks)
  • code/addons/docs/project.json (1 hunks)
  • code/addons/links/project.json (1 hunks)
  • code/addons/onboarding/project.json (1 hunks)
  • code/addons/pseudo-states/project.json (1 hunks)
  • code/addons/themes/project.json (1 hunks)
  • code/addons/vitest/project.json (1 hunks)
  • code/builders/builder-vite/project.json (1 hunks)
  • code/builders/builder-webpack5/project.json (1 hunks)
  • code/core/project.json (1 hunks)
  • code/frameworks/angular/project.json (1 hunks)
  • code/frameworks/ember/project.json (1 hunks)
  • code/frameworks/html-vite/project.json (1 hunks)
  • code/frameworks/nextjs-vite/project.json (1 hunks)
  • code/frameworks/nextjs/project.json (1 hunks)
  • code/frameworks/preact-vite/project.json (1 hunks)
  • code/frameworks/react-native-web-vite/project.json (1 hunks)
  • code/frameworks/react-vite/project.json (1 hunks)
  • code/frameworks/react-webpack5/project.json (1 hunks)
  • code/frameworks/server-webpack5/project.json (1 hunks)
  • code/frameworks/svelte-vite/project.json (1 hunks)
  • code/frameworks/sveltekit/project.json (1 hunks)
  • code/frameworks/vue3-vite/project.json (1 hunks)
  • code/frameworks/web-components-vite/project.json (1 hunks)
  • code/lib/cli-storybook/project.json (1 hunks)
  • code/lib/codemod/project.json (1 hunks)
  • code/lib/core-webpack/project.json (1 hunks)
  • code/lib/create-storybook/project.json (1 hunks)
  • code/lib/csf-plugin/project.json (1 hunks)
  • code/lib/eslint-plugin/project.json (1 hunks)
  • code/lib/react-dom-shim/project.json (1 hunks)
  • code/presets/create-react-app/project.json (1 hunks)
  • code/presets/react-webpack/project.json (1 hunks)
  • code/presets/server-webpack/project.json (1 hunks)
  • code/project.json (1 hunks)
  • code/renderers/html/project.json (1 hunks)
  • code/renderers/preact/project.json (1 hunks)
  • code/renderers/react/project.json (1 hunks)
  • code/renderers/server/project.json (1 hunks)
  • code/renderers/svelte/project.json (1 hunks)
  • code/renderers/vue3/project.json (1 hunks)
  • code/renderers/web-components/project.json (1 hunks)
  • nx.json (1 hunks)
  • scripts/create-nx-sandbox-projects.ts (1 hunks)
  • scripts/project.json (1 hunks)
  • scripts/tasks/compile.ts (3 hunks)
  • test-storybooks/yarn-pnp/project.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (19)
  • code/frameworks/sveltekit/project.json
  • code/project.json
  • code/renderers/react/project.json
  • code/renderers/web-components/project.json
  • code/presets/server-webpack/project.json
  • code/frameworks/react-native-web-vite/project.json
  • scripts/project.json
  • code/frameworks/vue3-vite/project.json
  • code/addons/pseudo-states/project.json
  • code/addons/a11y/project.json
  • code/lib/create-storybook/project.json
  • code/lib/codemod/project.json
  • code/lib/core-webpack/project.json
  • code/addons/links/project.json
  • code/renderers/html/project.json
  • code/addons/themes/project.json
  • code/renderers/preact/project.json
  • code/lib/csf-plugin/project.json
  • code/frameworks/nextjs/project.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/builders/builder-webpack5/project.json
  • code/frameworks/preact-vite/project.json
  • code/addons/docs/project.json
  • code/frameworks/html-vite/project.json
  • nx.json
  • code/frameworks/server-webpack5/project.json
  • code/addons/vitest/project.json
  • code/frameworks/ember/project.json
  • code/frameworks/angular/project.json
  • code/addons/onboarding/project.json
  • code/builders/builder-vite/project.json
  • code/frameworks/nextjs-vite/project.json
  • code/lib/eslint-plugin/project.json
  • test-storybooks/yarn-pnp/project.json
  • scripts/tasks/compile.ts
  • code/frameworks/svelte-vite/project.json
  • code/frameworks/react-webpack5/project.json
  • code/renderers/vue3/project.json
  • code/renderers/server/project.json
  • code/lib/react-dom-shim/project.json
  • code/presets/create-react-app/project.json
  • code/frameworks/react-vite/project.json
  • code/lib/cli-storybook/project.json
  • code/frameworks/web-components-vite/project.json
  • code/presets/react-webpack/project.json
  • code/renderers/svelte/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/core/project.json
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/tasks/compile.ts
  • scripts/create-nx-sandbox-projects.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/tasks/compile.ts
  • scripts/create-nx-sandbox-projects.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • nx.json
  • code/addons/vitest/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Use ESLint and Prettier for code style enforcement

Applied to files:

  • code/lib/eslint-plugin/project.json
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • test-storybooks/yarn-pnp/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'yarn vitest run --coverage <test-file>' to run tests with coverage reports and aim for 75%+ coverage of statements/lines

Applied to files:

  • test-storybooks/yarn-pnp/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • test-storybooks/yarn-pnp/project.json
  • scripts/tasks/compile.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager

Applied to files:

  • test-storybooks/yarn-pnp/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn prettier --write <file>' to format code after making changes

Applied to files:

  • test-storybooks/yarn-pnp/project.json
  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • test-storybooks/yarn-pnp/project.json
  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Tests are located in the `code/` directory with root directory for test execution at `./code/`

Applied to files:

  • scripts/tasks/compile.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • code/lib/cli-storybook/project.json
  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Run 'yarn task --task check' to verify TypeScript types across all packages before submitting PRs

Applied to files:

  • code/renderers/svelte/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn lint:js:cmd <file>' to check for ESLint issues after making changes

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
🧬 Code graph analysis (1)
scripts/create-nx-sandbox-projects.ts (2)
code/lib/cli-storybook/src/sandbox-templates.ts (5)
  • Template (30-106)
  • allTemplates (988-992)
  • normal (994-1013)
  • merged (1015-1024)
  • daily (1026-1049)
scripts/utils/tools.ts (2)
  • process (115-115)
  • prettier (122-122)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (31)
nx.json (4)

56-62: Verify sandbox output path alignment with PR objectives.

The PR objectives state sandboxes are being moved to ../storybook-sandboxes, but this target specifies output to {workspaceRoot}/sandbox/{options.dir}. Clarify whether:

  • The output path should reference ../storybook-sandboxes instead, or
  • The environment variable SANDBOX_ROOT mentioned in PR objectives should control this path dynamically.

198-216: Align namedInputs paths with monorepo root refactoring.

The PR objective is to refactor from ./code root to git root, but namedInputs still references {workspaceRoot}/code/tsconfig.json (line 200) and {workspaceRoot}/code/**/* (lines 213–214). Verify whether:

  • tsconfig.json should now be at the repository root (Line 200), or
  • These paths should remain under code/ for the new structure.

Additionally, confirm that the sharedGlobals input (line 199) correctly captures all shared configuration files needed by targets at the new root level.


1-22: Configuration structure looks solid.

The core Nx configuration (schema, cloud ID, parallelism, plugin settings, task runner options) is well-structured and appropriately configured for a TypeScript monorepo with inference plugins disabled and analytics disabled.


58-58: All sandbox-enabled projects consistently define {options.dir}. Verification confirms that all 47 projects in code/sandbox/*/project.json define the sandbox target with the required options.dir configuration. No inconsistencies found.

code/addons/onboarding/project.json (3)

8-8: Tags configuration looks good.

The "ci:normal" tag aligns with the PR's objective to centralize CI behavior and organize targets by CI tier.


1-9: Based on my verification, I found that the original review comment is based on an incorrect premise. The file code/addons/onboarding/project.json is new (created in this PR), not modified. The $schema property was never present in this file to begin with, so no removal occurred.

However, the underlying verification points are still valid and have been confirmed:

  1. Centralized schema validation exists: The root nx.json file contains "$schema": "./node_modules/nx/schemas/workspace-schema.json", providing workspace-level schema configuration.

  2. IDE tooling doesn't depend on per-file schema: VSCode settings are not configured to validate individual project.json files using per-file schema declarations. Validation is handled centrally or through other mechanisms (ESLint for JSON linting).

  3. No tooling depends on per-file schema: The repository's ESLint configuration validates JSON files separately from schema validation. NX CLI validates project.json files using its own internal schema logic, independent of per-file $schema references.

File is newly created, not modified. No schema was removed.

Likely an incorrect or invalid review comment.


5-6: Perfect! I now have all the information needed. The verification shows that the empty target definitions are intentional and correct. Let me provide the final rewritten review comment:


No issues found with the empty target definitions.

The empty compile and check targets in this project.json are correct. This follows the Nx targetDefaults pattern where individual project configurations declare targets as empty objects, with the actual implementation provided centrally in nx.json. The scripts/tasks/compile.ts and scripts/tasks/check.ts files invoke these via yarn nx run-many -t compile and yarn nx run-many -t check, which properly resolve the target definitions from nx.json's targetDefaults section. This pattern is consistently used across all addon project files (a11y, docs, links, pseudo-states, themes, vitest) and is the intended monorepo architecture.

code/lib/cli-storybook/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

code/renderers/server/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

code/frameworks/web-components-vite/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

code/addons/docs/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

code/addons/vitest/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

test-storybooks/yarn-pnp/project.json (3)

6-6: Verify the broad dependency scope on all projects' compile targets.

The test target depends on compiling all projects (["*"]). In a large monorepo, this could be expensive and may be unnecessary for a yarn-pnp smoke test. Verify whether this dependency scope is intentional, or if it should be narrowed to only the required projects for this particular test storybook.


10-10: Verify the --no-immutable flag is appropriate for CI context.

The command uses yarn --no-immutable, which allows installing new or different dependency versions. For a CI smoke test, confirm this is the intended behavior. If reproducibility and consistency are required, consider using --immutable instead to enforce exact version matching.


1-18: New test target structure looks good overall.

The test target is well-structured, uses nx:run-commands appropriately, and includes proper working directory scoping. The configuration placeholder for production and the ci:normal tag align with the broader refactor pattern.

code/frameworks/ember/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

code/frameworks/preact-vite/project.json (1)

4-8: Verify centralized target configuration for compile and check targets.

The compile and check targets are empty objects, suggesting they're implemented via inheritance or a centralized Nx config. Ensure that the root-level Nx configuration (or relevant parent project configs) properly defines the executors and options for these targets so the build pipeline functions as intended.

code/frameworks/svelte-vite/project.json (1)

5-8: LGTM: Standardized Nx target structure.

The migration from a single build target to separate compile and check targets, along with the CI classification tag, aligns with the repository-wide standardization pattern.

code/lib/eslint-plugin/project.json (1)

5-8: LGTM: Consistent target migration.

The standardization to compile/check targets with CI tagging is consistent across the repository.

scripts/create-nx-sandbox-projects.ts (2)

95-97: Good addition: Prettier formatting for generated files.

Using Prettier to format the generated JSON files ensures consistency and readability.


35-72: Based on my verification, I've discovered a critical issue. Let me generate the final rewritten review comment:

Generated project.json files are out of sync with the current code — naming mismatch detected.

The conditional target generation logic itself is correct:

  • typeCheck === true properly includes the 'check-sandbox' target (verified with react-vite-default-ts)
  • skipTasks array filtering works as expected across all template variants
  • inDevelopment flag is intentionally not used in target generation (only for CI tags)

However, the generated project.json files in code/sandbox/ contain mismatched target names:

  • Code defines: 'prepare-sandbox' and 'prepare-build-sandbox'
  • Generated files contain: 'prepared-sandbox' and 'prepared-build-sandbox'

The generated project.json files must be regenerated to match the current code by running scripts/create-nx-sandbox-projects.ts.

⛔ Skipped due to learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Run 'yarn task --task check' to verify TypeScript types across all packages before submitting PRs
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
code/frameworks/nextjs-vite/project.json (1)

5-8: LGTM: Consistent standardization.

The target migration follows the established pattern across the repository.

scripts/tasks/compile.ts (3)

15-16: LGTM: Updated commands align with new target structure.

The change from build to compile target and from npx to yarn is consistent with the repository-wide refactoring.


45-45: LGTM: Working directory updated for new monorepo root.

Changing the working directory from codeDir to ROOT_DIRECTORY correctly reflects the monorepo root migration from ./code to the git root.


5-5: ROOT_DIRECTORY correctly points to the git root.

The constant is properly defined in scripts/utils/constants.ts at line 8 as join(__dirname, '..', '..'), which resolves from scripts/utils/ to the repository root. It serves as the base for all other directory constants (CODE_DIRECTORY, SNIPPETS_DIRECTORY, PACKS_DIRECTORY, etc.), confirming it supports the monorepo root refactoring as intended.

code/core/project.json (1)

5-8: LGTM: Core package aligned with repository standard.

The standardized target structure is now consistently applied across the repository, including the core package.

code/renderers/vue3/project.json (1)

5-18: LGTM: Well-structured check target with proper dependencies.

The check target correctly depends on the compile target and uses the standard Vue type-checking command. Verification confirms vue-tsc is available in the project dependencies (code/renderers/vue3/package.json, line 59).

code/renderers/svelte/project.json (1)

5-18: LGTM: Proper check target implementation with verified dependencies.

The check target is correctly configured with the standard Svelte type-checking command and appropriate dependency ordering. Verification confirms svelte-check is available in the project as a devDependency (version ^4.3.2).

code/builders/builder-vite/project.json (2)

8-8: Verify CI system recognizes the ci:normal tag.

The tags field with ["ci:normal"] appears to be a new CI classification strategy. Ensure that:

  • CI/CD pipeline configuration (GitHub Actions, etc.) recognizes and uses these tags appropriately
  • This aligns with NX agent configuration mentioned in the PR objectives
  • Tag values are documented or consistent across all projects being refactored

5-7: No action needed—empty targets with inherited executors from targetDefaults is the correct NX pattern and is consistently applied across all packages in the workspace.

The compile and check targets in code/builders/builder-vite/project.json are correctly configured as empty objects. They inherit their executor definitions, commands, caching rules, and other configuration from the root nx.json targetDefaults, which define:

  • compile: runs yarn exec jiti ./scripts/build/build-package.ts --cwd {projectRoot}
  • check: runs yarn exec jiti ./scripts/check/check-package.ts --cwd {projectRoot}

This pattern is consistent across the entire workspace (verified in code/addons/a11y, code/addons/docs, code/addons/links, etc.). NX can discover and execute these targets via nx run builder-vite:compile and nx run builder-vite:check, and the yarn task command in package.json (which delegates to scripts/task.ts) works correctly with this setup.

code/frameworks/html-vite/project.json (1)

5-8: Identical pattern and same verification requirements as builder-vite.

This file has the same structure and changes as code/builders/builder-vite/project.json. The verification concerns about empty target configuration and CI tag recognition apply here as well. Given this pattern is applied across multiple projects, consider:

  • Creating a base/shared project.json configuration if not already done
  • Documenting the executor definitions that are referenced by these empty targets
  • Adding a validation check to the CI pipeline to ensure all projects have complete executor definitions

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
code/sandbox/qwik-vite-default-ts/project.json (1)

4-11: Add "qwik-vite" to implicitDependencies array.

This is still missing from the previous review. All similar sandbox configurations include their corresponding framework in implicitDependencies: html-vite, react-vite, svelte-vite, and sveltekit all follow this pattern. Add "qwik-vite" as the final entry to maintain consistency and ensure Nx correctly tracks dependencies.

Apply this diff:

  "implicitDependencies": [
    "core",
    "cli",
    "addon-a11y",
    "addon-docs",
    "addon-vitest",
-   "addon-onboarding"
+   "addon-onboarding",
+   "qwik-vite"
  ],
code/sandbox/solid-vite-default-js/project.json (1)

13-22: Missing vitest-integration target breaks consistency with TS variant and other JS frameworks.

Line 9 specifies addon-vitest in implicitDependencies, yet the vitest-integration target is absent. This target exists in the TS counterpart (line 16) and in other JS variants (vue3-vite-default-js, react-vite-default-js), making this a breaking inconsistency.

Add "vitest-integration": {} between the dev and build-sandbox targets:

   "dev": {},
+  "vitest-integration": {},
   "build-sandbox": { "options": { "dir": "solid-vite-default-js" } },
🧹 Nitpick comments (3)
code/sandbox/angular-cli-prerelease/project.json (1)

4-12: Verify that all implicit dependencies are actually used by this sandbox.

The implicitDependencies list has been significantly expanded to include cli, addon-a11y, addon-docs, and addon-vitest. Ensure these packages are actually imported or required by the angular-cli-prerelease sandbox; unused dependencies should be removed to keep the dependency graph accurate.

scripts/create-nx-sandbox-projects.ts (2)

76-80: Async handling fixed, but process.cwd()-based path is brittle

Switching to await Promise.all(Object.entries(allTemplates).map(async ...)) correctly ensures all async work completes before the script exits and addresses the previous forEach(async ...) issue. 👍

However, building full as:

const full = join(process.cwd(), '../code/sandbox', p, 'project.json');

means the output location depends on where the script is invoked. With the monorepo root now at ., running this from the repo root will resolve to a sibling ../code/sandbox/..., whereas running it from ./scripts resolves to ./code/sandbox/.... That can easily drift if someone calls the script differently or via CI.

I’d recommend deriving the path relative to the repo (or script) root instead of process.cwd() to make it location-independent, or at least double-check that all callers intentionally run it from a directory where this resolves to the correct sandbox folder.

Please verify how this script is invoked in package.json / CI and confirm that ../code/sandbox resolves to the intended directory in all cases, given the monorepo root refactor.


81-87: Consider trimming or structuring debug logging

There are multiple console.log calls (full logged twice, project, and an empty console.log()), which look primarily diagnostic.

If this script is going to be run frequently in CI or by contributors, consider:

  • consolidating into a single, structured log per project, or
  • removing the purely debug/duplicate logs (including the empty console.log()).

This will keep output noise down while still being debuggable when needed.

Also applies to: 94-94

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cc883eb and 2b6f89a.

📒 Files selected for processing (51)
  • .github/copilot-instructions.md (5 hunks)
  • code/frameworks/nextjs/src/next-image-loader-stub.ts (1 hunks)
  • code/renderers/web-components/src/docs/web-components-properties.test.ts (1 hunks)
  • code/sandbox/angular-cli-default-ts/project.json (1 hunks)
  • code/sandbox/angular-cli-prerelease/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/cra-default-js/project.json (1 hunks)
  • code/sandbox/cra-default-ts/project.json (1 hunks)
  • code/sandbox/ember-3-js/project.json (1 hunks)
  • code/sandbox/ember-default-js/project.json (1 hunks)
  • code/sandbox/html-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/html-vite-default-js/project.json (1 hunks)
  • code/sandbox/html-vite-default-ts/project.json (1 hunks)
  • code/sandbox/internal-react16-webpack/project.json (1 hunks)
  • code/sandbox/internal-react18-webpack-babel/project.json (1 hunks)
  • code/sandbox/internal-server-webpack5/project.json (1 hunks)
  • code/sandbox/lit-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/lit-vite-default-js/project.json (1 hunks)
  • code/sandbox/lit-vite-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-prerelease/project.json (1 hunks)
  • code/sandbox/nextjs-vite-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-default-ts/project.json (1 hunks)
  • code/sandbox/preact-vite-default-js/project.json (1 hunks)
  • code/sandbox/preact-vite-default-ts/project.json (1 hunks)
  • code/sandbox/qwik-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-expo-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json (1 hunks)
  • code/sandbox/react-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-default-js/project.json (1 hunks)
  • code/sandbox/react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-prerelease-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-17-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-prerelease-ts/project.json (1 hunks)
  • code/sandbox/solid-vite-default-js/project.json (1 hunks)
  • code/sandbox/solid-vite-default-ts/project.json (1 hunks)
  • code/sandbox/svelte-kit-skeleton-ts/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-js/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-js/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-ts/project.json (1 hunks)
  • scripts/create-nx-sandbox-projects.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • code/sandbox/nextjs-15-ts/project.json
🚧 Files skipped from review as they are similar to previous changes (19)
  • .github/copilot-instructions.md
  • code/sandbox/nextjs-14-ts/project.json
  • code/frameworks/nextjs/src/next-image-loader-stub.ts
  • code/sandbox/nextjs-vite-15-ts/project.json
  • code/renderers/web-components/src/docs/web-components-properties.test.ts
  • code/sandbox/html-vite-default-js/project.json
  • code/sandbox/react-native-web-vite-expo-ts/project.json
  • code/sandbox/react-rsbuild-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/sandbox/html-rsbuild-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/lit-rsbuild-default-ts/project.json
  • code/sandbox/nextjs-vite-default-ts/project.json
  • code/sandbox/internal-react18-webpack-babel/project.json
  • code/sandbox/cra-default-js/project.json
  • code/sandbox/vue3-rsbuild-default-ts/project.json
  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/sandbox/react-webpack-18-ts/project.json
  • code/sandbox/nextjs-prerelease/project.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/sandbox/nextjs-default-ts/project.json
  • code/sandbox/svelte-vite-default-ts/project.json
  • code/sandbox/internal-react16-webpack/project.json
  • code/sandbox/angular-cli-default-ts/project.json
  • code/sandbox/cra-default-ts/project.json
  • code/sandbox/react-webpack-17-ts/project.json
  • code/sandbox/html-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/sandbox/nextjs-vite-14-ts/project.json
  • code/sandbox/react-vite-default-ts/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/svelte-kit-skeleton-ts/project.json
  • code/sandbox/ember-default-js/project.json
  • code/sandbox/ember-3-js/project.json
  • code/sandbox/preact-vite-default-ts/project.json
  • code/sandbox/react-vite-default-js/project.json
  • code/sandbox/react-webpack-prerelease-ts/project.json
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/preact-vite-default-js/project.json
  • code/sandbox/qwik-vite-default-ts/project.json
  • code/sandbox/internal-server-webpack5/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/sandbox/lit-vite-default-js/project.json
  • code/sandbox/solid-vite-default-js/project.json
  • code/sandbox/angular-cli-prerelease/project.json
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • code/sandbox/svelte-vite-default-js/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/vue3-vite-default-js/project.json
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/create-nx-sandbox-projects.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/create-nx-sandbox-projects.ts
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • code/sandbox/svelte-vite-default-ts/project.json
  • code/sandbox/html-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/sandbox/nextjs-vite-14-ts/project.json
  • code/sandbox/react-vite-default-ts/project.json
  • code/sandbox/preact-vite-default-ts/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/qwik-vite-default-ts/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • code/sandbox/svelte-vite-default-ts/project.json
  • code/sandbox/html-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/sandbox/nextjs-vite-14-ts/project.json
  • code/sandbox/react-vite-default-ts/project.json
  • code/sandbox/preact-vite-default-ts/project.json
  • code/sandbox/react-vite-default-js/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/preact-vite-default-js/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn prettier --write <file>' to format code after making changes

Applied to files:

  • code/sandbox/nextjs-vite-14-ts/project.json
  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn lint:js:cmd <file>' to check for ESLint issues after making changes

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid inline mock implementations within test cases in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Keep mock implementations simple and focused in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking without the `spy: true` option in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mock implementations outside of `beforeEach` blocks in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid direct function mocking without `vi.mocked()` in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Document complex mock behaviors in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required properties and methods that the test subject uses in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
🧬 Code graph analysis (1)
scripts/create-nx-sandbox-projects.ts (2)
code/lib/cli-storybook/src/sandbox-templates.ts (5)
  • Template (30-106)
  • allTemplates (988-992)
  • normal (994-1013)
  • merged (1015-1024)
  • daily (1026-1049)
scripts/utils/tools.ts (2)
  • process (115-115)
  • prettier (122-122)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
nx.json (1)

56-96: Based on my verification, I have gathered sufficient information to rewrite the review comment. The analysis confirms the core concerns while revealing some additional nuance.


Clarify the sandbox target dependency optimization opportunity.

The prepare-sandbox and prepare-build-sandbox targets have redundant explicit dependencies on scripts/run-registry. The prepare-sandbox target already depends on sandbox, which depends on run-registry; similarly, prepare-build-sandbox depends on build, which chains back to run-registry. Since run-registry is defined as continuous, these direct re-declarations are unnecessary and can be removed, allowing Nx to resolve the dependency once via the chain.

Consider removing the explicit { "projects": ["scripts"], "target": "run-registry" } from prepare-sandbox and prepare-build-sandbox to simplify the dependency graph.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b6f89a and 1590fda.

📒 Files selected for processing (2)
  • nx.json (1 hunks)
  • scripts/prepare-sandbox.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/prepare-sandbox.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • nx.json
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • nx.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (2)
nx.json (2)

30-33: I'll help you verify the path reference in nx.json. Let me start by examining the directory structure and the nx.json file itself.
<function_calls>

#!/bin/bash

Verify the code directory structure exists

ls -la code/bench/ 2>/dev/null || echo "code/bench/ not found"
ls -la code/ 2>/dev/null | head -20


</function_calls>

Now let me examine the nx.json file to understand the full context:
<function_calls>

#!/bin/bash

Read the nx.json file around lines 30-33 with context

wc -l nx.json
cat -n nx.json | sed -n '25,40p'


</function_calls>

Let me also search for other references to this path in the codebase:
<function_calls>

#!/bin/bash

Search for references to bench/esbuild-metafiles

rg "bench/esbuild-metafiles" -n -C 3

Also search for compile target configuration

rg "compile" nx.json -n -C 5


</function_calls>


198-216: Yes, please provide the exact file paths for all tsconfig.json files that exist on the default branch of storybookjs/storybook.

@kasperpeulen kasperpeulen force-pushed the kasper/yarn-monorepo-refactor branch from 93f088f to 24aa914 Compare November 26, 2025 17:50
@valentinpalkovic
Copy link
Contributor

Please update and lookup our contribution guidelines/markdown files and watch out whether they need any update

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/release/version.ts (1)

80-86: Guard against schema.releaseType being undefined in superRefine

schema.releaseType is optional, but schema.releaseType.startsWith('pre') is called unconditionally when preId is present, which will throw a runtime error if a user passes --pre-id without --release-type instead of producing a ZodError.

A small defensive tweak keeps behavior while avoiding this edge-case crash:

-    if (schema.preId && !schema.releaseType.startsWith('pre')) {
+    const isPreReleaseType =
+      typeof schema.releaseType === 'string' && schema.releaseType.startsWith('pre');
+    if (schema.preId && !isPreReleaseType) {
       ctx.addIssue({
         code: z.ZodIssueCode.custom,
         message:
           'Using prerelease identifier requires one of release types: premajor, preminor, prepatch, prerelease',
       });
     }
♻️ Duplicate comments (5)
scripts/build/utils/generate-types.ts (2)

21-25: Update concurrency comment to match the actual limit(10) behavior

The comment still says “we limit the number of concurrent processes to 3” and “3 seems to be the sweet spot”, but the code uses limit(10). This can easily confuse anyone tuning build performance.

Consider updating the comment to reflect the current concurrency:

-  // we limit the number of concurrent processes to 3, because we don't want to overload the host machine
-  // by trial and error, 3 seems to be the sweet spot between perf and consistency
+  // we limit the number of concurrent processes to 10, because we don't want to overload the host machine
+  // by trial and error, 10 seems to be the sweet spot between perf and consistency

After editing, please run the usual formatting and lint commands for this file as per the repo guidelines.


64-70: Confirm 20‑minute timeout and consider extracting a named constant

1200000 here is 20 minutes, which is a long time to leave a potentially hung dts-process running. If that’s intentional to accommodate slow builds, fine—but it’s worth double‑checking, and the magic number would be clearer as a named constant:

-const DIR_CODE = join(import.meta.dirname, '..', '..', '..', 'code');
+const DIR_CODE = join(import.meta.dirname, '..', '..', '..', 'code');
+const DTS_TIMEOUT_MS = 20 * 60 * 1000;
@@
-            timer = setTimeout(() => {
+            timer = setTimeout(() => {
@@
-              dtsProcess.kill(408); // timed out
-              resolve(void 0);
-            }, 1200000);
+              dtsProcess.kill(408); // timed out
+              resolve(void 0);
+            }, DTS_TIMEOUT_MS);

Please confirm that 20 minutes is the intended timeout; if not, this is a good place to adjust it now.

nx.json (2)

57-64: Fix {options.dir} placeholder in sandbox target outputs—unresolved from prior review.

Line 62 uses the undefined {options.dir} placeholder. This was flagged in prior reviews but remains unresolved. Nx only recognizes {projectRoot} and {workspaceRoot}. The command correctly uses {projectName} (line 59), so outputs should too.

-      "outputs": ["{workspaceRoot}/sandbox/{options.dir}"],
+      "outputs": ["{workspaceRoot}/sandbox/{projectName}"],

78-85: Fix {options.dir} placeholder in build target outputs—unresolved from prior review.

Line 83 repeats the same invalid placeholder. Replace with {projectName} to align with the command pattern and restore proper Nx caching.

-      "outputs": ["{workspaceRoot}/sandbox/{options.dir}/storybook-static"],
+      "outputs": ["{workspaceRoot}/sandbox/{projectName}/storybook-static"],
scripts/prepare-sandbox.ts (1)

34-38: Still missing cache existence guard and background exec error handling

Two minor robustness issues remain (both already noted in a prior review):

  1. Cache directory assumptions (Lines 34–38)
    If cacheDir doesn’t exist (e.g. first run for a template), cp(cacheDir, sandboxDir, …) will reject. A clearer behavior would be to either (a) warn and skip the copy, or (b) fail with an explicit message about how to create/populate the cache.

  2. Fire‑and‑forget exec can reject unnoticed (Lines 51–57)
    exec('yarn local-registry --open', …) is called and discarded. If that Promise rejects, the error won’t be observed, even though you later rely on waitOn to confirm readiness. Wrapping the call in .catch(() => {}) preserves the existing behavior while avoiding stray unhandled rejections and noisy logs.

A possible adjustment:

-    if (sandboxDir !== cacheDir) {
-      console.log(`🧹 copying cached ${cacheDir} to ${sandboxDir}`);
-      await rm(sandboxDir, { recursive: true, force: true });
-      await cp(cacheDir, sandboxDir, { recursive: true, force: true });
-    }
+    if (sandboxDir !== cacheDir) {
+      if (!existsSync(cacheDir)) {
+        console.warn(`⚠️ cache directory ${cacheDir} does not exist; skipping cache copy`);
+      } else {
+        console.log(`🧹 copying cached ${cacheDir} to ${sandboxDir}`);
+        await rm(sandboxDir, { recursive: true, force: true });
+        await cp(cacheDir, sandboxDir, { recursive: true, force: true });
+      }
+    }
@@
-        void exec('yarn local-registry --open', { cwd: CODE_DIRECTORY });
+        void exec('yarn local-registry --open', { cwd: CODE_DIRECTORY }).catch(() => {
+          // best-effort; readiness is validated by waitOn below
+        });

Also applies to: 51-57

🧹 Nitpick comments (8)
scripts/create-nx-sandbox-projects.ts (3)

86-99: Remove redundant logging.

Lines 86 and 99 both log the same full path. Remove the duplicate to reduce noise.

Apply this diff:

-    console.log(full);
     const framework = value.expected.framework;
     const project = framework.includes('@storybook/')
       ? framework.replace('@storybook/', '')
       : undefined;
     console.log(project);
     console.log();
     const tags = [
       ...(normal.includes(key as any) && !value.inDevelopment ? ['ci:normal'] : []),
       ...(merged.includes(key as any) && !value.inDevelopment ? ['ci:merged'] : []),
       ...(daily.includes(key as any) && !value.inDevelopment ? ['ci:daily'] : []),
     ];
     ensureDirectoryExistence(full);
     console.log(full);

101-105: Consider adding error handling for formatting and file operations.

If prettier.format fails (e.g., due to invalid JSON structure) or writeFileSync encounters a disk error, the script will crash without a clear indication of which template failed. Consider wrapping these operations in a try-catch block to provide better error messages.

Apply this diff to add error handling:

+    try {
       const data = await prettier.format(JSON.stringify(projectJson(key, project, tags, value)), {
         filepath: full,
       });
 
       writeFileSync(full, data, { encoding: 'utf-8' });
+    } catch (error) {
+      console.error(`Failed to generate project.json for ${key}:`, error);
+      throw error;
+    }

109-116: Consider using Node.js built-in recursive directory creation.

The ensureDirectoryExistence function manually implements recursive directory creation. Node.js mkdirSync has a built-in recursive: true option that achieves the same result more simply.

Apply this diff to simplify:

-function ensureDirectoryExistence(filePath: string): void {
-  const dir = dirname(filePath);
-  if (existsSync(dir)) {
-    return;
-  }
-  ensureDirectoryExistence(dir);
-  mkdirSync(dir);
-}
+function ensureDirectoryExistence(filePath: string): void {
+  const dir = dirname(filePath);
+  mkdirSync(dir, { recursive: true });
+}
.env (1)

1-3: Reorder environment variables alphabetically and add trailing newline.

The dotenv-linter tool flags the file for unordered keys and a missing blank line at EOF. While not functionally critical, these are standard conventions for configuration files.

Apply this diff to address the linting warnings:

-STORYBOOK_DISABLE_TELEMETRY=true
-IN_STORYBOOK_SANDBOX=true
-SANDBOX_ROOT=../storybook-sandboxes
+IN_STORYBOOK_SANDBOX=true
+SANDBOX_ROOT=../storybook-sandboxes
+STORYBOOK_DISABLE_TELEMETRY=true
code/sandbox/cra-default-js/project.json (1)

4-25: Confirm that dropping all ci:* tags for this sandbox is intentional

The new targets and expanded implicitDependencies look consistent with the other sandboxes, but tags is now an empty array. Given the Nx workflow filters projects via ci:* tags, this means cra/default-js won’t run in the new Nx CI job at all and will only be exercised by the existing non‑Nx pipelines (if any).

If that’s deliberate (e.g., to keep this sandbox out of the experimental Nx job), all good; otherwise, consider restoring an appropriate ci:* tag set (for example, ["ci:daily"] as before).

scripts/run-registry.ts (1)

46-62: Consider extracting the duplicated port-clearing logic.

The port-clearing blocks for 6001 and 6002 are nearly identical. A helper function would reduce duplication and make future maintenance easier.

+const clearPort = async (port: number) => {
+  if (await isPortUsed(port)) {
+    await killProcessOnPort(port);
+    let attempts = 0;
+    while ((await isPortUsed(port)) && attempts < 10) {
+      await sleep(1000);
+      attempts++;
+    }
+  }
+};
+
 const startVerdaccio = async () => {
-  // Kill Verdaccio related processes if they are already running
-  if (await isPortUsed(6001)) {
-    await killProcessOnPort(6001);
-
-    let attempts = 0;
-    while ((await isPortUsed(6001)) && attempts < 10) {
-      await sleep(1000);
-      attempts++;
-    }
-  }
-  if (await isPortUsed(6002)) {
-    await killProcessOnPort(6002);
-    let attempts = 0;
-    while ((await isPortUsed(6002)) && attempts < 10) {
-      await sleep(1000);
-      attempts++;
-    }
-  }
+  // Kill Verdaccio related processes if they are already running
+  await clearPort(6001);
+  await clearPort(6002);
package.json (1)

3-17: Avoid hard‑coding ../storybook-sandboxes in ecosystem‑CI scripts

The new svelte-ecosystem-ci:before-test and vite-ecosystem-ci:before-test scripts cd into ../storybook-sandboxes/... directly. Since the rest of this PR introduces SANDBOX_ROOT/SANDBOX_DIRECTORY to make the sandbox root configurable, consider routing these scripts through the same mechanism (or at least honoring SANDBOX_ROOT) so users overriding the sandbox root don’t end up with mismatched paths here.

Also applies to: 23-23, 26-26, 29-32, 36-36, 43-64, 65-75

scripts/task.ts (1)

123-123: Clarify semantics of startFrom: "task" and non‑template runs with the new dir/sandboxDir wiring

The new pieces here generally make sense, but there are a couple of behaviors worth explicitly confirming:

  • startFrom: "task" now forces only the final task to run (shouldRun = finalTask === task), regardless of dependency readiness. That’s fine as an “experts only” mode, but it does mean any dependsOn chain is ignored in this mode. Please confirm that in all places you pass startFrom=task (likely from Nx), the dependencies are either already satisfied or not required for those invocations.
  • templateSandboxDir is now templateKey && join(SANDBOX_DIRECTORY, dir ?? templateKey.replace('/', '-')), and sandboxDir/builtSandboxDir are derived from it. For non‑sandbox tasks, template can be omitted, so templateKey and templateSandboxDir end up undefined. That’s OK as long as non‑sandbox tasks never assume details.sandboxDir/builtSandboxDir are non‑empty; it’s worth double‑checking that assumption holds across the tasks in ./tasks/*.
  • Using SANDBOX_DIRECTORY plus the per‑project dir option lines up nicely with the new project.json target options.dir values and the SANDBOX_ROOT mechanism; this should keep Nx‑driven runs and direct yarn task runs in sync as long as callers provide --dir when needed.

If you’d like, I can draft a quick rg/ast-grep script to scan scripts/tasks/**/*.ts for usages of sandboxDir/builtSandboxDir that might break when template is omitted.

Also applies to: 152-157, 395-407, 441-442, 450-454, 501-512

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c62f200 and 1b0a0bf.

⛔ Files ignored due to path filters (11)
  • .yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch is excluded by !**/.yarn/**
  • .yarn/patches/@types-babel__traverse-npm-7.20.6-fac4243243.patch is excluded by !**/.yarn/**
  • .yarn/patches/@vitest-expect-npm-3.2.4-97c526d5cc.patch is excluded by !**/.yarn/**
  • .yarn/patches/react-aria-components-npm-1.12.2-6c5dcdafab.patch is excluded by !**/.yarn/**
  • .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs is excluded by !**/.yarn/**
  • .yarn/plugins/@yarnpkg/plugin-typescript.cjs is excluded by !**/.yarn/**
  • code/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • node_modules/.package-lock.json is excluded by !**/node_modules/**
  • node_modules/.yarn-state.yml is excluded by !**/node_modules/**
  • scripts/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (207)
  • .circleci/config.yml (14 hunks)
  • .circleci/src/jobs/bench-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/build.yml (2 hunks)
  • .circleci/src/jobs/check-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/check.yml (1 hunks)
  • .circleci/src/jobs/chromatic-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/create-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/e2e-dev.yml (1 hunks)
  • .circleci/src/jobs/e2e-production.yml (1 hunks)
  • .circleci/src/jobs/pretty-docs.yml (1 hunks)
  • .circleci/src/jobs/test-runner-production.yml (1 hunks)
  • .circleci/src/jobs/vitest-integration.yml (1 hunks)
  • .cursor/environment.json (1 hunks)
  • .env (1 hunks)
  • .github/actions/setup-node-and-install/action.yml (1 hunks)
  • .github/copilot-instructions.md (5 hunks)
  • .github/workflows/nx.yml (1 hunks)
  • .gitignore (2 hunks)
  • .ignore (0 hunks)
  • .nvmrc (1 hunks)
  • .nx/workflows/agents.yaml (1 hunks)
  • .nx/workflows/distribution-config.yaml (1 hunks)
  • .yarnrc.yml (1 hunks)
  • CONTRIBUTING/RELEASING.md (1 hunks)
  • code/.env (0 hunks)
  • code/.nxignore (0 hunks)
  • code/.yarnrc.yml (0 hunks)
  • code/addons/a11y/package.json (0 hunks)
  • code/addons/a11y/project.json (1 hunks)
  • code/addons/docs/package.json (0 hunks)
  • code/addons/docs/project.json (1 hunks)
  • code/addons/links/package.json (0 hunks)
  • code/addons/links/project.json (1 hunks)
  • code/addons/onboarding/package.json (0 hunks)
  • code/addons/onboarding/project.json (1 hunks)
  • code/addons/pseudo-states/package.json (0 hunks)
  • code/addons/pseudo-states/project.json (1 hunks)
  • code/addons/themes/package.json (0 hunks)
  • code/addons/themes/project.json (1 hunks)
  • code/addons/vitest/package.json (0 hunks)
  • code/addons/vitest/project.json (1 hunks)
  • code/builders/builder-vite/package.json (0 hunks)
  • code/builders/builder-vite/project.json (1 hunks)
  • code/builders/builder-webpack5/package.json (0 hunks)
  • code/builders/builder-webpack5/project.json (1 hunks)
  • code/core/package.json (1 hunks)
  • code/core/project.json (1 hunks)
  • code/core/src/components/components/Tabs/StatelessTabsView.tsx (2 hunks)
  • code/core/src/components/components/Tabs/TabsView.tsx (2 hunks)
  • code/core/src/telemetry/anonymous-id.ts (1 hunks)
  • code/e2e-tests/storybook-hooks.spec.ts (2 hunks)
  • code/frameworks/angular/package.json (0 hunks)
  • code/frameworks/angular/project.json (1 hunks)
  • code/frameworks/ember/package.json (0 hunks)
  • code/frameworks/ember/project.json (1 hunks)
  • code/frameworks/html-vite/package.json (0 hunks)
  • code/frameworks/html-vite/project.json (1 hunks)
  • code/frameworks/nextjs-vite/package.json (0 hunks)
  • code/frameworks/nextjs-vite/project.json (1 hunks)
  • code/frameworks/nextjs/package.json (0 hunks)
  • code/frameworks/nextjs/project.json (1 hunks)
  • code/frameworks/nextjs/src/next-image-loader-stub.ts (1 hunks)
  • code/frameworks/preact-vite/package.json (0 hunks)
  • code/frameworks/preact-vite/project.json (1 hunks)
  • code/frameworks/react-native-web-vite/package.json (0 hunks)
  • code/frameworks/react-native-web-vite/project.json (1 hunks)
  • code/frameworks/react-vite/package.json (0 hunks)
  • code/frameworks/react-vite/project.json (1 hunks)
  • code/frameworks/react-webpack5/package.json (0 hunks)
  • code/frameworks/react-webpack5/project.json (1 hunks)
  • code/frameworks/server-webpack5/package.json (0 hunks)
  • code/frameworks/server-webpack5/project.json (1 hunks)
  • code/frameworks/svelte-vite/package.json (0 hunks)
  • code/frameworks/svelte-vite/project.json (1 hunks)
  • code/frameworks/sveltekit/package.json (0 hunks)
  • code/frameworks/sveltekit/project.json (1 hunks)
  • code/frameworks/vue3-vite/package.json (0 hunks)
  • code/frameworks/vue3-vite/project.json (1 hunks)
  • code/frameworks/web-components-vite/package.json (0 hunks)
  • code/frameworks/web-components-vite/project.json (1 hunks)
  • code/lib/cli-sb/project.json (0 hunks)
  • code/lib/cli-storybook/package.json (0 hunks)
  • code/lib/cli-storybook/project.json (1 hunks)
  • code/lib/cli-storybook/src/link.ts (1 hunks)
  • code/lib/codemod/package.json (0 hunks)
  • code/lib/codemod/project.json (1 hunks)
  • code/lib/core-webpack/package.json (0 hunks)
  • code/lib/core-webpack/project.json (1 hunks)
  • code/lib/create-storybook/package.json (0 hunks)
  • code/lib/create-storybook/project.json (1 hunks)
  • code/lib/csf-plugin/package.json (0 hunks)
  • code/lib/csf-plugin/project.json (1 hunks)
  • code/lib/eslint-plugin/package.json (0 hunks)
  • code/lib/eslint-plugin/project.json (1 hunks)
  • code/lib/react-dom-shim/package.json (0 hunks)
  • code/lib/react-dom-shim/project.json (1 hunks)
  • code/nx.json (0 hunks)
  • code/package.json (4 hunks)
  • code/presets/create-react-app/package.json (0 hunks)
  • code/presets/create-react-app/project.json (1 hunks)
  • code/presets/react-webpack/package.json (0 hunks)
  • code/presets/react-webpack/project.json (1 hunks)
  • code/presets/server-webpack/package.json (0 hunks)
  • code/presets/server-webpack/project.json (1 hunks)
  • code/project.json (1 hunks)
  • code/renderers/html/package.json (0 hunks)
  • code/renderers/html/project.json (1 hunks)
  • code/renderers/preact/package.json (0 hunks)
  • code/renderers/preact/project.json (1 hunks)
  • code/renderers/react/package.json (0 hunks)
  • code/renderers/react/project.json (1 hunks)
  • code/renderers/react/src/entry-preview.tsx (0 hunks)
  • code/renderers/server/package.json (0 hunks)
  • code/renderers/server/project.json (1 hunks)
  • code/renderers/svelte/package.json (0 hunks)
  • code/renderers/svelte/project.json (1 hunks)
  • code/renderers/vue3/package.json (0 hunks)
  • code/renderers/vue3/project.json (1 hunks)
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts (0 hunks)
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts (1 hunks)
  • code/renderers/web-components/package.json (0 hunks)
  • code/renderers/web-components/project.json (1 hunks)
  • code/renderers/web-components/src/docs/web-components-properties.test.ts (1 hunks)
  • code/sandbox/angular-cli-default-ts/project.json (1 hunks)
  • code/sandbox/angular-cli-prerelease/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/cra-default-js/project.json (1 hunks)
  • code/sandbox/cra-default-ts/project.json (1 hunks)
  • code/sandbox/ember-3-js/project.json (1 hunks)
  • code/sandbox/ember-default-js/project.json (1 hunks)
  • code/sandbox/experimental-nextjs-vite-default-ts/project.json (0 hunks)
  • code/sandbox/html-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/html-vite-default-js/project.json (1 hunks)
  • code/sandbox/html-vite-default-ts/project.json (1 hunks)
  • code/sandbox/internal-react16-webpack/project.json (1 hunks)
  • code/sandbox/internal-react18-webpack-babel/project.json (1 hunks)
  • code/sandbox/internal-server-webpack5/project.json (1 hunks)
  • code/sandbox/lit-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/lit-vite-default-js/project.json (1 hunks)
  • code/sandbox/lit-vite-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-default-js/project.json (0 hunks)
  • code/sandbox/nextjs-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-prerelease/project.json (1 hunks)
  • code/sandbox/nextjs-vite-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-default-ts/project.json (1 hunks)
  • code/sandbox/nuxt-vite-default-ts/project.json (0 hunks)
  • code/sandbox/preact-vite-default-js/project.json (1 hunks)
  • code/sandbox/preact-vite-default-ts/project.json (1 hunks)
  • code/sandbox/qwik-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-expo-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json (1 hunks)
  • code/sandbox/react-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-default-js/project.json (1 hunks)
  • code/sandbox/react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-prerelease-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-17-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-prerelease-ts/project.json (1 hunks)
  • code/sandbox/solid-vite-default-js/project.json (1 hunks)
  • code/sandbox/solid-vite-default-ts/project.json (1 hunks)
  • code/sandbox/svelte-kit-default-ts/project.json (0 hunks)
  • code/sandbox/svelte-kit-skeleton-js/project.json (0 hunks)
  • code/sandbox/svelte-kit-skeleton-ts/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-js/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-js/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-ts/project.json (1 hunks)
  • docs/_snippets/addon-consume-and-update-globaltype.md (1 hunks)
  • docs/_snippets/main-config-builder-custom-config.md (0 hunks)
  • docs/_snippets/storybook-addon-css-example.md (1 hunks)
  • docs/_snippets/storybook-addon-toolkit-types.md (1 hunks)
  • docs/_snippets/storybook-addons-api-getchannel.md (1 hunks)
  • docs/_snippets/storybook-preview-use-global-type.md (1 hunks)
  • nx.json (1 hunks)
  • package.json (1 hunks)
  • scripts/.yarnrc.yml (0 hunks)
  • scripts/build-package.ts (2 hunks)
  • scripts/build/build-package.ts (2 hunks)
  • scripts/build/utils/generate-bundle.ts (1 hunks)
  • scripts/build/utils/generate-type-mappers.ts (1 hunks)
  • scripts/build/utils/generate-types.ts (3 hunks)
  • scripts/build/utils/modify-core-theme-types.ts (2 hunks)
  • scripts/check-package.ts (1 hunks)
  • scripts/check/check-package.ts (1 hunks)
  • scripts/check/utils/typescript.ts (2 hunks)
  • scripts/create-nx-sandbox-projects.ts (1 hunks)
  • scripts/ecosystem-ci/before-test.js (1 hunks)
  • scripts/event-log-checker.ts (1 hunks)
  • scripts/get-sandbox-dir.ts (2 hunks)
  • scripts/get-template.ts (3 hunks)
  • scripts/knip.config.ts (1 hunks)
  • scripts/package.json (2 hunks)
  • scripts/prepare-sandbox.ts (1 hunks)
  • scripts/project.json (1 hunks)
  • scripts/release/__tests__/version.test.ts (1 hunks)
  • scripts/release/version.ts (2 hunks)
  • scripts/run-registry.ts (8 hunks)
  • scripts/sandbox/utils/getPort.ts (1 hunks)
  • scripts/task.ts (5 hunks)
⛔ Files not processed due to max files limit (32)
  • scripts/tasks/build.ts
  • scripts/tasks/check.ts
  • scripts/tasks/chromatic.ts
  • scripts/tasks/compile.ts
  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
  • scripts/tasks/run-registry.ts
  • scripts/tasks/sandbox-parts.ts
  • scripts/tasks/sandbox.ts
  • scripts/tasks/serve.ts
  • scripts/tasks/test-runner-build.ts
  • scripts/upload-bench.ts
  • scripts/utils/constants.ts
  • scripts/utils/kill-process-on-port.ts
  • scripts/utils/main-js.ts
  • scripts/utils/tools.ts
  • scripts/utils/workspace.ts
  • scripts/utils/yarn.ts
  • test-storybooks/portable-stories-kitchen-sink/nextjs/package.json
  • test-storybooks/portable-stories-kitchen-sink/nextjs/project.json
  • test-storybooks/portable-stories-kitchen-sink/react-vitest-3/package.json
  • test-storybooks/portable-stories-kitchen-sink/react-vitest-3/playwright-e2e.config.ts
  • test-storybooks/portable-stories-kitchen-sink/react-vitest-3/project.json
  • test-storybooks/portable-stories-kitchen-sink/react/package.json
  • test-storybooks/portable-stories-kitchen-sink/react/playwright-e2e.config.ts
  • test-storybooks/portable-stories-kitchen-sink/react/project.json
  • test-storybooks/portable-stories-kitchen-sink/svelte/package.json
  • test-storybooks/portable-stories-kitchen-sink/svelte/project.json
  • test-storybooks/portable-stories-kitchen-sink/vue3/package.json
  • test-storybooks/portable-stories-kitchen-sink/vue3/project.json
  • test-storybooks/yarn-pnp/package.json
  • test-storybooks/yarn-pnp/project.json
💤 Files with no reviewable changes (55)
  • code/addons/docs/package.json
  • code/frameworks/web-components-vite/package.json
  • code/frameworks/react-vite/package.json
  • code/frameworks/ember/package.json
  • code/addons/links/package.json
  • code/builders/builder-vite/package.json
  • code/builders/builder-webpack5/package.json
  • code/presets/react-webpack/package.json
  • code/frameworks/react-webpack5/package.json
  • code/renderers/svelte/package.json
  • code/frameworks/angular/package.json
  • code/renderers/vue3/package.json
  • code/addons/themes/package.json
  • code/frameworks/nextjs-vite/package.json
  • code/frameworks/react-native-web-vite/package.json
  • code/renderers/server/package.json
  • code/sandbox/svelte-kit-skeleton-js/project.json
  • code/addons/onboarding/package.json
  • code/presets/server-webpack/package.json
  • .ignore
  • code/sandbox/nextjs-default-js/project.json
  • code/lib/csf-plugin/package.json
  • code/frameworks/svelte-vite/package.json
  • code/renderers/react/package.json
  • code/addons/vitest/package.json
  • code/renderers/html/package.json
  • code/.env
  • code/.nxignore
  • code/renderers/react/src/entry-preview.tsx
  • code/addons/a11y/package.json
  • code/sandbox/svelte-kit-default-ts/project.json
  • code/frameworks/html-vite/package.json
  • code/lib/cli-sb/project.json
  • code/lib/react-dom-shim/package.json
  • code/frameworks/vue3-vite/package.json
  • code/sandbox/experimental-nextjs-vite-default-ts/project.json
  • code/lib/codemod/package.json
  • code/presets/create-react-app/package.json
  • code/frameworks/sveltekit/package.json
  • docs/_snippets/main-config-builder-custom-config.md
  • code/lib/core-webpack/package.json
  • code/lib/eslint-plugin/package.json
  • code/lib/cli-storybook/package.json
  • code/frameworks/nextjs/package.json
  • code/lib/create-storybook/package.json
  • code/.yarnrc.yml
  • code/frameworks/preact-vite/package.json
  • code/sandbox/nuxt-vite-default-ts/project.json
  • code/renderers/web-components/package.json
  • code/nx.json
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts
  • code/addons/pseudo-states/package.json
  • code/frameworks/server-webpack5/package.json
  • scripts/.yarnrc.yml
  • code/renderers/preact/package.json
✅ Files skipped from review due to trivial changes (2)
  • code/lib/codemod/project.json
  • docs/_snippets/storybook-addon-toolkit-types.md
🚧 Files skipped from review as they are similar to previous changes (88)
  • code/sandbox/vue3-rsbuild-default-ts/project.json
  • code/lib/cli-storybook/src/link.ts
  • scripts/event-log-checker.ts
  • scripts/build/utils/generate-type-mappers.ts
  • code/addons/vitest/project.json
  • .circleci/src/jobs/vitest-integration.yml
  • code/frameworks/sveltekit/project.json
  • code/e2e-tests/storybook-hooks.spec.ts
  • scripts/ecosystem-ci/before-test.js
  • code/addons/onboarding/project.json
  • code/frameworks/react-webpack5/project.json
  • scripts/check/utils/typescript.ts
  • .circleci/src/jobs/test-runner-production.yml
  • code/presets/server-webpack/project.json
  • code/core/src/telemetry/anonymous-id.ts
  • code/renderers/react/project.json
  • code/frameworks/preact-vite/project.json
  • code/frameworks/nextjs/src/next-image-loader-stub.ts
  • code/lib/csf-plugin/project.json
  • .circleci/src/jobs/build.yml
  • code/renderers/web-components/project.json
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts
  • code/sandbox/cra-default-ts/project.json
  • .circleci/src/jobs/bench-sandboxes.yml
  • scripts/check-package.ts
  • code/lib/create-storybook/project.json
  • code/sandbox/nextjs-vite-14-ts/project.json
  • code/lib/core-webpack/project.json
  • scripts/sandbox/utils/getPort.ts
  • code/renderers/web-components/src/docs/web-components-properties.test.ts
  • code/sandbox/angular-cli-prerelease/project.json
  • code/sandbox/nextjs-15-ts/project.json
  • code/sandbox/react-vite-default-ts/project.json
  • code/sandbox/preact-vite-default-ts/project.json
  • code/renderers/html/project.json
  • scripts/get-sandbox-dir.ts
  • code/frameworks/svelte-vite/project.json
  • code/sandbox/nextjs-14-ts/project.json
  • scripts/build/utils/generate-bundle.ts
  • scripts/get-template.ts
  • code/sandbox/html-vite-default-ts/project.json
  • code/core/package.json
  • code/sandbox/react-native-web-vite-expo-ts/project.json
  • code/sandbox/vue3-vite-default-js/project.json
  • code/presets/react-webpack/project.json
  • scripts/check/check-package.ts
  • code/presets/create-react-app/project.json
  • code/renderers/server/project.json
  • code/sandbox/react-rsbuild-default-ts/project.json
  • code/frameworks/react-vite/project.json
  • .github/actions/setup-node-and-install/action.yml
  • scripts/project.json
  • .cursor/environment.json
  • code/renderers/svelte/project.json
  • .circleci/src/jobs/e2e-production.yml
  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/frameworks/html-vite/project.json
  • code/sandbox/preact-vite-default-js/project.json
  • CONTRIBUTING/RELEASING.md
  • .circleci/src/jobs/check-sandboxes.yml
  • code/sandbox/svelte-kit-skeleton-ts/project.json
  • docs/_snippets/storybook-preview-use-global-type.md
  • code/frameworks/web-components-vite/project.json
  • code/frameworks/ember/project.json
  • .circleci/src/jobs/pretty-docs.yml
  • code/renderers/preact/project.json
  • code/sandbox/html-rsbuild-default-ts/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/lib/eslint-plugin/project.json
  • .circleci/src/jobs/create-sandboxes.yml
  • .circleci/src/jobs/e2e-dev.yml
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • .nvmrc
  • scripts/build/utils/modify-core-theme-types.ts
  • code/sandbox/nextjs-default-ts/project.json
  • code/sandbox/internal-react16-webpack/project.json
  • code/frameworks/vue3-vite/project.json
  • code/sandbox/nextjs-vite-default-ts/project.json
  • code/sandbox/react-webpack-prerelease-ts/project.json
  • scripts/knip.config.ts
  • code/addons/links/project.json
  • code/core/src/components/components/Tabs/TabsView.tsx
  • code/builders/builder-webpack5/project.json
  • code/sandbox/nextjs-vite-15-ts/project.json
  • code/sandbox/qwik-vite-default-ts/project.json
  • code/frameworks/nextjs/project.json
  • docs/_snippets/addon-consume-and-update-globaltype.md
  • code/frameworks/nextjs-vite/project.json
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/build/utils/generate-types.ts
  • code/core/src/components/components/Tabs/StatelessTabsView.tsx
  • scripts/release/__tests__/version.test.ts
  • scripts/build/build-package.ts
  • scripts/task.ts
  • scripts/release/version.ts
  • scripts/prepare-sandbox.ts
  • scripts/create-nx-sandbox-projects.ts
  • scripts/run-registry.ts
  • scripts/build-package.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/build/utils/generate-types.ts
  • code/core/src/components/components/Tabs/StatelessTabsView.tsx
  • scripts/release/__tests__/version.test.ts
  • scripts/build/build-package.ts
  • scripts/task.ts
  • scripts/release/version.ts
  • scripts/prepare-sandbox.ts
  • scripts/create-nx-sandbox-projects.ts
  • scripts/run-registry.ts
  • scripts/build-package.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/build/utils/generate-types.ts
  • code/core/src/components/components/Tabs/StatelessTabsView.tsx
  • scripts/release/__tests__/version.test.ts
  • code/package.json
  • scripts/build/build-package.ts
  • code/addons/a11y/project.json
  • code/addons/docs/project.json
  • code/project.json
  • code/sandbox/ember-3-js/project.json
  • code/addons/pseudo-states/project.json
  • code/sandbox/solid-vite-default-js/project.json
  • code/sandbox/svelte-vite-default-js/project.json
  • scripts/task.ts
  • code/sandbox/cra-default-js/project.json
  • code/sandbox/ember-default-js/project.json
  • code/frameworks/server-webpack5/project.json
  • code/addons/themes/project.json
  • code/sandbox/internal-server-webpack5/project.json
  • scripts/release/version.ts
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/frameworks/react-native-web-vite/project.json
  • code/sandbox/lit-vite-default-js/project.json
  • code/sandbox/react-webpack-18-ts/project.json
  • code/sandbox/angular-cli-default-ts/project.json
  • scripts/prepare-sandbox.ts
  • code/sandbox/react-webpack-17-ts/project.json
  • scripts/create-nx-sandbox-projects.ts
  • scripts/run-registry.ts
  • code/sandbox/react-vite-default-js/project.json
  • code/lib/react-dom-shim/project.json
  • package.json
  • code/lib/cli-storybook/project.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • code/sandbox/internal-react18-webpack-babel/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/core/project.json
  • code/sandbox/nextjs-prerelease/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/sandbox/lit-rsbuild-default-ts/project.json
  • code/builders/builder-vite/project.json
  • code/sandbox/html-vite-default-js/project.json
  • scripts/build-package.ts
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/svelte-vite-default-ts/project.json
  • scripts/package.json
  • nx.json
  • code/frameworks/angular/project.json
  • code/renderers/vue3/project.json
code/**/!(*.test).{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

code/**/!(*.test).{ts,tsx,js,mjs}: Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error
Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error
Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/core/src/components/components/Tabs/StatelessTabsView.tsx
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{test,spec}.{ts,tsx}: Test files should follow the naming pattern *.test.ts, *.test.tsx, *.spec.ts, or *.spec.tsx
Follow the spy mocking rules defined in .cursor/rules/spy-mocking.mdc for consistent mocking patterns with Vitest

Files:

  • scripts/release/__tests__/version.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.test.{ts,tsx}: Write meaningful unit tests that import and call functions being tested, not just verify syntax patterns
Use 'yarn vitest run --coverage ' to run tests with coverage reports and aim for 75%+ coverage of statements/lines
Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations
Use 'vi.mock()' to mock external dependencies like file system and loggers in unit tests

Files:

  • scripts/release/__tests__/version.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/spy-mocking.mdc)

**/*.test.{ts,tsx,js,jsx}: Use vi.mock() with the spy: true option for all package and file mocks in Vitest tests
Place all mocks at the top of the test file before any test cases
Use vi.mocked() to type and access the mocked functions in Vitest tests
Implement mock behaviors in beforeEach blocks in Vitest tests
Mock all required dependencies that the test subject uses
Each mock implementation should return a Promise for async functions in Vitest
Mock implementations should match the expected return type of the original function
Mock all required properties and methods that the test subject uses in Vitest tests
Avoid direct function mocking without vi.mocked() in Vitest tests
Avoid mock implementations outside of beforeEach blocks in Vitest tests
Avoid mocking without the spy: true option in Vitest tests
Avoid inline mock implementations within test cases in Vitest tests
Avoid mocking only a subset of required dependencies in Vitest tests
Mock at the highest level of abstraction needed in Vitest tests
Keep mock implementations simple and focused in Vitest tests
Use type-safe mocking with vi.mocked() in Vitest tests
Document complex mock behaviors in Vitest tests
Group related mocks together in Vitest tests

Files:

  • scripts/release/__tests__/version.test.ts
.yarnrc.yml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Yarn 4.9.1 as the package manager

Files:

  • .yarnrc.yml
🧠 Learnings (41)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • .gitignore
  • code/package.json
  • .circleci/config.yml
  • scripts/release/version.ts
  • scripts/prepare-sandbox.ts
  • scripts/create-nx-sandbox-projects.ts
  • package.json
  • .github/copilot-instructions.md
  • scripts/build-package.ts
  • .env
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'yarn vitest run --coverage <test-file>' to run tests with coverage reports and aim for 75%+ coverage of statements/lines

Applied to files:

  • .gitignore
  • code/package.json
  • code/project.json
  • scripts/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn prettier --write <file>' to format code after making changes

Applied to files:

  • .gitignore
  • code/package.json
  • code/project.json
  • scripts/create-nx-sandbox-projects.ts
  • .github/copilot-instructions.md
  • scripts/build-package.ts
  • scripts/package.json
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • .gitignore
  • code/package.json
  • .circleci/config.yml
  • scripts/release/version.ts
  • .yarnrc.yml
  • package.json
  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • .gitignore
  • scripts/release/__tests__/version.test.ts
  • code/package.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/sandbox/react-vite-default-js/project.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/svelte-vite-default-ts/project.json
  • scripts/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to code/**/!(*.test).{ts,tsx,js,mjs} : Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error

Applied to files:

  • .gitignore
  • code/package.json
  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Use ESLint and Prettier for code style enforcement

Applied to files:

  • .gitignore
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to code/**/!(*.test).{ts,tsx,js,mjs} : Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error

Applied to files:

  • .gitignore
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn lint:js:cmd <file>' to check for ESLint issues after making changes

Applied to files:

  • .gitignore
  • code/package.json
  • code/project.json
  • scripts/create-nx-sandbox-projects.ts
  • package.json
  • .github/copilot-instructions.md
  • scripts/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager

Applied to files:

  • .gitignore
  • code/package.json
  • .circleci/config.yml
  • .yarnrc.yml
  • .github/copilot-instructions.md
  • scripts/package.json
📚 Learning: 2025-10-01T15:24:01.060Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32594
File: code/core/src/components/components/Popover/WithPopover.tsx:7-9
Timestamp: 2025-10-01T15:24:01.060Z
Learning: In the Storybook repository, "react-aria-components/patched-dist/*" (e.g., "react-aria-components/patched-dist/Dialog", "react-aria-components/patched-dist/Popover", "react-aria-components/patched-dist/Tooltip") are valid import paths created by a patch applied to the react-aria-components package. These imports should not be flagged as broken or invalid until a maintainer explicitly states they are no longer acceptable.

Applied to files:

  • code/core/src/components/components/Tabs/StatelessTabsView.tsx
📚 Learning: 2025-11-05T09:38:47.712Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.

Applied to files:

  • code/core/src/components/components/Tabs/StatelessTabsView.tsx
  • code/package.json
  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • scripts/release/__tests__/version.test.ts
  • code/package.json
  • scripts/release/version.ts
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • package.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/lit-rsbuild-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/svelte-vite-default-ts/project.json
  • nx.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx} : Export functions from modules for testing purposes

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock implementations should match the expected return type of the original function

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid direct function mocking without `vi.mocked()` in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'vi.mock()' to mock external dependencies like file system and loggers in unit tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid inline mock implementations within test cases in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required dependencies that the test subject uses

Applied to files:

  • scripts/release/__tests__/version.test.ts
  • code/package.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Group related mocks together in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Keep mock implementations simple and focused in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use `vi.mocked()` to type and access the mocked functions in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use `vi.mock()` with the `spy: true` option for all package and file mocks in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use type-safe mocking with `vi.mocked()` in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock at the highest level of abstraction needed in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required properties and methods that the test subject uses in Vitest tests

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Each mock implementation should return a Promise for async functions in Vitest

Applied to files:

  • scripts/release/__tests__/version.test.ts
📚 Learning: 2025-09-17T07:31:04.432Z
Learnt from: ndelangen
Repo: storybookjs/storybook PR: 32484
File: code/core/package.json:326-326
Timestamp: 2025-09-17T07:31:04.432Z
Learning: In Storybook's core package, dependencies like `open` are bundled into the final distribution during the build process, so they should remain in devDependencies rather than being moved to dependencies. End users don't need these packages as separate runtime dependencies since they're included in the bundled code.

Applied to files:

  • code/package.json
  • package.json
  • .github/copilot-instructions.md
📚 Learning: 2025-11-05T09:37:25.920Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/tooltip/WithTooltip.tsx:54-96
Timestamp: 2025-11-05T09:37:25.920Z
Learning: Repo: storybookjs/storybook — In code/core/src/components/components/tooltip/WithTooltip.tsx, the legacy WithTooltip implementation is intentionally reintroduced for backward compatibility and is deprecated; maintainers (per Sidnioulz) do not want maintenance or improvements on it. Prefer WithTooltipNew/Popover; avoid suggesting changes to WithTooltip.* going forward.

Applied to files:

  • code/package.json
  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'cd code && yarn storybook:ui' to start the development server for testing UI changes on http://localhost:6006/

Applied to files:

  • code/package.json
  • .circleci/config.yml
  • scripts/prepare-sandbox.ts
  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • code/package.json
  • .circleci/config.yml
  • scripts/task.ts
  • .circleci/src/jobs/chromatic-sandboxes.yml
  • scripts/prepare-sandbox.ts
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • .github/copilot-instructions.md
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • scripts/package.json
  • nx.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • code/package.json
  • .circleci/config.yml
  • code/project.json
  • .circleci/src/jobs/check.yml
  • .github/copilot-instructions.md
  • scripts/build-package.ts
  • scripts/package.json
📚 Learning: 2025-09-29T13:20:23.346Z
Learnt from: mrginglymus
Repo: storybookjs/storybook PR: 32556
File: code/core/package.json:309-313
Timestamp: 2025-09-29T13:20:23.346Z
Learning: The `fast-printf` dependency in Storybook's core package is bundled into the final distribution during the build process, so it should remain in devDependencies rather than being moved to dependencies, following the same pattern as other bundled dependencies like `open`.

Applied to files:

  • code/package.json
  • package.json
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: The useGlobals hook from storybook/manager-api returns a tuple where the third element (storyGlobals) is typed as Globals, not Globals | undefined. This means TypeScript guarantees it's always defined, making the `in` operator safe to use without additional null checks.

Applied to files:

  • docs/_snippets/storybook-addons-api-getchannel.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to README.md : Update relevant README files for significant changes

Applied to files:

  • .circleci/config.yml
  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Run 'yarn task --task check' to verify TypeScript types across all packages before submitting PRs

Applied to files:

  • .circleci/config.yml
  • .github/copilot-instructions.md
  • scripts/build-package.ts
  • scripts/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .nvmrc : Use Node.js 22.16.0 as specified in .nvmrc

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Tests are located in the `code/` directory with root directory for test execution at `./code/`

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Do not use 'yarn task --task dev' or 'yarn start' as these start permanent development servers that run indefinitely

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Document complex mock behaviors in Vitest tests

Applied to files:

  • scripts/package.json
🪛 dotenv-linter (4.0.0)
.env

[warning] 2-2: [UnorderedKey] The IN_STORYBOOK_SANDBOX key should go before the STORYBOOK_DISABLE_TELEMETRY key

(UnorderedKey)


[warning] 3-3: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 3-3: [UnorderedKey] The SANDBOX_ROOT key should go before the STORYBOOK_DISABLE_TELEMETRY key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx

@kasperpeulen kasperpeulen added ci:daily Run the CI jobs that normally run in the daily job. and removed ci:normal labels Nov 26, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
package.json (1)

3-4: ESM type inheritance issue requires scripts/eslint-plugin-local-rules fix.

As flagged in the previous review, root "type": "module" causes scripts/eslint-plugin-local-rules/ to inherit ESM, breaking the require() calls in those files. Ensure scripts/eslint-plugin-local-rules/package.json has "type": "commonjs" added or those files are converted to ES module syntax.

🧹 Nitpick comments (1)
.nx/workflows/agents.yaml (1)

91-95: Windows template initialization incomplete.

The windows-js launch template lacks the init-steps configuration (marked as TODO on line 94). This will require implementation before Windows agents can be used in distributed CI. For now, this is acceptable as a known gap, but should be prioritized when Windows support is needed.

Would you like me to generate the Windows init-steps configuration based on the Linux templates?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b0a0bf and f54b921.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • .github/workflows/nx.yml (1 hunks)
  • .nx/workflows/agents.yaml (1 hunks)
  • code/frameworks/nextjs/src/next-image-loader-stub.ts (1 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • code/frameworks/nextjs/src/next-image-loader-stub.ts
  • .github/workflows/nx.yml
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • package.json
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn lint:js:cmd <file>' to check for ESLint issues after making changes

Applied to files:

  • package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • package.json
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • package.json
📚 Learning: 2025-09-17T07:31:04.432Z
Learnt from: ndelangen
Repo: storybookjs/storybook PR: 32484
File: code/core/package.json:326-326
Timestamp: 2025-09-17T07:31:04.432Z
Learning: In Storybook's core package, dependencies like `open` are bundled into the final distribution during the build process, so they should remain in devDependencies rather than being moved to dependencies. End users don't need these packages as separate runtime dependencies since they're included in the bundled code.

Applied to files:

  • package.json
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • package.json
📚 Learning: 2025-09-29T13:20:23.346Z
Learnt from: mrginglymus
Repo: storybookjs/storybook PR: 32556
File: code/core/package.json:309-313
Timestamp: 2025-09-29T13:20:23.346Z
Learning: The `fast-printf` dependency in Storybook's core package is bundled into the final distribution during the build process, so it should remain in devDependencies rather than being moved to dependencies, following the same pattern as other bundled dependencies like `open`.

Applied to files:

  • package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: daily
  • GitHub Check: nx
🔇 Additional comments (6)
.nx/workflows/agents.yaml (1)

75-75: Sandbox path configuration aligns with PR objectives.

The SANDBOX_ROOT environment variable correctly points to ../storybook-sandboxes for sandbox isolation as described in the PR summary.

package.json (5)

5-17: Workspaces configuration properly structured for monorepo root move.

The workspace packages declaration correctly reflects the move from ./code root to the git repository root. All package globs (code/addons/, code/frameworks/, etc.) and the scripts workspace are properly configured relative to the new root.


23-23: Root-level CLI scripts updated appropriately.

The simplified i, new nx, and updated task scripts align with the monorepo restructuring. Scripts now correctly delegate to the scripts/ subdirectory from the new root context.

Also applies to: 26-26, 32-32


29-29: Ecosystem CI script paths updated for sandbox relocation.

The svelte-ecosystem-ci:before-test and vite-ecosystem-ci:before-test scripts correctly reference the new sandbox path (../storybook-sandboxes/) as per the PR's sandbox isolation objective.

Also applies to: 36-36


44-64: Resolutions block properly manages monorepo-wide dependency consistency.

The resolutions configuration correctly pins transitive dependencies across the workspace, using a mix of version constraints, patches, and latest versions to ensure consistency. This is appropriate monorepo practice.

Note: The Playwright vulnerability flagged in lines 48, 58–59 is addressed separately in a prior review comment.


65-73: Root-level devDependencies appropriately support NX workspace integration.

The new devDependencies include essential NX workspace tooling (@nx/workspace, nx) along with complementary utilities (prettier, jiti, kill-port, @playwright/test). This aligns with the PR's NX integration objectives.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
scripts/build/utils/generate-types.ts (1)

21-25: Fix comment/code mismatch for concurrency limit

The comment still states "limit the number of concurrent processes to 3" and "3 seems to be the sweet spot", but the implementation uses limit(10). Please either update the comment to "10" (and rationale) or change the limit back to 3 so they agree.

🧹 Nitpick comments (3)
.yarnrc.yml (2)

7-13: Review justification for suppressing Yarn warnings.

The configuration discards three Yarn warning codes (YN0007, YN0005, YN0076) without inline commentary explaining why. These codes typically relate to lockfile version mismatches, resolution issues, and caching problems—which may surface legitimate issues during the monorepo refactor.

Verify that suppressing these warnings will not obscure problems:

  • YN0007: Lockfile version mismatch (could indicate schema drift after refactor)
  • YN0005: Package resolution issues
  • YN0076: Registry or fetch problems (especially relevant given unsafeHttpWhitelist for local Verdaccio)

If suppression is necessary, add an inline comment explaining the reason for each code.


1-1: Consider trade-off of zero compression.

Setting compressionLevel: 0 disables package compression in the global cache. This improves install speed but increases disk footprint. Confirm this trade-off is intentional for the sandboxing/CI improvements in this PR.

scripts/build/utils/generate-types.ts (1)

10-15: Optional: derive DIR_CODE from ROOT_DIRECTORY for consistency

Given that ROOT_DIRECTORY now represents the monorepo root, you could reduce path fragility by defining:

const DIR_CODE = join(ROOT_DIRECTORY, 'code');

instead of relying on import.meta.dirname with multiple .. segments. This keeps all root-relative paths centralized.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f54b921 and 4fdcfab.

📒 Files selected for processing (4)
  • .gitignore (2 hunks)
  • .yarnrc.yml (1 hunks)
  • docs/_snippets/storybook-addons-api-getchannel.md (1 hunks)
  • scripts/build/utils/generate-types.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .gitignore
🧰 Additional context used
📓 Path-based instructions (4)
.yarnrc.yml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Yarn 4.9.1 as the package manager

Files:

  • .yarnrc.yml
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/build/utils/generate-types.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/build/utils/generate-types.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/build/utils/generate-types.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager

Applied to files:

  • .yarnrc.yml
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • .yarnrc.yml
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: In viewport tool code, when using the `useGlobals` hook from storybook/manager-api, the third returned value `storyGlobals` is guaranteed by TypeScript to be defined (not undefined/null), making the `in` operator safe to use without additional null checks.

Applied to files:

  • docs/_snippets/storybook-addons-api-getchannel.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: daily
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (3)
docs/_snippets/storybook-addons-api-getchannel.md (1)

15-21: Good fix — documentation example now demonstrates best practices.

The comma operator pattern has been properly replaced with two clear, separate statements. Each call is now on its own line with proper semicolons, making the code more readable and teaching a better pattern to developers learning from this example. The execution order (updateGlobals first, then emit FORCE_RE_RENDER) is preserved, and the comment placement is appropriate.

.yarnrc.yml (1)

38-38: Verify Yarn version against coding guidelines.

The yarnPath specifies yarn-4.10.3.cjs, but the coding guidelines require Yarn 4.9.1. Confirm whether 4.10.3 is intentional (e.g., for a specific bug fix or feature in the monorepo refactor) or if this should be downgraded to 4.9.1.

scripts/build/utils/generate-types.ts (1)

6-6: ROOT_DIRECTORY-based jiti path looks correct for new monorepo root

Importing ROOT_DIRECTORY and resolving the jiti binary from join(ROOT_DIRECTORY, 'node_modules', '.bin', 'jiti') makes this script robust to the workspace root change and avoids fragile deep relative paths. The quoting and spawn options remain consistent with the previous implementation.

Also applies to: 33-35

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
scripts/utils/cli-utils.ts (2)

10-17: Excellent simplification of dependency installation.

The refactoring from multiple parallel installs to a single root-level install is clearer and aligns perfectly with the monorepo restructuring. The spawn configuration correctly inherits stdio streams for proper logging.

Consider removing shell: true unless it's required for cross-platform compatibility, as it adds a small overhead:

 const task = spawn('yarn', ['install'], {
   cwd: ROOT_DIRECTORY,
-  shell: true,
   stdio: ['inherit', 'inherit', 'inherit'],
 });

19-30: Error handling is correct.

The promise-based error handling properly rejects on non-zero exit codes and cleans up the spawned process. The logic is sound.

Consider capturing the exit code in the error message for better debugging:

 await new Promise<void>((res, rej) => {
   task.on('exit', (code: number) => {
     if (code !== 0) {
-      rej();
+      rej(code);
     } else {
       res();
     }
   });
-}).catch(() => {
+}).catch((code) => {
   task.kill();
-  throw new Error('Failed to install dependencies');
+  throw new Error(`Failed to install dependencies (exit code: ${code || 'unknown'})`);
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cf9a67c and b9ea221.

📒 Files selected for processing (2)
  • scripts/tasks/install.ts (2 hunks)
  • scripts/utils/cli-utils.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/tasks/install.ts
  • scripts/utils/cli-utils.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/tasks/install.ts
  • scripts/utils/cli-utils.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/tasks/install.ts
  • scripts/utils/cli-utils.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Run 'yarn task --task check' to verify TypeScript types across all packages before submitting PRs

Applied to files:

  • scripts/tasks/install.ts
  • scripts/utils/cli-utils.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • scripts/utils/cli-utils.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: daily
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (3)
scripts/utils/cli-utils.ts (1)

5-6: LGTM: Centralized root directory import.

The import of ROOT_DIRECTORY aligns well with the PR's objective to refactor the monorepo root from ./code to the git root. This simplifies the dependency management logic.

scripts/tasks/install.ts (2)

1-1: Import cleanup from node:fs/promises looks good

Only access is imported and used, which keeps the dependency surface minimal and matches the pathExists helper’s needs. No issues here.


7-7: Using ROOT_DIRECTORY centralizes monorepo root resolution

Importing and using ROOT_DIRECTORY here is consistent with the PR’s move to the git root as the monorepo root, and helps avoid ad‑hoc codeDir handling scattered across tasks.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f99ea16 and b3a5eaf.

📒 Files selected for processing (1)
  • scripts/ecosystem-ci/before-test.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/ecosystem-ci/before-test.js
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/ecosystem-ci/before-test.js
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
📚 Learning: 2025-10-01T15:24:01.060Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32594
File: code/core/src/components/components/Popover/WithPopover.tsx:7-9
Timestamp: 2025-10-01T15:24:01.060Z
Learning: In the Storybook repository, "react-aria-components/patched-dist/*" (e.g., "react-aria-components/patched-dist/Dialog", "react-aria-components/patched-dist/Popover", "react-aria-components/patched-dist/Tooltip") are valid import paths created by a patch applied to the react-aria-components package. These imports should not be flagged as broken or invalid until a maintainer explicitly states they are no longer acceptable.

Applied to files:

  • scripts/ecosystem-ci/before-test.js
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • scripts/ecosystem-ci/before-test.js
📚 Learning: 2025-09-17T07:31:04.432Z
Learnt from: ndelangen
Repo: storybookjs/storybook PR: 32484
File: code/core/package.json:326-326
Timestamp: 2025-09-17T07:31:04.432Z
Learning: In Storybook's core package, dependencies like `open` are bundled into the final distribution during the build process, so they should remain in devDependencies rather than being moved to dependencies. End users don't need these packages as separate runtime dependencies since they're included in the bundled code.

Applied to files:

  • scripts/ecosystem-ci/before-test.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: daily
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (2)
scripts/ecosystem-ci/before-test.js (2)

22-22: LGTM: Path correctly updated to new sandbox location.

The path change from ../../sandbox/ to ../../../storybook-sandboxes/ aligns with the PR objective of relocating sandboxes outside the monorepo root.


28-32: LGTM: Filtering logic correctly extracts patch resolutions.

The filtering approach appropriately isolates patch protocol resolutions using includes('patch:') and safely handles the case when no resolutions exist.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
scripts/ecosystem-ci/before-test.js (1)

28-37: Resolutions filtering/merge logic is correct; consider tightening patch detection

The new logic correctly:

  • Derives a filtered resolutions object from the root package.json, excluding entries whose value contains patch:.
  • Merges those into sandboxPackageJson.resolutions using spread, fixing the previous nested resolutions.resolutions structure and ensuring root resolutions override sandbox ones.

If you want to make this a bit more robust and explicit about patch handling, you could additionally guard against non-string values and only treat real Yarn patch protocol entries as patches:

-const resolutions = rootPackageJson.resolutions
-  ? Object.fromEntries(
-      Object.entries(rootPackageJson.resolutions).filter(([_, v]) => !v.includes('patch:'))
-    )
-  : {};
+const resolutions = rootPackageJson.resolutions
+  ? Object.fromEntries(
+      Object.entries(rootPackageJson.resolutions).filter(
+        ([, v]) => typeof v === 'string' && !v.startsWith('patch:')
+      )
+    )
+  : {};

This is optional, but it makes the intent clearer and guards against any unexpected value shapes in rootPackageJson.resolutions.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3a5eaf and cc1a401.

📒 Files selected for processing (1)
  • scripts/ecosystem-ci/before-test.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/ecosystem-ci/before-test.js
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/ecosystem-ci/before-test.js
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
📚 Learning: 2025-09-17T07:31:04.432Z
Learnt from: ndelangen
Repo: storybookjs/storybook PR: 32484
File: code/core/package.json:326-326
Timestamp: 2025-09-17T07:31:04.432Z
Learning: In Storybook's core package, dependencies like `open` are bundled into the final distribution during the build process, so they should remain in devDependencies rather than being moved to dependencies. End users don't need these packages as separate runtime dependencies since they're included in the bundled code.

Applied to files:

  • scripts/ecosystem-ci/before-test.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: daily
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (1)
scripts/ecosystem-ci/before-test.js (1)

20-23: Sandbox path update aligns with new SANDBOX_ROOT layout

The updated sandboxPackageJsonPath correctly climbs three levels and targets ../storybook-sandboxes, matching the new default sandbox root while preserving the sandbox.replace('/', '-') naming convention. This looks consistent with the PR’s directory scheme.

@kasperpeulen kasperpeulen force-pushed the kasper/yarn-monorepo-refactor branch from c16da0e to 250127b Compare November 27, 2025 10:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (9)
.nvmrc (1)

1-1: Verify documentation consistency across the repository after Node.js version bump.

The .nvmrc file correctly pins Node.js to 22.21.1 (latest stable 22.x, released 2025-10-28). However, based on learnings, .github/copilot-instructions.md still references the outdated version 22.16.0. A past review comment flagged this same issue, and it remains unresolved.

Ensure all references to Node.js version are updated consistently across documentation, CI workflows, Docker configurations, and developer guidelines to reflect the new version.

Run the following verification script to identify all references to the old version:

#!/bin/bash
# Search for Node.js version references across the repository
echo "=== Searching for Node.js 22.16.0 references ==="
rg -n '22\.16\.0' --type yaml --type json --type md --type txt

echo ""
echo "=== Searching for Node.js version references in CI configs ==="
rg -n 'node.*22\.' .github/ --type yaml -A 2 -B 2
code/lib/create-storybook/project.json (1)

4-8: Consistent with broader project.json refactoring.

This file follows the same pattern observed in other library projects (removing $schema, using empty compile/check target blocks, adding ci:normal tags). Confirm NX executor defaults support this minimal configuration.

code/frameworks/nextjs/project.json (1)

4-8: Consistent framework project.json refactoring.

Follows the established pattern. Ensure NX executor defaults support empty target configurations as described in prior reviews.

code/addons/vitest/project.json (1)

4-8: Consistent addon project.json refactoring.

Follows the same pattern as other library and framework projects. Verify NX executor configuration as noted in prior reviews.

code/builders/builder-vite/project.json (1)

4-8: Consistent builder project.json refactoring.

Follows the same pattern as frameworks, addons, and libraries. Ensure NX executor defaults support the empty target configuration.

code/frameworks/react-vite/project.json (1)

4-8: Consistent framework project.json refactoring.

Follows the established pattern across all frameworks. Verify NX executor configuration as noted in prior reviews.

code/renderers/svelte/project.json (1)

12-17: dependsOn with projects: ["*"] is non-standard and not documented by Nx.

According to Nx documentation, the projects field in dependsOn accepts only:

  • "{dependencies}" — all dependency projects
  • "self" — the same project
  • An explicit array of project names (e.g., ["proj1", "proj2"], not ["*"])

The wildcard syntax projects: ["*"] is not documented and may result in undefined behavior. Use one of the documented patterns instead:

  • "dependsOn": ["compile"] (same-project target)
  • "dependsOn": ["^compile"] (dependency projects' compile target)
  • "dependsOn": [{ "projects": "{dependencies}", "target": "compile" }] (explicit object form)
code/renderers/vue3/project.json (1)

12-17: dependsOn with projects: ["*"] remains non-standard.

This issue was previously flagged. According to Nx documentation, the wildcard projects: ["*"] is not a valid value. Use one of the documented patterns:

  • "dependsOn": ["compile"] (same-project target)
  • "dependsOn": ["^compile"] (dependency projects' compile target)
  • "dependsOn": [{ "projects": "{dependencies}", "target": "compile" }] (explicit object form)
nx.json (1)

57-64: {options.dir} placeholder is not a valid Nx token—caching will fail.

This issue was previously flagged: Nx only recognizes {projectRoot}, {workspaceRoot}, and {projectName} as built-in output placeholders. The {options.dir} token at lines 62 and 83 cannot be resolved in targetDefaults outputs.

Replace with {projectName} to match the command patterns:

-      "outputs": ["{workspaceRoot}/sandbox/{options.dir}"],
+      "outputs": ["{workspaceRoot}/sandbox/{projectName}"],
-      "outputs": ["{workspaceRoot}/sandbox/{options.dir}/storybook-static"],
+      "outputs": ["{workspaceRoot}/sandbox/{projectName}/storybook-static"],

Note: Project names like react-vite/default-ts contain /, but the sandbox directories use - (e.g., react-vite-default-ts). You may need a custom approach or ensure directory naming is consistent.

Also applies to: 78-85

🧹 Nitpick comments (16)
scripts/get-template.ts (1)

302-308: Consider validating environment variable conversion.

While the unary plus operator converts to numbers, invalid values will produce NaN, which could lead to undefined behavior when used as an array index (line 55) or in comparisons (line 43).

Consider adding validation:

  const { CIRCLE_NODE_INDEX = 0, CIRCLE_NODE_TOTAL = 1 } = process.env;
+ const index = Number(CIRCLE_NODE_INDEX);
+ const total = Number(CIRCLE_NODE_TOTAL);
+ if (!Number.isFinite(index) || !Number.isFinite(total) || index < 0 || total < 1) {
+   throw new Error(`Invalid CircleCI node configuration: index=${CIRCLE_NODE_INDEX}, total=${CIRCLE_NODE_TOTAL}`);
+ }
  console.log(
    await getTemplate(cadence as Cadence, task, {
-      // Convert to integer
-      index: +CIRCLE_NODE_INDEX,
-      total: +CIRCLE_NODE_TOTAL,
+      index,
+      total,
    })
  );
code/sandbox/internal-react16-webpack/project.json (1)

1-26: Schema removal may impact IDE support and validation.

The root $schema property was removed from this file. While this may be intentional as part of the monorepo restructuring, ensure that NX project validation is still properly configured at the workspace level or via other means. IDE schema hints for this file may be lost.

Please verify:

  1. Whether a workspace-level NX schema is configured to validate all project.json files
  2. Whether the schema removal was intentional or an oversight

If the schema is still needed for this file, consider restoring it or ensuring workspace-level validation covers it.

scripts/task.ts (2)

152-157: Consider validating the dir option value.

The dir option allows custom sandbox directory names but lacks validation. Consider adding validation to ensure it doesn't contain path separators (/, \) or other characters that could cause issues when constructing paths.

Example validation could be added in the options definition:

dir: {
  type: 'string',
  description: 'Name of sandbox directory',
  required: false,
  promptType: false,
  validate: (value: string) => {
    if (value && (value.includes('/') || value.includes('\\'))) {
      throw new Error('Directory name cannot contain path separators');
    }
  },
},

439-443: Redundant optional chaining on array method.

The second optional chaining operator on forEach is unnecessary because filter always returns an array, never undefined.

Apply this diff:

   tasksThatDepend
     .get(task)
     ?.filter((t) => !t.service)
-    ?.forEach(setUnready);
+    .forEach(setUnready);

Additionally, the first ?. operator appears defensive. In getTaskList (lines 257-278), every task added to sortedTasks receives an entry in tasksThatDepend. If get(task) returns undefined, it indicates a bug in the task graph construction rather than an expected edge case.

scripts/event-log-checker.ts (1)

115-117: Based on my verification of the code, I can now provide the rewritten review comment:

Assertion could be more precise for clarity, though current implementation is functionally safe.

The assertion assert.equal(mainEvent.context.anonymousId, undefined) works correctly because getAnonymousProjectId() returns undefined when the git command fails (which occurs in non-git directories). However, using assert.ok(!('anonymousId' in mainEvent.context)) would be more explicit about the intent—verifying the property is absent rather than merely checking its value.

The behavioral change is correct and safe: getAnonymousProjectId() silently catches git failures and returns undefined, which the telemetry code handles properly. The absence of a complementary test for when anonymousId is present (in a git directory) appears intentional, given the commented note at line 121 that CI doesn't provide this value.

Apply this diff for a more precise assertion:

    test(`main event should not contain anonymousId because it is not a git directory`, () => {
-     assert.equal(mainEvent.context.anonymousId, undefined);
+     assert.ok(!('anonymousId' in mainEvent.context));
    });
.env (1)

1-3: Fix environment variable ordering and add trailing newline.

The static analysis tool (dotenv-linter) detected two formatting issues:

  1. Environment variables are not in alphabetical order (dotenv convention).
  2. Missing blank line at end of file.

Apply this diff to fix the formatting:

-STORYBOOK_DISABLE_TELEMETRY=true
-IN_STORYBOOK_SANDBOX=true
-SANDBOX_ROOT=../storybook-sandboxes
+IN_STORYBOOK_SANDBOX=true
+SANDBOX_ROOT=../storybook-sandboxes
+STORYBOOK_DISABLE_TELEMETRY=true
CONTRIBUTING.md (1)

74-97: Docs mostly align with new yarn root; consider two small tweaks

  • The updated tree comment on Line 119 (“Root of the yarn monorepo”) plus the existing code/ entry together now describe the new setup well (root as Yarn workspace, code/ as main source tree). That looks correct with this PR’s goals.
  • The new two-step snippet (yarn then yarn start) on Lines 151–155 is clearer and better matches Yarn 4 behavior than relying on yarn start to install dependencies implicitly. This is a good change.
  • Minor shell nit: on Line 177 the snippet cd code yarn build --watch ... will fail in most shells because cd is given extra args. Consider splitting into two lines or using cd code && yarn build --watch ... for copy‑paste correctness.

Also applies to: 119-119, 151-155, 176-178

scripts/build/build-package.ts (1)

15-41: parseArgs and cwd handling are solid; watch for call‑site expectations

Switching to util.parseArgs with explicit prod/production/optimized/watch booleans is a nice cleanup, and allowNegative: true correctly enables --no-watch semantics.(nodejs.org) A couple of small follow‑ups to consider:

  • parseArgs defaults to strict: true and allowPositionals: false, so any existing invocations that relied on positional args (e.g. a bare package name) or unknown flags will now throw. It’s worth sanity‑checking the scripts/task.ts / Nx call sites to ensure they only pass the options defined here, or explicitly enabling allowPositionals if you still want to tolerate them.
  • DIR_CWD = cwd ? join(ROOT_DIRECTORY, cwd) : process.cwd(); assumes cwd is always relative to the repo root. If a caller ever passes an absolute path, join will mangle it. A small robustness tweak is to treat absolute paths as‑is (e.g., using isAbsolute(cwd)).

Also applies to: 45-51

scripts/build-package.ts (1)

14-18: Consider using consistent import style for path modules.

Line 14 uses the modern node:path prefix while line 18 uses the legacy path import. For consistency and clarity, consider using the node: prefix for all Node.js built-in modules.

Apply this diff to make the imports consistent:

-import { resolve } from 'path';
+import { resolve } from 'node:path';
.nx/workflows/agents.yaml (2)

3-26: Consider extracting shared init steps to reduce duplication.

The linux-init-steps (lines 3-26) and linux-browsers-init-steps (lines 28-70) share identical Checkout, Restore Node Modules Cache, Install Node, and Install Node Modules steps. This duplication increases maintenance burden—any change to cache paths or install commands must be made in both places.

YAML anchors can be nested or composed to reduce this. However, this is a nice-to-have improvement and the current structure works correctly.

Also applies to: 28-70


91-95: Windows template lacks init-steps (TODO).

The windows-js launch template has a placeholder TODO for init-steps. Ensure this is tracked and completed before relying on Windows agents in Nx Cloud workflows.

Do you want me to open an issue to track the Windows init-steps implementation?

scripts/create-nx-sandbox-projects.ts (1)

86-92: Consider removing or conditionalizing debug console.log statements.

Multiple console.log statements (lines 86, 91-92, 99) output debugging information during execution. For production scripts, consider either removing these or gating them behind a --debug flag to reduce noise in CI output.

Also applies to: 99-99

code/package.json (1)

46-48: Confirm Nx includedScripts configuration

Adding the nx block with "includedScripts": [] is valid, but in Nx this typically disables auto-discovery of package.json scripts for this project. If the intent is for Nx to consider some of these scripts as targets (for invalidation, graph display, etc.), you may want to list them explicitly instead of leaving the array empty.

scripts/check/utils/typescript.ts (1)

29-43: Making TS config resolution cwd-aware

Adding the optional cwd parameter and threading it through as the base path and outDir makes this utility much more robust when called from different directories, while the default still preserves previous behavior. One small improvement you might consider (not required for this PR) is to give getTSFilesAndConfig an explicit return type of typescript.ParsedCommandLine to make downstream usage clearer.

scripts/run-registry.ts (2)

40-62: Deduplicate port‑cleanup logic for 6001 and 6002

The kill + retry loops for ports 6001 and 6002 are identical. Functionally this is fine, but it’s an easy place to DRY up and centralize the retry behavior.

You could factor to something like:

-const isPortUsed = async (port: number) => (await detectFreePort(port)) !== port;
+const isPortUsed = async (port: number) => (await detectFreePort(port)) !== port;
 const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
+
+const ensurePortFree = async (port: number) => {
+  if (!(await isPortUsed(port))) {
+    return;
+  }
+
+  await killProcessOnPort(port);
+
+  let attempts = 0;
+  while ((await isPortUsed(port)) && attempts < 10) {
+    await sleep(1000);
+    attempts += 1;
+  }
+};
@@
-  // Kill Verdaccio related processes if they are already running
-  if (await isPortUsed(6001)) {
-    await killProcessOnPort(6001);
-
-    let attempts = 0;
-    while ((await isPortUsed(6001)) && attempts < 10) {
-      await sleep(1000);
-      attempts++;
-    }
-  }
-  if (await isPortUsed(6002)) {
-    await killProcessOnPort(6002);
-    let attempts = 0;
-    while ((await isPortUsed(6002)) && attempts < 10) {
-      await sleep(1000);
-      attempts++;
-    }
-  }
+  // Kill Verdaccio related processes if they are already running
+  await ensurePortFree(6001);
+  await ensurePortFree(6002);

This keeps the behavior identical but makes future tuning of the timeout/backoff logic much simpler.


244-249: Ensure .npmrc is cleaned up on successful non‑publish runs

npmAuth always writes a .npmrc in root, but on the success path where opts.publish === false and !opts.open, the script exits without removing it. That can leave the user’s npm config pointing at http://localhost:6002 even though Verdaccio has been shut down.

You can fix this by moving the .npmrc removal into the non‑open termination path and letting the error handler continue to handle failures:

-  if (opts.publish) {
-    try {
-      await publish(packages, 'http://localhost:6002');
-    } finally {
-      await rm(join(root, '.npmrc'), { force: true });
-    }
-  }
-
-  if (!opts.open) {
-    await servers?.close();
-    process.exit(0);
-  }
+  if (opts.publish) {
+    await publish(packages, 'http://localhost:6002');
+  }
+
+  if (!opts.open) {
+    await servers?.close();
+    await rm(join(root, '.npmrc'), { force: true });
+    process.exit(0);
+  }
@@
 run().catch(async (e) => {
   logger.error(e);
   await servers?.close();
   await rm(join(root, '.npmrc'), { force: true });
   process.exit(1);
 });

This keeps behavior for the existing publish flows but also cleans up .npmrc on a successful “start registry, don’t publish, then exit” run.

Also applies to: 253-254, 258-262

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cc1a401 and 250127b.

⛔ Files ignored due to path filters (11)
  • .yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch is excluded by !**/.yarn/**
  • .yarn/patches/@types-babel__traverse-npm-7.20.6-fac4243243.patch is excluded by !**/.yarn/**
  • .yarn/patches/@vitest-expect-npm-3.2.4-97c526d5cc.patch is excluded by !**/.yarn/**
  • .yarn/patches/react-aria-components-npm-1.12.2-6c5dcdafab.patch is excluded by !**/.yarn/**
  • .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs is excluded by !**/.yarn/**
  • .yarn/plugins/@yarnpkg/plugin-typescript.cjs is excluded by !**/.yarn/**
  • code/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • node_modules/.package-lock.json is excluded by !**/node_modules/**
  • node_modules/.yarn-state.yml is excluded by !**/node_modules/**
  • scripts/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (207)
  • .circleci/config.yml (14 hunks)
  • .circleci/src/jobs/bench-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/build.yml (2 hunks)
  • .circleci/src/jobs/check-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/check.yml (1 hunks)
  • .circleci/src/jobs/chromatic-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/create-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/e2e-dev.yml (1 hunks)
  • .circleci/src/jobs/e2e-production.yml (1 hunks)
  • .circleci/src/jobs/pretty-docs.yml (1 hunks)
  • .circleci/src/jobs/test-runner-production.yml (1 hunks)
  • .circleci/src/jobs/vitest-integration.yml (1 hunks)
  • .cursor/environment.json (1 hunks)
  • .env (1 hunks)
  • .github/actions/setup-node-and-install/action.yml (1 hunks)
  • .github/copilot-instructions.md (5 hunks)
  • .github/workflows/nx.yml (1 hunks)
  • .gitignore (2 hunks)
  • .ignore (0 hunks)
  • .nvmrc (1 hunks)
  • .nx/workflows/agents.yaml (1 hunks)
  • .nx/workflows/distribution-config.yaml (1 hunks)
  • .yarnrc.yml (1 hunks)
  • CONTRIBUTING.md (3 hunks)
  • CONTRIBUTING/RELEASING.md (1 hunks)
  • code/.env (0 hunks)
  • code/.nxignore (0 hunks)
  • code/.yarnrc.yml (0 hunks)
  • code/addons/a11y/package.json (0 hunks)
  • code/addons/a11y/project.json (1 hunks)
  • code/addons/docs/package.json (0 hunks)
  • code/addons/docs/project.json (1 hunks)
  • code/addons/links/package.json (0 hunks)
  • code/addons/links/project.json (1 hunks)
  • code/addons/onboarding/package.json (0 hunks)
  • code/addons/onboarding/project.json (1 hunks)
  • code/addons/pseudo-states/package.json (0 hunks)
  • code/addons/pseudo-states/project.json (1 hunks)
  • code/addons/themes/package.json (0 hunks)
  • code/addons/themes/project.json (1 hunks)
  • code/addons/vitest/package.json (0 hunks)
  • code/addons/vitest/project.json (1 hunks)
  • code/builders/builder-vite/package.json (0 hunks)
  • code/builders/builder-vite/project.json (1 hunks)
  • code/builders/builder-webpack5/package.json (0 hunks)
  • code/builders/builder-webpack5/project.json (1 hunks)
  • code/core/package.json (1 hunks)
  • code/core/project.json (1 hunks)
  • code/e2e-tests/storybook-hooks.spec.ts (2 hunks)
  • code/frameworks/angular/package.json (0 hunks)
  • code/frameworks/angular/project.json (1 hunks)
  • code/frameworks/ember/package.json (0 hunks)
  • code/frameworks/ember/project.json (1 hunks)
  • code/frameworks/html-vite/package.json (0 hunks)
  • code/frameworks/html-vite/project.json (1 hunks)
  • code/frameworks/nextjs-vite/package.json (0 hunks)
  • code/frameworks/nextjs-vite/project.json (1 hunks)
  • code/frameworks/nextjs/package.json (0 hunks)
  • code/frameworks/nextjs/project.json (1 hunks)
  • code/frameworks/nextjs/src/next-image-loader-stub.ts (1 hunks)
  • code/frameworks/preact-vite/package.json (0 hunks)
  • code/frameworks/preact-vite/project.json (1 hunks)
  • code/frameworks/react-native-web-vite/package.json (0 hunks)
  • code/frameworks/react-native-web-vite/project.json (1 hunks)
  • code/frameworks/react-vite/package.json (0 hunks)
  • code/frameworks/react-vite/project.json (1 hunks)
  • code/frameworks/react-webpack5/package.json (0 hunks)
  • code/frameworks/react-webpack5/project.json (1 hunks)
  • code/frameworks/server-webpack5/package.json (0 hunks)
  • code/frameworks/server-webpack5/project.json (1 hunks)
  • code/frameworks/svelte-vite/package.json (0 hunks)
  • code/frameworks/svelte-vite/project.json (1 hunks)
  • code/frameworks/sveltekit/package.json (0 hunks)
  • code/frameworks/sveltekit/project.json (1 hunks)
  • code/frameworks/vue3-vite/package.json (0 hunks)
  • code/frameworks/vue3-vite/project.json (1 hunks)
  • code/frameworks/web-components-vite/package.json (0 hunks)
  • code/frameworks/web-components-vite/project.json (1 hunks)
  • code/lib/cli-sb/project.json (0 hunks)
  • code/lib/cli-storybook/package.json (0 hunks)
  • code/lib/cli-storybook/project.json (1 hunks)
  • code/lib/cli-storybook/src/link.ts (1 hunks)
  • code/lib/codemod/package.json (0 hunks)
  • code/lib/codemod/project.json (1 hunks)
  • code/lib/core-webpack/package.json (0 hunks)
  • code/lib/core-webpack/project.json (1 hunks)
  • code/lib/create-storybook/package.json (0 hunks)
  • code/lib/create-storybook/project.json (1 hunks)
  • code/lib/csf-plugin/package.json (0 hunks)
  • code/lib/csf-plugin/project.json (1 hunks)
  • code/lib/eslint-plugin/package.json (0 hunks)
  • code/lib/eslint-plugin/project.json (1 hunks)
  • code/lib/react-dom-shim/package.json (0 hunks)
  • code/lib/react-dom-shim/project.json (1 hunks)
  • code/nx.json (0 hunks)
  • code/package.json (4 hunks)
  • code/presets/create-react-app/package.json (0 hunks)
  • code/presets/create-react-app/project.json (1 hunks)
  • code/presets/react-webpack/package.json (0 hunks)
  • code/presets/react-webpack/project.json (1 hunks)
  • code/presets/server-webpack/package.json (0 hunks)
  • code/presets/server-webpack/project.json (1 hunks)
  • code/project.json (1 hunks)
  • code/renderers/html/package.json (0 hunks)
  • code/renderers/html/project.json (1 hunks)
  • code/renderers/preact/package.json (0 hunks)
  • code/renderers/preact/project.json (1 hunks)
  • code/renderers/react/package.json (0 hunks)
  • code/renderers/react/project.json (1 hunks)
  • code/renderers/react/src/entry-preview.tsx (0 hunks)
  • code/renderers/server/package.json (0 hunks)
  • code/renderers/server/project.json (1 hunks)
  • code/renderers/svelte/package.json (0 hunks)
  • code/renderers/svelte/project.json (1 hunks)
  • code/renderers/vue3/package.json (0 hunks)
  • code/renderers/vue3/project.json (1 hunks)
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts (0 hunks)
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts (1 hunks)
  • code/renderers/web-components/package.json (0 hunks)
  • code/renderers/web-components/project.json (1 hunks)
  • code/renderers/web-components/src/docs/web-components-properties.test.ts (1 hunks)
  • code/sandbox/angular-cli-default-ts/project.json (1 hunks)
  • code/sandbox/angular-cli-prerelease/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/cra-default-js/project.json (1 hunks)
  • code/sandbox/cra-default-ts/project.json (1 hunks)
  • code/sandbox/ember-3-js/project.json (1 hunks)
  • code/sandbox/ember-default-js/project.json (1 hunks)
  • code/sandbox/experimental-nextjs-vite-default-ts/project.json (0 hunks)
  • code/sandbox/html-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/html-vite-default-js/project.json (1 hunks)
  • code/sandbox/html-vite-default-ts/project.json (1 hunks)
  • code/sandbox/internal-react16-webpack/project.json (1 hunks)
  • code/sandbox/internal-react18-webpack-babel/project.json (1 hunks)
  • code/sandbox/internal-server-webpack5/project.json (1 hunks)
  • code/sandbox/lit-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/lit-vite-default-js/project.json (1 hunks)
  • code/sandbox/lit-vite-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-default-js/project.json (0 hunks)
  • code/sandbox/nextjs-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-prerelease/project.json (1 hunks)
  • code/sandbox/nextjs-vite-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-default-ts/project.json (1 hunks)
  • code/sandbox/nuxt-vite-default-ts/project.json (0 hunks)
  • code/sandbox/preact-vite-default-js/project.json (1 hunks)
  • code/sandbox/preact-vite-default-ts/project.json (1 hunks)
  • code/sandbox/qwik-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-expo-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json (1 hunks)
  • code/sandbox/react-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-default-js/project.json (1 hunks)
  • code/sandbox/react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-prerelease-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-17-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-prerelease-ts/project.json (1 hunks)
  • code/sandbox/solid-vite-default-js/project.json (1 hunks)
  • code/sandbox/solid-vite-default-ts/project.json (1 hunks)
  • code/sandbox/svelte-kit-default-ts/project.json (0 hunks)
  • code/sandbox/svelte-kit-skeleton-js/project.json (0 hunks)
  • code/sandbox/svelte-kit-skeleton-ts/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-js/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-js/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-ts/project.json (1 hunks)
  • docs/_snippets/addon-consume-and-update-globaltype.md (1 hunks)
  • docs/_snippets/main-config-builder-custom-config.md (0 hunks)
  • docs/_snippets/storybook-addon-css-example.md (1 hunks)
  • docs/_snippets/storybook-addon-toolkit-types.md (1 hunks)
  • docs/_snippets/storybook-addons-api-getchannel.md (1 hunks)
  • docs/_snippets/storybook-preview-use-global-type.md (1 hunks)
  • nx.json (1 hunks)
  • package.json (1 hunks)
  • scripts/.yarnrc.yml (0 hunks)
  • scripts/build-package.ts (2 hunks)
  • scripts/build/build-package.ts (2 hunks)
  • scripts/build/utils/generate-bundle.ts (1 hunks)
  • scripts/build/utils/generate-type-mappers.ts (1 hunks)
  • scripts/build/utils/generate-types.ts (2 hunks)
  • scripts/build/utils/modify-core-theme-types.ts (2 hunks)
  • scripts/check-package.ts (1 hunks)
  • scripts/check/check-package.ts (1 hunks)
  • scripts/check/utils/typescript.ts (2 hunks)
  • scripts/create-nx-sandbox-projects.ts (1 hunks)
  • scripts/ecosystem-ci/before-test.js (1 hunks)
  • scripts/event-log-checker.ts (1 hunks)
  • scripts/get-sandbox-dir.ts (2 hunks)
  • scripts/get-template.ts (3 hunks)
  • scripts/knip.config.ts (1 hunks)
  • scripts/package.json (2 hunks)
  • scripts/prepare-sandbox.ts (1 hunks)
  • scripts/project.json (1 hunks)
  • scripts/release/__tests__/version.test.ts (1 hunks)
  • scripts/release/version.ts (2 hunks)
  • scripts/run-registry.ts (8 hunks)
  • scripts/sandbox/utils/getPort.ts (1 hunks)
  • scripts/task.ts (5 hunks)
  • scripts/tasks/build.ts (3 hunks)
  • scripts/tasks/check.ts (2 hunks)
⛔ Files not processed due to max files limit (32)
  • scripts/tasks/chromatic.ts
  • scripts/tasks/compile.ts
  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
  • scripts/tasks/install.ts
  • scripts/tasks/run-registry.ts
  • scripts/tasks/sandbox-parts.ts
  • scripts/tasks/sandbox.ts
  • scripts/tasks/serve.ts
  • scripts/tasks/test-runner-build.ts
  • scripts/upload-bench.ts
  • scripts/utils/cli-utils.ts
  • scripts/utils/constants.ts
  • scripts/utils/kill-process-on-port.ts
  • scripts/utils/main-js.ts
  • scripts/utils/tools.ts
  • scripts/utils/workspace.ts
  • scripts/utils/yarn.ts
  • test-storybooks/portable-stories-kitchen-sink/nextjs/package.json
  • test-storybooks/portable-stories-kitchen-sink/nextjs/project.json
  • test-storybooks/portable-stories-kitchen-sink/react-vitest-3/package.json
  • test-storybooks/portable-stories-kitchen-sink/react-vitest-3/playwright-e2e.config.ts
  • test-storybooks/portable-stories-kitchen-sink/react-vitest-3/project.json
  • test-storybooks/portable-stories-kitchen-sink/react/package.json
  • test-storybooks/portable-stories-kitchen-sink/react/playwright-e2e.config.ts
  • test-storybooks/portable-stories-kitchen-sink/react/project.json
  • test-storybooks/portable-stories-kitchen-sink/svelte/package.json
  • test-storybooks/portable-stories-kitchen-sink/svelte/project.json
  • test-storybooks/portable-stories-kitchen-sink/vue3/package.json
  • test-storybooks/portable-stories-kitchen-sink/vue3/project.json
  • test-storybooks/yarn-pnp/package.json
  • test-storybooks/yarn-pnp/project.json
💤 Files with no reviewable changes (55)
  • code/sandbox/svelte-kit-default-ts/project.json
  • code/renderers/vue3/package.json
  • code/addons/docs/package.json
  • code/addons/vitest/package.json
  • code/renderers/html/package.json
  • code/lib/codemod/package.json
  • code/frameworks/nextjs-vite/package.json
  • code/sandbox/svelte-kit-skeleton-js/project.json
  • code/lib/react-dom-shim/package.json
  • code/frameworks/html-vite/package.json
  • code/lib/create-storybook/package.json
  • code/frameworks/ember/package.json
  • code/frameworks/nextjs/package.json
  • code/frameworks/react-vite/package.json
  • code/frameworks/web-components-vite/package.json
  • code/frameworks/react-native-web-vite/package.json
  • code/renderers/web-components/package.json
  • code/renderers/react/src/entry-preview.tsx
  • code/lib/cli-sb/project.json
  • code/frameworks/angular/package.json
  • code/frameworks/vue3-vite/package.json
  • code/renderers/svelte/package.json
  • code/.env
  • code/builders/builder-vite/package.json
  • code/.yarnrc.yml
  • scripts/.yarnrc.yml
  • code/frameworks/server-webpack5/package.json
  • .ignore
  • code/frameworks/sveltekit/package.json
  • code/lib/csf-plugin/package.json
  • code/addons/themes/package.json
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ReactiveArgs.stories.ts
  • code/lib/cli-storybook/package.json
  • code/frameworks/react-webpack5/package.json
  • code/presets/create-react-app/package.json
  • code/frameworks/svelte-vite/package.json
  • code/renderers/react/package.json
  • code/addons/pseudo-states/package.json
  • code/addons/a11y/package.json
  • code/lib/eslint-plugin/package.json
  • code/addons/links/package.json
  • code/sandbox/nextjs-default-js/project.json
  • code/sandbox/nuxt-vite-default-ts/project.json
  • code/addons/onboarding/package.json
  • code/builders/builder-webpack5/package.json
  • code/renderers/server/package.json
  • code/.nxignore
  • code/lib/core-webpack/package.json
  • code/presets/server-webpack/package.json
  • code/sandbox/experimental-nextjs-vite-default-ts/project.json
  • code/frameworks/preact-vite/package.json
  • docs/_snippets/main-config-builder-custom-config.md
  • code/renderers/preact/package.json
  • code/presets/react-webpack/package.json
  • code/nx.json
✅ Files skipped from review due to trivial changes (1)
  • docs/_snippets/storybook-preview-use-global-type.md
🚧 Files skipped from review as they are similar to previous changes (77)
  • code/frameworks/sveltekit/project.json
  • code/sandbox/nextjs-vite-14-ts/project.json
  • code/sandbox/cra-default-ts/project.json
  • code/renderers/html/project.json
  • code/sandbox/html-vite-default-ts/project.json
  • code/renderers/web-components/src/docs/web-components-properties.test.ts
  • code/renderers/react/project.json
  • .circleci/src/jobs/e2e-production.yml
  • scripts/knip.config.ts
  • scripts/build/utils/generate-types.ts
  • .circleci/src/jobs/build.yml
  • .circleci/src/jobs/chromatic-sandboxes.yml
  • scripts/prepare-sandbox.ts
  • .yarnrc.yml
  • scripts/sandbox/utils/getPort.ts
  • code/frameworks/preact-vite/project.json
  • .circleci/src/jobs/test-runner-production.yml
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/frameworks/angular/project.json
  • .github/copilot-instructions.md
  • code/sandbox/nextjs-vite-default-ts/project.json
  • code/sandbox/nextjs-14-ts/project.json
  • code/sandbox/nextjs-vite-15-ts/project.json
  • code/addons/themes/project.json
  • code/addons/docs/project.json
  • code/renderers/server/project.json
  • .circleci/src/jobs/bench-sandboxes.yml
  • code/renderers/preact/project.json
  • scripts/build/utils/generate-type-mappers.ts
  • code/lib/cli-storybook/src/link.ts
  • code/frameworks/react-webpack5/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/addons/a11y/project.json
  • scripts/release/tests/version.test.ts
  • scripts/project.json
  • scripts/build/utils/modify-core-theme-types.ts
  • .circleci/src/jobs/e2e-dev.yml
  • code/lib/react-dom-shim/project.json
  • code/sandbox/react-webpack-17-ts/project.json
  • scripts/check-package.ts
  • .circleci/src/jobs/pretty-docs.yml
  • code/frameworks/web-components-vite/project.json
  • docs/_snippets/addon-consume-and-update-globaltype.md
  • scripts/build/utils/generate-bundle.ts
  • code/sandbox/preact-vite-default-js/project.json
  • scripts/release/version.ts
  • .circleci/src/jobs/check-sandboxes.yml
  • code/builders/builder-webpack5/project.json
  • code/sandbox/html-rsbuild-default-ts/project.json
  • scripts/package.json
  • code/sandbox/lit-rsbuild-default-ts/project.json
  • code/sandbox/html-vite-default-js/project.json
  • code/lib/csf-plugin/project.json
  • .cursor/environment.json
  • code/sandbox/qwik-vite-default-ts/project.json
  • code/presets/react-webpack/project.json
  • code/sandbox/react-vite-default-ts/project.json
  • docs/_snippets/storybook-addon-css-example.md
  • .circleci/src/jobs/create-sandboxes.yml
  • code/sandbox/react-webpack-18-ts/project.json
  • code/sandbox/solid-vite-default-js/project.json
  • code/frameworks/html-vite/project.json
  • code/frameworks/vue3-vite/project.json
  • code/sandbox/svelte-kit-skeleton-ts/project.json
  • code/sandbox/preact-vite-default-ts/project.json
  • code/sandbox/react-native-web-vite-expo-ts/project.json
  • code/renderers/vue3/template/stories_vue3-vite-default-ts/ScopedSlots.stories.ts
  • .circleci/src/jobs/check.yml
  • .nx/workflows/distribution-config.yaml
  • docs/_snippets/storybook-addon-toolkit-types.md
  • code/e2e-tests/storybook-hooks.spec.ts
  • .github/workflows/nx.yml
  • code/frameworks/svelte-vite/project.json
  • code/sandbox/react-webpack-prerelease-ts/project.json
  • code/sandbox/angular-cli-default-ts/project.json
  • code/frameworks/react-native-web-vite/project.json
  • code/sandbox/angular-cli-prerelease/project.json
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • code/frameworks/nextjs/src/next-image-loader-stub.ts
  • scripts/tasks/check.ts
  • scripts/run-registry.ts
  • scripts/check/check-package.ts
  • scripts/get-sandbox-dir.ts
  • scripts/event-log-checker.ts
  • scripts/create-nx-sandbox-projects.ts
  • scripts/task.ts
  • scripts/build/build-package.ts
  • scripts/check/utils/typescript.ts
  • scripts/tasks/build.ts
  • scripts/get-template.ts
  • scripts/ecosystem-ci/before-test.js
  • scripts/build-package.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • code/frameworks/nextjs/src/next-image-loader-stub.ts
  • scripts/tasks/check.ts
  • scripts/run-registry.ts
  • scripts/check/check-package.ts
  • scripts/get-sandbox-dir.ts
  • scripts/event-log-checker.ts
  • scripts/create-nx-sandbox-projects.ts
  • scripts/task.ts
  • scripts/build/build-package.ts
  • scripts/check/utils/typescript.ts
  • scripts/tasks/build.ts
  • scripts/get-template.ts
  • scripts/build-package.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/frameworks/nextjs/src/next-image-loader-stub.ts
  • scripts/tasks/check.ts
  • code/sandbox/svelte-vite-default-ts/project.json
  • code/addons/pseudo-states/project.json
  • code/frameworks/react-vite/project.json
  • code/sandbox/vue3-rsbuild-default-ts/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/lib/core-webpack/project.json
  • scripts/run-registry.ts
  • code/frameworks/nextjs/project.json
  • code/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/svelte-vite-default-js/project.json
  • code/presets/server-webpack/project.json
  • scripts/check/check-package.ts
  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/sandbox/vue3-vite-default-js/project.json
  • code/sandbox/lit-vite-default-js/project.json
  • code/addons/onboarding/project.json
  • code/addons/vitest/project.json
  • code/lib/cli-storybook/project.json
  • code/core/project.json
  • code/builders/builder-vite/project.json
  • scripts/get-sandbox-dir.ts
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/ember-default-js/project.json
  • code/lib/create-storybook/project.json
  • code/sandbox/react-rsbuild-default-ts/project.json
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • scripts/event-log-checker.ts
  • code/sandbox/ember-3-js/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • code/sandbox/internal-server-webpack5/project.json
  • code/renderers/vue3/project.json
  • code/addons/links/project.json
  • scripts/task.ts
  • code/frameworks/nextjs-vite/project.json
  • scripts/build/build-package.ts
  • code/presets/create-react-app/project.json
  • code/core/package.json
  • code/renderers/svelte/project.json
  • scripts/check/utils/typescript.ts
  • scripts/tasks/build.ts
  • scripts/get-template.ts
  • scripts/ecosystem-ci/before-test.js
  • code/sandbox/internal-react16-webpack/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/cra-default-js/project.json
  • code/sandbox/nextjs-prerelease/project.json
  • code/sandbox/nextjs-15-ts/project.json
  • nx.json
  • code/frameworks/ember/project.json
  • code/sandbox/internal-react18-webpack-babel/project.json
  • code/frameworks/server-webpack5/project.json
  • code/renderers/web-components/project.json
  • code/sandbox/react-vite-default-js/project.json
  • code/lib/eslint-plugin/project.json
  • package.json
  • code/sandbox/nextjs-default-ts/project.json
  • scripts/build-package.ts
  • code/lib/codemod/project.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/package.json
code/**/!(*.test).{ts,tsx,js,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

code/**/!(*.test).{ts,tsx,js,mjs}: Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error
Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error
Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/frameworks/nextjs/src/next-image-loader-stub.ts
.nvmrc

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Node.js 22.16.0 as specified in .nvmrc

Files:

  • .nvmrc
🧠 Learnings (37)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Run 'yarn task --task check' to verify TypeScript types across all packages before submitting PRs

Applied to files:

  • scripts/tasks/check.ts
  • scripts/check/check-package.ts
  • CONTRIBUTING/RELEASING.md
  • code/renderers/svelte/project.json
  • scripts/check/utils/typescript.ts
  • .circleci/config.yml
  • scripts/build-package.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn lint:js:cmd <file>' to check for ESLint issues after making changes

Applied to files:

  • scripts/tasks/check.ts
  • code/project.json
  • scripts/check/check-package.ts
  • scripts/create-nx-sandbox-projects.ts
  • scripts/check/utils/typescript.ts
  • package.json
  • .gitignore
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn prettier --write <file>' to format code after making changes

Applied to files:

  • scripts/tasks/check.ts
  • CONTRIBUTING.md
  • code/sandbox/vue3-rsbuild-default-ts/project.json
  • code/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/nextjs-15-ts/project.json
  • .gitignore
  • code/sandbox/nextjs-default-ts/project.json
  • scripts/build-package.ts
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • scripts/tasks/check.ts
  • CONTRIBUTING.md
  • code/project.json
  • CONTRIBUTING/RELEASING.md
  • .circleci/config.yml
  • scripts/build-package.ts
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'yarn vitest run --coverage <test-file>' to run tests with coverage reports and aim for 75%+ coverage of statements/lines

Applied to files:

  • scripts/tasks/check.ts
  • CONTRIBUTING.md
  • code/project.json
  • package.json
  • .gitignore
  • code/package.json
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • code/sandbox/svelte-vite-default-ts/project.json
  • CONTRIBUTING.md
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • scripts/check/check-package.ts
  • code/addons/vitest/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • nx.json
  • package.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/package.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • code/sandbox/svelte-vite-default-ts/project.json
  • CONTRIBUTING.md
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • scripts/ecosystem-ci/before-test.js
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/react-vite-default-js/project.json
  • package.json
  • .gitignore
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to README.md : Update relevant README files for significant changes

Applied to files:

  • CONTRIBUTING.md
  • CONTRIBUTING/RELEASING.md
  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • CONTRIBUTING.md
  • .env
  • code/lib/create-storybook/project.json
  • scripts/event-log-checker.ts
  • scripts/create-nx-sandbox-projects.ts
  • code/core/package.json
  • scripts/tasks/build.ts
  • scripts/get-template.ts
  • .circleci/config.yml
  • package.json
  • .gitignore
  • scripts/build-package.ts
  • code/package.json
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • CONTRIBUTING.md
  • code/core/package.json
  • package.json
  • .gitignore
  • code/package.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Document complex mock behaviors in Vitest tests

Applied to files:

  • CONTRIBUTING.md
  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Group related mocks together in Vitest tests

Applied to files:

  • CONTRIBUTING.md
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Keep mock implementations simple and focused in Vitest tests

Applied to files:

  • CONTRIBUTING.md
  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid inline mock implementations within test cases in Vitest tests

Applied to files:

  • CONTRIBUTING.md
  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required properties and methods that the test subject uses in Vitest tests

Applied to files:

  • CONTRIBUTING.md
  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock at the highest level of abstraction needed in Vitest tests

Applied to files:

  • CONTRIBUTING.md
📚 Learning: 2025-09-29T13:20:23.346Z
Learnt from: mrginglymus
Repo: storybookjs/storybook PR: 32556
File: code/core/package.json:309-313
Timestamp: 2025-09-29T13:20:23.346Z
Learning: The `fast-printf` dependency in Storybook's core package is bundled into the final distribution during the build process, so it should remain in devDependencies rather than being moved to dependencies, following the same pattern as other bundled dependencies like `open`.

Applied to files:

  • CONTRIBUTING.md
  • package.json
  • code/package.json
📚 Learning: 2025-09-17T07:31:04.432Z
Learnt from: ndelangen
Repo: storybookjs/storybook PR: 32484
File: code/core/package.json:326-326
Timestamp: 2025-09-17T07:31:04.432Z
Learning: In Storybook's core package, dependencies like `open` are bundled into the final distribution during the build process, so they should remain in devDependencies rather than being moved to dependencies. End users don't need these packages as separate runtime dependencies since they're included in the bundled code.

Applied to files:

  • CONTRIBUTING.md
  • code/core/package.json
  • scripts/ecosystem-ci/before-test.js
  • package.json
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'cd code && yarn storybook:ui' to start the development server for testing UI changes on http://localhost:6006/

Applied to files:

  • CONTRIBUTING.md
  • .circleci/config.yml
  • code/package.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking without the `spy: true` option in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
  • .gitignore
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mock implementations outside of `beforeEach` blocks in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid direct function mocking without `vi.mocked()` in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .nvmrc : Use Node.js 22.16.0 as specified in .nvmrc

Applied to files:

  • .nvmrc
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx} : Enable TypeScript strict mode

Applied to files:

  • scripts/check/check-package.ts
  • scripts/check/utils/typescript.ts
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: The useGlobals hook from storybook/manager-api returns a tuple where the third element (storyGlobals) is typed as Globals, not Globals | undefined. This means TypeScript guarantees it's always defined, making the `in` operator safe to use without additional null checks.

Applied to files:

  • docs/_snippets/storybook-addons-api-getchannel.md
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: In viewport tool code, when using the `useGlobals` hook from storybook/manager-api, the third returned value `storyGlobals` is guaranteed by TypeScript to be defined (not undefined/null), making the `in` operator safe to use without additional null checks.

Applied to files:

  • docs/_snippets/storybook-addons-api-getchannel.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager

Applied to files:

  • CONTRIBUTING/RELEASING.md
  • .github/actions/setup-node-and-install/action.yml
  • .gitignore
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Work on feature branches following the Git workflow

Applied to files:

  • CONTRIBUTING/RELEASING.md
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • scripts/get-sandbox-dir.ts
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • scripts/task.ts
  • scripts/tasks/build.ts
  • scripts/get-template.ts
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • .circleci/config.yml
  • nx.json
  • .circleci/src/jobs/vitest-integration.yml
  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Use ESLint and Prettier for code style enforcement

Applied to files:

  • code/lib/eslint-plugin/project.json
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Test files should follow the naming pattern `*.test.ts`, `*.test.tsx`, `*.spec.ts`, or `*.spec.tsx`

Applied to files:

  • .gitignore
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to code/**/!(*.test).{ts,tsx,js,mjs} : Use 'logger' from 'storybook/internal/node-logger' for server-side (Node.js) logging, not console.log/console.warn/console.error

Applied to files:

  • .gitignore
  • code/package.json
📚 Learning: 2025-11-05T09:38:47.712Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.

Applied to files:

  • code/package.json
📚 Learning: 2025-11-05T09:37:25.920Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/tooltip/WithTooltip.tsx:54-96
Timestamp: 2025-11-05T09:37:25.920Z
Learning: Repo: storybookjs/storybook — In code/core/src/components/components/tooltip/WithTooltip.tsx, the legacy WithTooltip implementation is intentionally reintroduced for backward compatibility and is deprecated; maintainers (per Sidnioulz) do not want maintenance or improvements on it. Prefer WithTooltipNew/Popover; avoid suggesting changes to WithTooltip.* going forward.

Applied to files:

  • code/package.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to code/**/!(*.test).{ts,tsx,js,mjs} : Use 'logger' from 'storybook/internal/client-logger' for client-side (browser) logging, not console.log/console.warn/console.error

Applied to files:

  • code/package.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required dependencies that the test subject uses

Applied to files:

  • code/package.json
🧬 Code graph analysis (1)
scripts/get-template.ts (1)
code/lib/cli-storybook/src/sandbox-templates.ts (2)
  • allTemplates (988-992)
  • templatesByCadence (1051-1051)
🪛 dotenv-linter (4.0.0)
.env

[warning] 2-2: [UnorderedKey] The IN_STORYBOOK_SANDBOX key should go before the STORYBOOK_DISABLE_TELEMETRY key

(UnorderedKey)


[warning] 3-3: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)


[warning] 3-3: [UnorderedKey] The SANDBOX_ROOT key should go before the STORYBOOK_DISABLE_TELEMETRY key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: daily
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.nx/workflows/distribution-config.yaml (1)

13-21: Clarify parallelism allocation for mixed target types.

Rule 2 assigns parallelism: 6 uniformly to heterogeneous targets: compile, check, lint, pretty-docs, and knip. However, targets like lint and pretty-docs typically benefit minimally from high parallelism due to their single-threaded or I/O-bound nature, making this configuration potentially wasteful of agent resources.

Consider either:

  1. Splitting these targets into separate rules with appropriate parallelism values (e.g., parallelism: 6 for compile and check; parallelism: 1–2 for lint, pretty-docs, knip).
  2. Documenting the rationale if this allocation is intentional (e.g., if targets are I/O-heavy or have other parallelization benefits).
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 250127b and ec6d354.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (1)
  • .nx/workflows/distribution-config.yaml (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: daily
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (1)
.nx/workflows/distribution-config.yaml (1)

6-12: Verify the intent behind the core-project-only assignment rule.

The first assignment rule is narrowly scoped to the core project with parallelism: 1. Other projects' compile targets fall through to Rule 2 (with parallelism: 6). This asymmetry suggests core may require special handling (e.g., longer compile times, resource contention), but the rationale is not documented.

Clarify whether this is intentional (and if so, document it) or if other projects should also have dedicated rules.

…refactor

# Conflicts:
#	.circleci/config.yml
#	code/package.json
#	code/sandbox/solid-vite-default-js/project.json
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
scripts/run-registry.ts (1)

42-43: Consider parallelizing port cleanup.

Both killPort calls are independent and could run concurrently to speed up startup:

-  await killPort(6001);
-  await killPort(6002);
+  await Promise.all([killPort(6001), killPort(6002)]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae1ebf8 and f04dd28.

📒 Files selected for processing (3)
  • scripts/run-registry.ts (8 hunks)
  • scripts/tasks/run-registry.ts (1 hunks)
  • scripts/utils/port.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/tasks/run-registry.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/utils/port.ts
  • scripts/run-registry.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/utils/port.ts
  • scripts/run-registry.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/utils/port.ts
  • scripts/run-registry.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager
📚 Learning: 2025-11-05T09:38:47.712Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/components/components/Select/Select.tsx:200-204
Timestamp: 2025-11-05T09:38:47.712Z
Learning: Repo: storybookjs/storybook — Guidance: Until Storybook 11 is released, do not suggest using React.useId anywhere (e.g., in code/core/src/components/components/Select/Select.tsx) to maintain compatibility with React 17 runtimes. Prefer advising: accept a caller-provided props.id and, if needed, generate a client-only fallback id to minimize SSR hydration issues — but avoid useId. Resume prompting for useId after Storybook 11.

Applied to files:

  • scripts/run-registry.ts
📚 Learning: 2025-09-29T13:20:23.346Z
Learnt from: mrginglymus
Repo: storybookjs/storybook PR: 32556
File: code/core/package.json:309-313
Timestamp: 2025-09-29T13:20:23.346Z
Learning: The `fast-printf` dependency in Storybook's core package is bundled into the final distribution during the build process, so it should remain in devDependencies rather than being moved to dependencies, following the same pattern as other bundled dependencies like `open`.

Applied to files:

  • scripts/run-registry.ts
📚 Learning: 2025-09-17T07:31:04.432Z
Learnt from: ndelangen
Repo: storybookjs/storybook PR: 32484
File: code/core/package.json:326-326
Timestamp: 2025-09-17T07:31:04.432Z
Learning: In Storybook's core package, dependencies like `open` are bundled into the final distribution during the build process, so they should remain in devDependencies rather than being moved to dependencies. End users don't need these packages as separate runtime dependencies since they're included in the bundled code.

Applied to files:

  • scripts/run-registry.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • scripts/run-registry.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (8)
scripts/utils/port.ts (2)

1-5: LGTM! Clean utility implementations.

The isPortUsed and sleep functions are concise and correctly implemented. The port detection logic correctly identifies a port as "in use" when detectFreePort returns a different port than the one requested.


7-19: Well-structured retry logic with proper error handling.

The killPort function addresses the previous review feedback by:

  1. Throwing an error after exhausting retry attempts (20 attempts × 1 second = 20 seconds timeout)
  2. Only attempting to kill if the port is actually in use

One minor consideration: if killProcessOnPort(port) itself throws, the error will propagate immediately without cleanup. This is likely acceptable since there's no partial state to clean up.

scripts/run-registry.ts (6)

14-16: Clean import organization.

The new imports align with the refactoring goals: killPort centralizes port management, ROOT_DIRECTORY provides consistent path resolution, and getCodeWorkspaces reflects the monorepo restructuring.


79-91: Proper cleanup abstraction with graceful shutdown.

The servers.close() method correctly handles concurrent shutdown of both servers using Promise.all. The closure captures verdaccioApp appropriately, and the logging provides visibility during shutdown.


182-182: Module-level state enables proper cleanup.

Declaring servers at module scope allows the error handler at line 239 to access it for cleanup. The undefined initial value is handled correctly with optional chaining (servers?.close()).


226-230: Proper resource cleanup with try/finally.

The try/finally block ensures .npmrc is removed even if publish throws, preventing credentials from persisting on disk.


239-246: Robust error handling with guaranteed cleanup.

This implementation correctly addresses the previous review feedback:

  • servers?.close() is wrapped in a try block
  • .npmrc removal runs in the finally block regardless of whether close() succeeds
  • The original error is re-thrown after cleanup

190-197: Perfect! I've completed the verification. The review comment's concern about ROOT_DIRECTORY has been confirmed as accurate.

ROOT_DIRECTORY correctly resolves to the git root, and the cache path construction is proper.

ROOT_DIRECTORY is defined as join(__dirname, '..', '..') in scripts/utils/constants.ts (line 8), where __dirname is scripts/utils/. Two parent directory traversals correctly reach the repository root. The import in scripts/run-registry.ts (line 14) is correct, and the cache path join(ROOT_DIRECTORY, '.verdaccio-cache') will place it at the expected location in the monorepo root.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
.github/workflows/nx.yml (2)

35-49: PR and push conditionals are well-structured.

The label-based filtering for PRs and the branch-based filtering for pushes align well with the NX run-many pattern. The task escalation (normal → merged → daily) is logical.

However, ensure the pull-requests: read permission is added (see earlier comment) for the label conditions to work correctly.

Consider optimizing fetch-depth for push events. Since affected analysis typically requires full history, the current fetch-depth: 0 is appropriate here, but document why this is needed if it impacts CI performance.


21-21: Consider centralizing task definitions for maintainability.

The ALL_TASKS list is comprehensive but long and may be harder to maintain as tasks evolve. Consider defining task groupings via NX tags or a separate configuration file that's referenced in the workflow, making it easier to update in one place.

For example, extract this to a config file like .nx/task-groups.json or define task collections in nx.json and reference them from the workflow.

scripts/tasks/test-runner-build.ts (2)

16-20: Clarify the selectedTask mapping logic.

The conditional on line 19 maps selectedTask === 'test-runner' to 'serve', otherwise uses 'dev'. This assumes the test-runner task only ever runs against either a served build or a dev server. If selectedTask could have other values, this fallback to 'dev' might be unexpected.

Consider adding a comment explaining this mapping, or making it more explicit:

-        ? getPort({ key, selectedTask: selectedTask === 'test-runner' ? 'serve' : 'dev' })
+        // test-runner depends on 'serve' for built sandboxes; other tasks use 'dev'
+        ? getPort({ key, selectedTask: selectedTask === 'test-runner' ? 'serve' : 'dev' })

31-31: Consider logging when waitOn times out.

The 200-second timeout is generous, but if it fails, the error from waitOn may not clearly indicate what URL was being waited on. This is consistent with other task files, so no immediate action needed, but consider whether enhanced error messaging would help debugging.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f04dd28 and 4446340.

📒 Files selected for processing (5)
  • .github/workflows/nx.yml (1 hunks)
  • scripts/tasks/dev.ts (2 hunks)
  • scripts/tasks/e2e-tests-build.ts (3 hunks)
  • scripts/tasks/serve.ts (1 hunks)
  • scripts/tasks/test-runner-build.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/tasks/test-runner-build.ts
  • scripts/tasks/serve.ts
  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/tasks/test-runner-build.ts
  • scripts/tasks/serve.ts
  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/tasks/test-runner-build.ts
  • scripts/tasks/serve.ts
  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • scripts/tasks/test-runner-build.ts
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required dependencies that the test subject uses

Applied to files:

  • scripts/tasks/test-runner-build.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • scripts/tasks/test-runner-build.ts
  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Do not use 'yarn task --task dev' or 'yarn start' as these start permanent development servers that run indefinitely

Applied to files:

  • scripts/tasks/dev.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'cd code && yarn storybook:ui' to start the development server for testing UI changes on http://localhost:6006/

Applied to files:

  • scripts/tasks/dev.ts
  • scripts/tasks/e2e-tests-build.ts
🧬 Code graph analysis (2)
scripts/tasks/serve.ts (1)
scripts/task.ts (1)
  • Task (57-79)
scripts/tasks/dev.ts (2)
scripts/tasks/serve.ts (1)
  • PORT (10-12)
scripts/task.ts (1)
  • Task (57-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (11)
.github/workflows/nx.yml (2)

14-15: NX Cloud and task distribution setup looks good.

The integration with NX Cloud (token, start-ci-run, set-shas) is properly configured for distributed CI execution. This aligns well with the new NX-based orchestration described in the PR.

Also applies to: 27-27, 33-33


23-26: The sparse checkout filter tree:0 is valid and correctly configured.

GitHub Actions' actions/checkout@v4 officially supports the filter: tree:0 input as a Git partial-clone option that produces a treeless/minimal clone. This is documented in the checkout README and is a legitimate performance optimization, not a misconfiguration. Combined with fetch-depth: 0, this configuration is intentional and correct.

scripts/tasks/test-runner-build.ts (1)

1-6: LGTM on imports and structure.

The new imports for waitOn and getPort are appropriate for the dynamic port resolution pattern being introduced across the task files.

scripts/tasks/dev.ts (3)

14-16: LGTM on the getDevPort helper.

Clean extraction of port resolution logic. The pattern is consistent with getServePort in serve.ts, and the fallback to PORT when NX_CLI_SET is not set preserves backward compatibility.


42-57: Parallel waitOn calls are a good approach for responsiveness benchmarking.

Both iframe.html and index.html are awaited in parallel with Promise.all, correctly capturing independent timing for preview and manager responsiveness. The 200-second timeout is consistent with other task files.


22-25: Perfect! I have now verified all the necessary information. Let me confirm the findings:

Verification Summary:

  1. TemplateDetails type includes key: The TemplateDetails type definition (scripts/task.ts:45-53) explicitly includes key: TemplateKey as the first property.

  2. Task.ready signature: The Task type defines ready: (details: TemplateDetails, options?: PassedOptionValues) => MaybePromise<boolean>, which means ready() receives TemplateDetails as its first parameter.

  3. Call sites pass TemplateDetails: The single call site at scripts/task.ts:410 invokes t.ready(details, optionValues), where details is of type TemplateDetails.

  4. dev.ts is compatible: The dev.ts ready() function correctly destructures { key } from the first parameter, which will always be available since TemplateDetails includes it.

The review comment's concern is verified and accurate. The code change is safe and properly typed.


All call sites pass the required key property to ready(). The TemplateDetails type includes key: TemplateKey, which is always passed as the first parameter to the ready() function via t.ready(details, optionValues) at scripts/task.ts:410. The destructuring of { key } in dev.ts is correctly typed and guaranteed to succeed.

scripts/tasks/serve.ts (4)

4-7: LGTM on the updated imports.

The imports are well-organized. The type import syntax for Task and TemplateKey correctly indicates these are type-only imports, which can help with tree-shaking.


14-16: Consistent pattern with getDevPort.

The getServePort helper follows the same pattern as getDevPort in dev.ts, maintaining consistency across task files.


40-40: Different waitOn resource format noted.

This file uses tcp:127.0.0.1:${port} while dev.ts and test-runner-build.ts use http://localhost:${port}. The TCP check is appropriate here since http-server with -s (silent mode) might not respond to HTTP requests the same way, and you're just checking port availability. This is a valid approach.


31-32: The review comment's concern is not valid—http-server is correctly accessible from ROOT_DIRECTORY.

Root package.json includes http-server in devDependencies (version ^14.1.1), and ROOT_DIRECTORY in scripts/utils/constants.ts is correctly defined as join(__dirname, '..', '..'), which resolves to the repository root. With yarn workspaces configured, devDependencies hoisted at the root are available to workspace packages. The cwd change is correct and requires no adjustment.

scripts/tasks/e2e-tests-build.ts (1)

2-2: Server readiness gating with waitOn is appropriate

Importing wait-on and awaiting the sandbox URL before executing Playwright keeps tests from racing the server startup, and the interval/timeout values are reasonable for CI. No issues from a task-flow standpoint.

Also applies to: 40-40

Comment on lines +10 to +12
permissions:
actions: read
contents: read
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Add missing pull-requests: read permission for label-based conditionals.

The workflow reads PR labels in conditional steps (lines 36-44) but lacks the required pull-requests: read permission. Without this permission, the label checks may fail silently or behave unexpectedly, especially for external pull requests.

Apply this diff to add the missing permission:

 permissions:
   actions: read
   contents: read
+  pull-requests: read
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
actions: read
contents: read
permissions:
actions: read
contents: read
pull-requests: read
🤖 Prompt for AI Agents
.github/workflows/nx.yml around lines 10 to 12: the workflow currently grants
only actions: read and contents: read but omits pull-requests: read which is
required for steps that check PR labels; update the permissions block to include
pull-requests: read so label-based conditionals can access PR metadata (add the
permission alongside the existing ones).

import { dedent } from 'ts-dedent';
import waitOn from 'wait-on';

import { getPort } from '../sandbox/utils/getPort';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, read the e2e-tests-build.ts file to understand the full context
echo "=== Content of scripts/tasks/e2e-tests-build.ts ==="
wc -l scripts/tasks/e2e-tests-build.ts

Repository: storybookjs/storybook

Length of output: 152


🏁 Script executed:

#!/bin/bash
# Read the file with line numbers to see the context around lines 4, 20-24, 45
cat -n scripts/tasks/e2e-tests-build.ts

Repository: storybookjs/storybook

Length of output: 2410


🏁 Script executed:

#!/bin/bash
# Inspect the getPort implementation
echo "=== Looking for getPort definition ==="
fd -t f "getPort*" --exec cat -n {} +

echo ""
echo "=== Broader search for getPort.ts ==="
fd -name "getPort*" -type f

Repository: storybookjs/storybook

Length of output: 1111


🏁 Script executed:

#!/bin/bash
# Search for usages of NX_CLI_SET and selectedTask
echo "=== NX_CLI_SET usages ==="
rg -n "NX_CLI_SET" -C3

echo ""
echo "=== selectedTask usages ==="
rg -n "selectedTask" -C3

echo ""
echo "=== getPort usages ==="
rg -n "getPort" -C3

Repository: storybookjs/storybook

Length of output: 16085


🏁 Script executed:

#!/bin/bash
# Check the tasks object and TaskKey definition
echo "=== tasks object and TaskKey definition ==="
rg -n "export.*tasks|type TaskKey" scripts/task.ts -A5

echo ""
echo "=== Check all instances of the conditional mapping pattern ==="
rg -n "selectedTask.*\?" --type ts

Repository: storybookjs/storybook

Length of output: 811


🏁 Script executed:

#!/bin/bash
# Check if there's any shared config or helper for task mapping
echo "=== Search for any mapping helpers or configs ==="
fd -name "*.ts" -type f scripts/tasks/ -exec grep -l "serve\|dev" {} \; | head -20

echo ""
echo "=== Check the Task type to understand selectedTask better ==="
rg -n "type Task|interface Task" scripts/task.ts -B2 -A15 | head -60

Repository: storybookjs/storybook

Length of output: 2263


🏁 Script executed:

#!/bin/bash
# Check if selectedTask is always provided and required
echo "=== Check TemplateDetails type definition ==="
rg -n "type TemplateDetails|interface TemplateDetails" scripts/task.ts -A20

echo ""
echo "=== Verify all build tasks receive selectedTask ==="
rg -n "async run\(" scripts/tasks/*.ts -A1 | grep -E "(run\(|selectedTask)"

Repository: storybookjs/storybook

Length of output: 2282


Address duplicated task-name-to-port-key mapping in build tasks

The conditional port resolution is duplicated identically in e2e-tests-build.ts (line 23) and test-runner-build.ts (line 19), with the pattern selectedTask === 'taskName' ? 'serve' : 'dev'. This duplication creates maintenance risk:

  • Renaming e2e-tests or test-runner tasks will silently break port calculation without TypeScript catching it, since the mapping uses string literals rather than type-safe references
  • The port-calculation strategy—which defines which port key each task uses—is scattered across files instead of being centralized

Consider extracting this mapping to a shared helper function (e.g., getPortTaskKey(selectedTask: TaskKey): TaskKey) and using it consistently across both build tasks. This keeps the strategy explicit and maintainable when task names change in the future.

🤖 Prompt for AI Agents
In scripts/tasks/e2e-tests-build.ts around line 4 (and similarly update
test-runner-build.ts at its port logic), the port-key selection uses a
duplicated string-literal conditional (selectedTask === 'taskName' ? 'serve' :
'dev'), which is fragile and duplicated; extract this logic into a shared helper
exported from a common utils module (e.g., getPortTaskKey(selectedTask:
TaskKey): TaskKey) that maps TaskKey -> TaskKey using type-safe TaskKey values
(not string literals), replace the inline conditional with a call to this helper
in both e2e-tests-build.ts and test-runner-build.ts, and update imports and
types accordingly so renaming tasks is caught by TypeScript and the mapping
lives in one place.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4446340 and 7c89c17.

📒 Files selected for processing (1)
  • .circleci/config.yml (14 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to README.md : Update relevant README files for significant changes

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'cd code && yarn storybook:ui' to start the development server for testing UI changes on http://localhost:6006/

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • .circleci/config.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (7)
.circleci/config.yml (7)

344-344: Clarify why chromatic-sandboxes requires SANDBOX_ROOT=./sandbox.

The chromatic-sandboxes job explicitly sets SANDBOX_ROOT=./sandbox on both the prepare-sandbox and yarn task steps (lines 344, 347), while other sandbox jobs do not set this variable. Per the PR objectives, the default is ../storybook-sandboxes. Confirm:

  1. Why chromatic specifically requires the ./sandbox variant (noted as "not recommended" in PR objectives)
  2. Whether this is intentional or a temporary workaround
  3. Whether the environment variable is correctly inherited by both yarn workspace and yarn task commands

Also applies to: 347-347


325-325: Confirm resource class upgrades are justified.

Several jobs have been upgraded to medium+ resource class:

  • Line 325: chromatic-sandboxes (from small/default to medium+)
  • Line 563: pretty-docs (from default to medium+)
  • Line 988: test-portable-stories (from default to medium+)

These upgrades likely reflect increased workload after the monorepo refactor. However, document or confirm:

  1. Each upgrade addresses a specific performance or reliability issue
  2. No other sandbox or test jobs also require resource upgrades but were missed
  3. Cost impact has been considered

Also applies to: 563-563, 988-988


210-216: Clarify necessity of explicit yarn invocation in compile steps.

Both build (line 212) and check (line 262) jobs now explicitly run yarn before the yarn task --task compile command. Since both jobs use attach_workspace to restore previously-built node_modules, confirm whether this explicit invocation is:

  1. Necessary to regenerate workspace state after attachment
  2. Redundant and can be removed
  3. Required due to potential changes in root-level dependencies

If the explicit yarn is necessary, consider documenting why in the config or a comment for future maintainers.

Also applies to: 260-268


387-398: Confirm node_modules cleanup path in create-sandboxes is correct.

Line 394 uses cd $(yarn get-sandbox-dir --template $TEMPLATE) && rm -rf node_modules to clean up sandbox node_modules after test event collection. Since this job doesn't set SANDBOX_ROOT, sandboxes will default to ../storybook-sandboxes (per PR objectives). Verify:

  1. The cleanup path correctly resolves to the external sandbox directory
  2. The cleanup doesn't interfere with workspace persistence (which uses ./sandbox)
  3. Both cleanup and persistence work correctly for non-chromatic sandboxes

208-208: Cache consolidation strategy is correct—no separate lock files in code/ or scripts/ directories.

The verification confirms that the root yarn.lock is the sole lock file for the main monorepo. The code/ and scripts/ directories are workspaces managed by the root package.json, not isolated installations with their own lock files. Other yarn.lock and lock files found are in test-storybooks and fixtures directories only, which are test projects and fixtures, not part of the main monorepo dependencies.

Cache invalidation will properly trigger when any workspace dependency changes, as all are tracked in the root lock file.


189-189: The prepare-sandbox command is properly configured and functional across all CI jobs.

Verification confirms:

  • scripts/package.json defines the script: "prepare-sandbox": "jiti ./prepare-sandbox.ts"
  • scripts/prepare-sandbox.ts exists and properly parses all required arguments:
    • --template (required string argument) ✓
    • --link (boolean with allowNegative: true, supporting --no-link) ✓
  • The script correctly uses environment-based path constants (SANDBOX_DIRECTORY, ROOT_DIRECTORY) ✓
  • All seven CI jobs (bench, check, chromatic, e2e-dev, e2e-production, test-runner, vitest-integration) will execute successfully with this command

No configuration issues found.


230-245: I'll help you verify the node_modules persistence changes in the CircleCI configuration. Let me start by examining the build job and downstream jobs to understand the impact of this change.
<function_calls>


#!/bin/bash

Check the build job for yarn invocations at root level

echo "=== Build job section ==="
rg -B5 -A25 "- build:" .circleci/config.yml | head -80

echo ""
echo "=== Jobs that use attach_workspace ==="
rg -B3 "attach_workspace:" .circleci/config.yml | head -100

echo ""
echo "=== Checking for root yarn commands ==="
rg "yarn\s+(install|workspace|workspaces)" .circleci/config.yml | head -20


</function_calls>

#!/bin/bash # Get the full config file line count to understand its structure echo "=== Config file stats ===" wc -l .circleci/config.yml

echo ""
echo "=== Full build job with persist_to_workspace ==="

Find the build job and extract it completely

sed -n '/^\sbuild:/,/^\s[a-z_-]*:/p' .circleci/config.yml | head -150


</function_calls>

#!/bin/bash # Find the actual build job and see what commands it runs echo "=== Searching for build job definition ===" rg -A100 "^\s+build:" .circleci/config.yml | grep -A100 "steps:" | head -120 #!/bin/bash # More targeted search for persist_to_workspace and surrounding context echo "=== Context around persist_to_workspace (lines 225-255) ===" sed -n '225,255p' .circleci/config.yml

echo ""
echo "=== Looking for yarn install commands in build job ==="
sed -n '1,250p' .circleci/config.yml | grep -n "yarn" | tail -20


</function_calls>

#!/bin/bash # Get the full build job section to understand the complete picture echo "=== Build job and related commands ===" sed -n '130,260p' .circleci/config.yml #!/bin/bash # Check all jobs that use attach_workspace and what they do with node_modules echo "=== All job definitions with attach_workspace ===" rg -B15 "attach_workspace:" .circleci/config.yml | grep -E "^\s+(- |[a-z_-]+:)" | head -40

echo ""
echo "=== Check if any downstream jobs run yarn commands ==="
rg -A20 "attach_workspace:" .circleci/config.yml | grep -E "(yarn|npm)" | head -20


</function_calls>

#!/bin/bash # Get a full view of the config structure and job dependencies echo "=== Complete workflow section to see job dependencies ===" tail -100 .circleci/config.yml

echo ""
echo "=== Count total jobs ==="
rg "^\s{2}[a-z_-]+:" .circleci/config.yml | wc -l


</function_calls>

#!/bin/bash # Full file to understand complete context echo "=== Total lines and file structure ===" wc -l .circleci/config.yml

echo ""
echo "=== Checking if file is complete (last 50 lines) ==="
tail -50 .circleci/config.yml


</function_calls>

#!/bin/bash # Read the entire config file to understand structure cat -n .circleci/config.yml #!/bin/bash # Parse the YAML to understand structure better echo "=== All job names ===" rg "^\s{2}[a-z_-]+:" .circleci/config.yml

echo ""
echo "=== Jobs with attach_workspace ==="
rg -B20 "attach_workspace:" .circleci/config.yml | grep ":\s*$" | grep -v "steps|parameters|environment"


</function_calls>

#!/bin/bash # Focus on finding: (1) where yarn runs, (2) which jobs need node_modules echo "=== Lines with yarn commands and context ===" rg -n "yarn" .circleci/config.yml

echo ""
echo "=== Lines with persist_to_workspace and attach_workspace ==="
rg -n "persist_to_workspace|attach_workspace" .circleci/config.yml


</function_calls>

<function_calls>


#!/bin/bash

Read the full config with line numbers to analyze

cat -n .circleci/config.yml | tail -100


</function_calls>

#!/bin/bash # Get beginning of file cat -n .circleci/config.yml | head -150 #!/bin/bash # Middle section cat -n .circleci/config.yml | sed -n '140,170p' #!/bin/bash # Section around persist_to_workspace cat -n .circleci/config.yml | sed -n '220,260p' #!/bin/bash # Parse with Python to understand YAML structure and identify key information python3 << 'EOF' import re

with open('.circleci/config.yml', 'r') as f:
content = f.read()
lines = content.split('\n')

Find yarn commands

print("=== YARN COMMANDS ===")
for i, line in enumerate(lines, 1):
if 'yarn' in line.lower() and not line.strip().startswith('#'):
print(f"Line {i}: {line}")

print("\n=== PERSIST/ATTACH WORKSPACE ===")
for i, line in enumerate(lines, 1):
if 'persist_to_workspace' in line or 'attach_workspace' in line:
# Get context
start = max(0, i-5)
end = min(len(lines), i+15)
for j in range(start, end):
prefix = ">>> " if j == i-1 else " "
print(f"{prefix}{j+1}: {lines[j]}")
print()

print("\n=== JOB DEFINITIONS ===")
in_jobs = False
for i, line in enumerate(lines, 1):
if line.strip() == 'jobs:':
in_jobs = True
elif in_jobs and re.match(r'^[a-z]', line):
in_jobs = False
if in_jobs and re.match(r'^\s{2}[a-z_-]+:\s*$', line):
print(f"Line {i}: {line.strip()}")
EOF


</function_calls>

<function_calls>


#!/bin/bash

Get specific sections that matter

echo "=== BUILD JOB STEPS (lines 140-245) ==="
sed -n '140,245p' .circleci/config.yml

echo ""
echo "=== WORKFLOWS AND JOB DEPENDENCIES ==="
tail -50 .circleci/config.yml


</function_calls>

Now let me analyze what we found:

<function_calls>


#!/bin/bash

Let's extract just the critical sections in readable format

python3 << 'EOF'
import yaml

with open('.circleci/config.yml', 'r') as f:
config = yaml.safe_load(f)

Find all job definitions

print("=== ALL JOBS ===")
for job_name in config.get('jobs', {}).keys():
print(f"- {job_name}")

print("\n=== BUILD JOB DETAILS ===")
build_job = config.get('jobs', {}).get('build', {})
if build_job:
print(f"Working directory: {build_job.get('working_directory', 'default')}")
steps = build_job.get('steps', [])
print(f"Number of steps: {len(steps)}")

# Look for yarn commands
print("\nYarn commands in build job:")
for i, step in enumerate(steps):
    if isinstance(step, dict):
        if 'run' in step:
            run_cmd = step['run']
            if isinstance(run_cmd, dict):
                command = run_cmd.get('command', '')
            else:
                command = run_cmd
            if 'yarn' in str(command).lower():
                print(f"  Step {i}: {command[:100]}...")
        elif 'persist_to_workspace' in step:
            persist = step['persist_to_workspace']
            print(f"  Persist paths: {persist.get('paths', [])}")
            print(f"  Persist root: {persist.get('root', 'N/A')}")

print("\n=== JOBS WITH ATTACH_WORKSPACE ===")
for job_name, job_config in config.get('jobs', {}).items():
steps = job_config.get('steps', [])
for step in steps:
if isinstance(step, dict) and 'attach_workspace' in step:
print(f"- {job_name}")
print(f" At path: {step['attach_workspace'].get('at', 'N/A')}")

print("\n=== WORKFLOW ==="

)
if 'workflows' in config:
for workflow_name, workflow_config in config['workflows'].items():
print(f"Workflow: {workflow_name}")
jobs = workflow_config.get('jobs', [])
for job_entry in jobs:
if isinstance(job_entry, dict):
for job_name, job_config in job_entry.items():
requires = job_config.get('requires', []) if isinstance(job_config, dict) else []
print(f" - {job_name} (requires: {requires})")
else:
print(f" - {job_entry}")
EOF


</function_calls>

<function_calls>


#!/bin/bash

Install pyyaml if needed and re-run

pip install pyyaml -q 2>/dev/null || true

python3 << 'EOF'
import yaml

try:
with open('.circleci/config.yml', 'r') as f:
config = yaml.safe_load(f)

print("=== ALL JOBS ===")
for job_name in sorted(config.get('jobs', {}).keys()):
    print(f"  {job_name}")

print("\n=== BUILD JOB - YARN COMMANDS ===")
build_job = config.get('jobs', {}).get('build', {})
if build_job:
    steps = build_job.get('steps', [])
    for i, step in enumerate(steps):
        if isinstance(step, dict) and 'run' in step:
            run_step = step['run']
            if isinstance(run_step, dict):
                cmd = run_step.get('command', '')
            elif isinstance(run_step, str):
                cmd = run_step
            else:
                cmd = str(run_step)
            
            if 'yarn' in cmd.lower():
                print(f"  Step {i}: {cmd[:150]}")

print("\n=== JOBS USING ATTACH_WORKSPACE ===")
for job_name, job_config in sorted(config.get('jobs', {}).items()):
    steps = job_config.get('steps', [])
    uses_attach = False
    for step in steps:
        if isinstance(step, dict) and 'attach_workspace' in step:
            uses_attach = True
            at_path = step['attach_workspace'].get('at', '.')
            print(f"  {job_name} (at: {at_path})")
    
    # Also check for run commands that might use node_modules
    if not uses_attach:
        for step in steps:
            if isinstance(step, dict) and 'run' in step:
                run_step = step['run']
                cmd = str(run_step) if not isinstance(run_step, str) else run_step
                if 'yarn' in cmd.lower() or 'npm' in cmd.lower():
                    print(f"  {job_name} - uses npm/yarn but NO attach_workspace!")
                    break

print("\n=== PERSIST_TO_WORKSPACE ===")
for job_name, job_config in sorted(config.get('jobs', {}).items()):
    steps = job_config.get('steps', [])
    for step in steps:
        if isinstance(step, dict) and 'persist_to_workspace' in step:
            persist = step['persist_to_workspace']
            paths = persist.get('paths', [])
            root = persist.get('root', '.')
            print(f"  {job_name}:")
            print(f"    root: {root}")
            print(f"    paths: {paths}")

except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
EOF


</function_calls>

Perfect! Now I have the structure. Let me verify the specific claims in the review comment:

<function_calls>


#!/bin/bash

Get detailed view of build job and its steps

sed -n '160,250p' .circleci/config.yml


</function_calls>

#!/bin/bash # Check if there are any issues with the persist_to_workspace paths echo "=== Checking for potential issues ===" echo "" echo "1. Are all paths in persist_to_workspace being populated?" echo " Paths: node_modules, code/node_modules, code/addons, code/bench," echo " code/examples, code/frameworks, code/lib, code/core, code/builders," echo " code/renderers, code/presets, scripts/node_modules, .verdaccio-cache" echo "" echo "2. Searching for yarn workspace setup in config:" rg -n "workspace" .circleci/config.yml | head -10 echo "" echo "3. Looking for any build/setup steps at root:" sed -n '160,230p' .circleci/config.yml | grep -n "run\|command" | head -20

<function_calls>


#!/bin/bash

Let's examine the specific lines mentioned in the review (230-245)

echo "=== LINES 230-245 (as mentioned in review) ==="
sed -n '230,245p' .circleci/config.yml

echo ""
echo "=== LINES 220-245 (broader context) ==="
sed -n '220,245p' .circleci/config.yml


</function_calls>

<function_calls>


#!/bin/bash

Get full build job to see all yarn commands

echo "=== Full BUILD job definition ==="
python3 << 'EOF'
import yaml

with open('.circleci/config.yml', 'r') as f:
config = yaml.safe_load(f)

build_job = config['jobs']['build']

Print all steps

for i, step in enumerate(build_job['steps']):
print(f"\n--- Step {i} ---")
for key, value in step.items():
if key == 'run':
if isinstance(value, dict):
print(f" {key}:")
for k, v in value.items():
if k == 'command':
print(f" {k}: {v[:200] if len(str(v)) > 200 else v}")
else:
print(f" {k}: {v}")
else:
print(f" {key}: {value[:200] if len(str(value)) > 200 else value}")
else:
print(f" {key}: {value}")
EOF


</function_calls>

Excellent! Now I have detailed information. Let me check the workflows to understand job dependencies:

<function_calls>


#!/bin/bash

Check workflows and which jobs depend on build job

echo "=== WORKFLOWS - Job dependencies ==="
python3 << 'EOF'
import yaml

with open('.circleci/config.yml', 'r') as f:
config = yaml.safe_load(f)

workflows = config.get('workflows', {})
for workflow_name, workflow_config in workflows.items():
print(f"\n=== Workflow: {workflow_name} ===")
jobs = workflow_config.get('jobs', [])
for job_entry in jobs:
if isinstance(job_entry, dict):
for job_name, job_config in job_entry.items():
requires = job_config.get('requires', []) if isinstance(job_config, dict) else []
print(f" {job_name}: requires {requires}")
else:
print(f" {job_entry}: no dependencies")
EOF


</function_calls>

<function_calls>


#!/bin/bash

Check which downstream jobs attach workspace

echo "=== Downstream jobs that use attach_workspace ==="
python3 << 'EOF'
import yaml

with open('.circleci/config.yml', 'r') as f:
config = yaml.safe_load(f)

jobs = config['jobs']
for job_name, job_config in sorted(jobs.items()):
if job_name == 'build':
continue

steps = job_config.get('steps', [])
for step in steps:
    if isinstance(step, dict) and 'attach_workspace' in step:
        attach = step['attach_workspace']
        print(f"\n{job_name}:")
        print(f"  - attaches workspace at: {attach.get('at', '.')}")
        
        # Check what this job does with node_modules
        for s in steps:
            if isinstance(s, dict) and 'run' in s:
                run_val = s['run']
                cmd = run_val if isinstance(run_val, str) else run_val.get('command', '')
                if 'yarn' in str(cmd).lower() or 'npm' in str(cmd).lower():
                    print(f"  - uses npm/yarn: {str(cmd)[:100]}...")
        break

EOF


</function_calls>

Perfect! Now I have comprehensive information. Let me create a final verification summary:

<function_calls>


#!/bin/bash

Final verification - check git root working directory

echo "=== Working directory configuration ==="
python3 << 'EOF'
import yaml

with open('.circleci/config.yml', 'r') as f:
config = yaml.safe_load(f)

build_job = config['jobs']['build']
print(f"Build job working_directory: {build_job.get('working_directory', 'default (repo root)')}")

Get first few steps to show the yarn commands clearly

print("\nFirst yarn command in build job:")
for step in build_job['steps']:
if isinstance(step, dict) and 'run' in step:
run_val = step['run']
cmd = run_val if isinstance(run_val, str) else run_val.get('command', '')
if 'yarn' in str(cmd).lower():
print(f" {cmd[:200]}")
break
EOF


</function_calls>

Based on my thorough verification of the .circleci/config.yml file, I can now provide the rewritten review comment:

Root node_modules persistence is correctly configured for the monorepo structure.

The build job:

  1. Runs yarn at root: The build job executes yarn install at the repository root (default working directory), which populates root node_modules with workspace dependencies
  2. Downstream jobs restore correctly: Multiple downstream test and build jobs use attach_workspace at path . to restore all persisted artifacts, including the root node_modules
  3. All three node_modules directories are necessary: The monorepo structure requires maintaining node_modules (root workspace deps), code/node_modules (main package deps), and scripts/node_modules (tooling deps), alongside other build artifacts (code/addons, code/bench, etc.)

The change is sound—persisting root node_modules alongside the existing subdirectory node_modules ensures that workspace-level tooling and dependencies are available to all downstream jobs that attach the workspace.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/create-nx-sandbox-projects.ts (1)

82-117: I'll verify the review comment about the CWD-dependent output path in the script. Let me gather information about how this script is actually invoked and whether the concern about brittleness is valid.
<function_calls>

#!/bin/bash

Check how the create-nx-sandbox-projects script is wired up

rg -n "create-nx-sandbox-projects" -C3 --type-add 'scripts:*.json' -t scripts


</function_calls>

<function_calls>

#!/bin/bash

Find package.json files and search for references to the script

find . -name "package.json" -type f | head -20 | xargs grep -l "create-nx-sandbox" 2>/dev/null


</function_calls>

<function_calls>

#!/bin/bash

Broader search for create-nx-sandbox-projects references

rg "create-nx-sandbox-projects" -n --max-count=20


</function_calls>

<function_calls>

#!/bin/bash

Find the actual script file

find . -name "create-nx-sandbox-projects.ts" -type f


</function_calls>

<function_calls>

#!/bin/bash

Check what's in scripts directory and find TypeScript files

fd -t f ".ts$" scripts/ | head -20


</function_calls>

<function_calls>

#!/bin/bash

List top-level directories

ls -la | head -30


</function_calls>

<function_calls>

#!/bin/bash

Try to find the scripts directory

git ls-files | grep -E "scripts/.*.ts$" | head -20


</function_calls>

<function_calls>

#!/bin/bash

Search for the file more broadly

git ls-files | grep -i sandbox


</function_calls>

<function_calls>

#!/bin/bash

Check directory structure

git ls-files | grep "^scripts/" | head -30


</function_calls>

Now let me examine the actual file mentioned in the review:
<function_calls>

#!/bin/bash

Try to read the file directly

wc -l scripts/create-nx-sandbox-projects.ts


</function_calls>

<function_calls>

#!/bin/bash

Read the entire file

cat -n scripts/create-nx-sandbox-projects.ts


</function_calls>

<function_calls>

#!/bin/bash

Check TypeScript configuration

cat tsconfig.json | head -50


</function_calls>

<function_calls>

#!/bin/bash

Search for __dirname usage in TypeScript files

rg "__dirname" --type ts --type tsx -n | head -20


</function_calls>

<function_calls>

#!/bin/bash

Search for import.meta.url usage

rg "import.meta.url" --type ts --type tsx -n


</function_calls>

<function_calls>

#!/bin/bash

Check what's in the scripts directory

ls -la scripts/


</function_calls>

<function_calls>

#!/bin/bash

Find root package.json and check scripts

find . -maxdepth 2 -name "package.json" -exec grep -H "sandbox" {} ;


</function_calls>

<function_calls>

#!/bin/bash

Look for any .sh or script execution references

rg "create-nx-sandbox-projects|sandbox" package.json -A2 -B2


</function_calls>

<function_calls>

#!/bin/bash

Read root package.json scripts section

cat package.json | grep -A 100 '"scripts"' | head -120


</function_calls>

<function_calls>

#!/bin/bash

Check for GitHub Actions workflows

find .github -name ".yml" -o -name ".yaml" 2>/dev/null | xargs grep -l "sandbox" 2>/dev/null | head -10


</function_calls>

<function_calls>

#!/bin/bash

Check the context around where this script might be run

Look for any shell script files that might call this

find scripts -name ".sh" -o -name ".json" | xargs grep -l "create-nx" 2>/dev/null


</function_calls>

<function_calls>

#!/bin/bash

Check the directory structure

From scripts directory, ../code/sandbox would be:

If repo is /repo, scripts is /repo/scripts, then ../code/sandbox is /repo/code/sandbox

Let's verify this exists

ls -la code/sandbox 2>/dev/null || echo "Does not exist at repo/code/sandbox"
ls -la ../code/sandbox 2>/dev/null || echo "Does not exist at ../code/sandbox from root"


</function_calls>

<function_calls>

#!/bin/bash

Check if code directory exists at root

ls -la | grep code
fd -t d "^code$"


</function_calls>

<function_calls>

#!/bin/bash

List top-level items in repo

git ls-tree -r --name-only HEAD | cut -d/ -f1 | sort -u | head -30


</function_calls>

<function_calls>

#!/bin/bash

Key insight: let's check what the current code does

Line 86 uses process.cwd() + '../code/sandbox'

If CWD is /repo, then this becomes /repo/../code/sandbox = /code/sandbox (WRONG!)

If CWD is /repo/scripts, then this becomes /repo/scripts/../code/sandbox = /repo/code/sandbox (CORRECT!)

Let's verify by checking if there's any documentation in the file about CWD expectations

head -50 scripts/create-nx-sandbox-projects.ts | grep -i "cwd|directory|run"


</function_calls>

<function_calls>

#!/bin/bash

Let's verify the imports and see if __dirname equivalent can be easily created

sed -n '1,10p' scripts/create-nx-sandbox-projects.ts


</function_calls>

Perfect. I've now verified the review comment. The analysis confirms that:

  1. The concern is valid: The code at line 86 uses join(process.cwd(), '../code/sandbox', ...) which is indeed brittle and CWD-dependent. It only works correctly if the script is executed from the scripts/ directory.

  2. The file already has the infrastructure: Lines 1-4 show the file already imports fileURLToPath and uses import.meta.url, which means creating a __dirname equivalent is straightforward.

  3. The suggested fix is sound: Using the script location (via import.meta.url which is already available) would make this much more robust.

  4. No workaround or mitigation found: There's no evidence of documentation or safeguards that would make the current approach acceptable.

Resolve CWD-dependent path construction to ensure script works regardless of invocation directory

The path join(process.cwd(), '../code/sandbox', ...) assumes the script runs from the scripts/ directory and will fail or write to the wrong location otherwise. Since the file already imports fileURLToPath and uses import.meta.url (lines 1–4), use those to derive __dirname and construct an anchor path relative to the script location instead of relying on process.cwd(). This makes the script robust across any invocation context.

♻️ Duplicate comments (1)
.github/workflows/nx.yml (1)

10-12: Add missing pull-requests: read permission for label-based conditionals.

The workflow reads PR labels in conditional steps (lines 36-44) but lacks the required pull-requests: read permission. Without this permission, the label checks may fail silently or behave unexpectedly, especially for external pull requests.

Apply this diff to add the missing permission:

 permissions:
   actions: read
   contents: read
+  pull-requests: read
🧹 Nitpick comments (2)
code/sandbox/ember-default-js/project.json (1)

3-28: Ember sandbox tags are now empty – confirm CI intent

This project now has tags: [] even though ember/default-js is still listed in normal/merged/daily template arrays, so it will no longer participate in tag-based Nx CI runs. If Ember is intended to be temporarily excluded (e.g., via inDevelopment on the template), this is fine; otherwise, consider restoring the ci:* tags or removing it from those template lists to avoid confusion.

scripts/create-nx-sandbox-projects.ts (1)

13-79: Generator structure and conditional targets look solid (with minor DRY opportunity)

The projectJson helper cleanly centralizes description, implicitDependencies, and dir-scoped targets, and the typeCheck/skipTasks logic matches the various sandbox project.json outputs. If you want to trim repetition, you could factor a small helper like const skip = (task: string) => template.skipTasks?.includes(task); and reuse it for each conditional block, but that’s purely cosmetic.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c89c17 and 6e6a31c.

📒 Files selected for processing (52)
  • .github/workflows/nx.yml (1 hunks)
  • code/addons/vitest/src/vitest-plugin/index.ts (2 hunks)
  • code/renderers/svelte/project.json (1 hunks)
  • code/renderers/vue3/project.json (1 hunks)
  • code/sandbox/angular-cli-default-ts/project.json (1 hunks)
  • code/sandbox/angular-cli-prerelease/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json (1 hunks)
  • code/sandbox/bench-react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/cra-default-js/project.json (1 hunks)
  • code/sandbox/cra-default-ts/project.json (1 hunks)
  • code/sandbox/ember-3-js/project.json (1 hunks)
  • code/sandbox/ember-default-js/project.json (1 hunks)
  • code/sandbox/html-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/html-vite-default-js/project.json (1 hunks)
  • code/sandbox/html-vite-default-ts/project.json (1 hunks)
  • code/sandbox/internal-react16-webpack/project.json (1 hunks)
  • code/sandbox/internal-react18-webpack-babel/project.json (1 hunks)
  • code/sandbox/internal-server-webpack5/project.json (1 hunks)
  • code/sandbox/lit-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/lit-vite-default-js/project.json (1 hunks)
  • code/sandbox/lit-vite-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-default-ts/project.json (1 hunks)
  • code/sandbox/nextjs-prerelease/project.json (1 hunks)
  • code/sandbox/nextjs-vite-14-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-15-ts/project.json (1 hunks)
  • code/sandbox/nextjs-vite-default-ts/project.json (1 hunks)
  • code/sandbox/preact-vite-default-js/project.json (1 hunks)
  • code/sandbox/preact-vite-default-ts/project.json (1 hunks)
  • code/sandbox/qwik-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-expo-ts/project.json (1 hunks)
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json (1 hunks)
  • code/sandbox/react-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-default-js/project.json (1 hunks)
  • code/sandbox/react-vite-default-ts/project.json (1 hunks)
  • code/sandbox/react-vite-prerelease-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-17-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-18-ts/project.json (1 hunks)
  • code/sandbox/react-webpack-prerelease-ts/project.json (1 hunks)
  • code/sandbox/solid-vite-default-ts/project.json (1 hunks)
  • code/sandbox/svelte-kit-skeleton-ts/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-js/project.json (1 hunks)
  • code/sandbox/svelte-vite-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-rsbuild-default-ts/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-js/project.json (1 hunks)
  • code/sandbox/vue3-vite-default-ts/project.json (1 hunks)
  • docs/_snippets/addon-consume-and-update-globaltype.md (1 hunks)
  • scripts/create-nx-sandbox-projects.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • code/sandbox/nextjs-14-ts/project.json
🚧 Files skipped from review as they are similar to previous changes (24)
  • code/sandbox/react-webpack-prerelease-ts/project.json
  • code/sandbox/react-native-web-vite-expo-ts/project.json
  • code/sandbox/nextjs-vite-15-ts/project.json
  • code/sandbox/lit-rsbuild-default-ts/project.json
  • code/sandbox/nextjs-vite-default-ts/project.json
  • code/sandbox/vue3-rsbuild-default-ts/project.json
  • code/sandbox/preact-vite-default-js/project.json
  • code/sandbox/nextjs-15-ts/project.json
  • code/sandbox/react-native-web-vite-rn-cli-ts/project.json
  • code/sandbox/nextjs-vite-14-ts/project.json
  • code/addons/vitest/src/vitest-plugin/index.ts
  • code/sandbox/qwik-vite-default-ts/project.json
  • code/sandbox/nextjs-default-ts/project.json
  • code/sandbox/html-rsbuild-default-ts/project.json
  • code/sandbox/react-rsbuild-default-ts/project.json
  • code/sandbox/svelte-kit-skeleton-ts/project.json
  • code/sandbox/react-webpack-17-ts/project.json
  • code/renderers/svelte/project.json
  • code/sandbox/react-webpack-18-ts/project.json
  • code/sandbox/vue3-vite-default-js/project.json
  • code/sandbox/preact-vite-default-ts/project.json
  • code/sandbox/svelte-vite-default-js/project.json
  • code/sandbox/internal-react16-webpack/project.json
  • code/sandbox/lit-vite-default-js/project.json
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • code/sandbox/cra-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/sandbox/svelte-vite-default-ts/project.json
  • code/sandbox/angular-cli-default-ts/project.json
  • code/sandbox/internal-server-webpack5/project.json
  • code/sandbox/react-vite-default-ts/project.json
  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/sandbox/html-vite-default-ts/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/nextjs-prerelease/project.json
  • code/sandbox/angular-cli-prerelease/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/ember-3-js/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/cra-default-js/project.json
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/react-vite-default-js/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
  • code/sandbox/html-vite-default-js/project.json
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • code/renderers/vue3/project.json
  • code/sandbox/ember-default-js/project.json
  • code/sandbox/internal-react18-webpack-babel/project.json
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/create-nx-sandbox-projects.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/create-nx-sandbox-projects.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • code/sandbox/cra-default-ts/project.json
  • code/sandbox/bench-react-vite-default-ts-nodocs/project.json
  • code/sandbox/svelte-vite-default-ts/project.json
  • code/sandbox/angular-cli-default-ts/project.json
  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/sandbox/bench-react-vite-default-ts/project.json
  • code/sandbox/html-vite-default-ts/project.json
  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/nextjs-prerelease/project.json
  • code/sandbox/angular-cli-prerelease/project.json
  • scripts/create-nx-sandbox-projects.ts
  • code/sandbox/ember-3-js/project.json
  • code/sandbox/bench-react-vite-default-ts-test-build/project.json
  • code/sandbox/cra-default-js/project.json
  • code/sandbox/bench-react-webpack-18-ts-test-build/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/react-vite-default-js/project.json
  • code/sandbox/html-vite-default-js/project.json
  • code/sandbox/bench-react-webpack-18-ts/project.json
  • code/sandbox/internal-react18-webpack-babel/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests

Applied to files:

  • code/sandbox/react-vite-prerelease-ts/project.json
  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid inline mock implementations within test cases in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Keep mock implementations simple and focused in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking without the `spy: true` option in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mock implementations outside of `beforeEach` blocks in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid direct function mocking without `vi.mocked()` in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Document complex mock behaviors in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
  • code/sandbox/lit-vite-default-ts/project.json
  • code/sandbox/vue3-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:59.279Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Mock all required properties and methods that the test subject uses in Vitest tests

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,mjs} : Use camelCase for variable and function names

Applied to files:

  • code/sandbox/solid-vite-default-ts/project.json
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn prettier --write <file>' to format code after making changes

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.{ts,tsx,js,jsx,json,html,mjs} : Run 'yarn lint:js:cmd <file>' to check for ESLint issues after making changes

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • scripts/create-nx-sandbox-projects.ts
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: In viewport tool code, when using the `useGlobals` hook from storybook/manager-api, the third returned value `storyGlobals` is guaranteed by TypeScript to be defined (not undefined/null), making the `in` operator safe to use without additional null checks.

Applied to files:

  • docs/_snippets/addon-consume-and-update-globaltype.md
📚 Learning: 2025-09-18T20:51:06.618Z
Learnt from: Sidnioulz
Repo: storybookjs/storybook PR: 32458
File: code/core/src/viewport/components/Tool.tsx:38-39
Timestamp: 2025-09-18T20:51:06.618Z
Learning: The useGlobals hook from storybook/manager-api returns a tuple where the third element (storyGlobals) is typed as Globals, not Globals | undefined. This means TypeScript guarantees it's always defined, making the `in` operator safe to use without additional null checks.

Applied to files:

  • docs/_snippets/addon-consume-and-update-globaltype.md
🧬 Code graph analysis (1)
scripts/create-nx-sandbox-projects.ts (1)
code/lib/cli-storybook/src/sandbox-templates.ts (5)
  • Template (30-106)
  • allTemplates (978-982)
  • normal (984-1003)
  • merged (1005-1015)
  • daily (1017-1040)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (39)
docs/_snippets/addon-consume-and-update-globaltype.md (1)

14-21: Documentation formatting improvement — verify PR scope alignment.

The formatting changes improve code readability by properly separating the updateGlobals call closure from the comment and subsequent emit call. The example remains functionally correct and follows proper Storybook API usage patterns.

However, this documentation change appears disconnected from the stated PR scope (monorepo root refactoring from ./code to repository root). Please confirm whether this file should be included in this PR or if it was modified separately.

code/sandbox/cra-default-js/project.json (2)

1-27: Verify the generation script and CI tag removal.

This file is marked as auto-generated by scripts/create-nx-sandbox-projects.ts, so changes should be verified against that script to ensure it was updated to produce this structure.

Additionally, the removal of the "ci:daily" tag (line 26) is a behavioral change—verify that this won't impact CI workflows or task scheduling.


3-13: Consistent with PR standardization.

The expanded implicitDependencies array now includes the CLI and multiple addons (addon-a11y, addon-docs, addon-vitest), aligning with the monorepo refactor pattern applied across other sandbox projects. The dir options on sandbox and build targets (lines 15, 18) correctly reference the sandbox directory name.

code/renderers/vue3/project.json (4)

5-5: Verify the empty compile target is intentional.

The compile target is defined but empty ({}). Clarify whether:

  1. This is a placeholder/dependency marker with no actual compilation step for Vue3
  2. It should contain an executor and options (e.g., running a Vue3 build or type-check step)

Confirm this aligns with the migration pattern across other renderers in the monorepo.


6-9: Type-checking target configuration looks correct.

The check target properly delegates Vue type-checking via nx:run-commands with vue-tsc --noEmit, which aligns with the refactored compile+check workflow.


11-11: CI tag standardization is correct.

The tags: ["ci:normal"] addition aligns with the PR objective to standardize CI tag usage across renderer project configs.


5-11: Verify the removal of the build target does not break CI or dependent projects.

The refactor replaces the build target with separate compile and check targets. Confirm that:

  1. CI workflows and other projects no longer reference the build target
  2. The new compile and check targets are properly wired into downstream tasks
  3. Other renderers follow the same pattern for consistency
code/sandbox/angular-cli-prerelease/project.json (1)

18-18: The review comment is incorrect. The naming is intentional, not a bug.

The file is correctly auto-generated. Across all sandbox projects in the codebase, the target is consistently named "build" (not "build-sandbox"), paired with "prepare-build-sandbox". This asymmetric naming is intentional:

  • The generation script (lines 51–56 in scripts/create-nx-sandbox-projects.ts) deliberately produces "build" as the target name
  • nx.json explicitly configures "prepare-build-sandbox" to depend on the "build" target
  • All sandbox project.json files follow this same pattern consistently

The assumption that the target should be named "build-sandbox" for symmetry with "sandbox" / "prepare-sandbox" is unfounded. The actual design intentionally uses "build" as the primary target name.

Likely an incorrect or invalid review comment.

code/sandbox/internal-server-webpack5/project.json (3)

3-3: I'll help you verify the auto-generated nature of this file and gather evidence about the script that generates it. Let me run some investigation scripts.
<function_calls>

#!/bin/bash

Step 1: Verify the create-nx-sandbox-projects.ts script exists

echo "=== Checking for create-nx-sandbox-projects.ts ==="
fd -e ts 'create-nx-sandbox-projects' 2>/dev/null | head -5

Step 2: Check file size before reading

echo -e "\n=== File size check ==="
fd -e ts 'create-nx-sandbox-projects' -x wc -l {} 2>/dev/null

Step 3: List all sandbox project.json files

echo -e "\n=== All sandbox project.json files ==="
fd 'project.json' 'code/sandbox' --type f 2>/dev/null | sort

Step 4: Count total sandbox project.json files

echo -e "\n=== Total count ==="
fd 'project.json' 'code/sandbox' --type f 2>/dev/null | wc -l


</function_calls>


5-13: "addon-links" removal is intentional and consistent across all sandbox projects.

The verification shows:

  • Zero sandbox projects reference "addon-links" in their implicit dependencies
  • The "addon-links" package does not exist in the monorepo
  • All sandbox projects follow an identical implicit dependency pattern (core, cli, addon-a11y, addon-docs, addon-vitest, addon-onboarding, plus environment-specific package)

The internal-server-webpack5 project.json is aligned with the standard across all sandboxes. There is no selective oversight here.


15-25: All targets are properly configured in the root nx.json.

Verification confirms that all 11 targets defined as empty objects {} in code/sandbox/internal-server-webpack5/project.json have their full implementations in root/nx.json under targetDefaults. This is the correct and intentional pattern in Nx—project-level project.json files reference task definitions from the workspace targetDefaults, allowing centralized configuration management. The empty objects properly inherit all configuration (dependsOn, command, cache, inputs, outputs, etc.) from the root definitions.

code/sandbox/nextjs-prerelease/project.json (3)

5-13: Verify the expanded implicitDependencies list is intentional.

The implicitDependencies list expanded from 4 packages to 7, adding "cli", "addon-a11y", "addon-docs", and "addon-vitest". Confirm these are necessary dependencies for the Next.js prerelease sandbox in the new monorepo structure after moving the root to git root.


15-24: Clarify the sparse target definitions and verify executor configuration location.

Most targets (lines 16–17, 19–24) are defined as empty objects {}, with only sandbox and build specifying a dir option. Confirm this is intentional and that the executor configurations (commands, scripts, etc.) are defined at the root level or in shared Nx configurations, not expected to be in this file.


3-3: Based on my verification, I now have enough information to provide the rewritten review comment.


This file was not regenerated in this PR; verify if regeneration was required for the migration.

The generation script at scripts/create-nx-sandbox-projects.ts was not run as part of this PR—git diff shows no changes to either the script or this file. The file content matches what the script would produce, but the absence of a git diff indicates no regeneration occurred. Confirm whether the monorepo root migration required running this script to update sandbox project files.

code/sandbox/cra-default-ts/project.json (2)

5-13: The implicitDependencies list in cra-default-ts is appropriately scoped and consistent with all other sandboxes.

All 50+ sandbox projects in the codebase follow the same pattern: including the six core addons (core, cli, addon-a11y, addon-docs, addon-vitest, addon-onboarding) plus a single framework-specific dependency. The cra-default-ts sandbox correctly lists react-webpack5 as its framework-specific dependency, following the exact same pattern as other React-webpack sandboxes (react-webpack-17-ts, react-webpack-18-ts, etc.). The listed addons are all necessary and framework-relevant.


1-28: Based on my verification of the generation script and configuration:

All concerns in the review comment have been verified and resolved—no issues found.

The generation script (scripts/create-nx-sandbox-projects.ts) confirms:

  1. Executor definitions are intentional: Empty target objects {} inherit their executor configurations from nx.json targetDefaults. This is the intended design pattern, as shown in the nx.json output which defines executors for sandbox, prepare-sandbox, dev, build, etc.

  2. Dir values are correct: The script uses name.replaceAll('/', '-') to convert the template name (e.g., "cra/default-ts") into a stable folder name ("cra-default-ts"). The nx.json then references {options.dir} as a template variable in output paths.

  3. Generation script is reliable: The script iterates through allTemplates, dynamically generates project.json for each, and writes them with Prettier formatting. The file is deterministic and properly auto-generated.

  4. Implicit dependencies are correct: The script includes base dependencies (core, cli, addons) plus the framework (react-webpack5 for CRA). This matches other sandbox projects like cra-default-js and react-vite-default-ts.

  5. Consistency verified: Comparing cra-default-ts with cra-default-js and react-vite-default-ts confirms the file follows the correct pattern.

code/sandbox/html-vite-default-js/project.json (2)

15-15: Confirm dir option aligns with monorepo root refactoring.

Lines 15 and 18 add "dir": "html-vite-default-js" to the sandbox and build targets. This appears consistent with the PR's refactoring to move the monorepo root to the git root—tasks now need explicit directory specifications. Verify that the NX executors handling these targets correctly interpret this dir option relative to the new repository root.

Also applies to: 18-18


3-3: All implicit dependencies and targets are correctly generated and valid.

Verification confirms:

  1. Generation script exists (scripts/create-nx-sandbox-projects.ts) and is functional
  2. All implicit dependencies are valid packages existing in the codebase:
    • core (code/core/)
    • cli (code/lib/cli-storybook/)
    • addon-a11y (code/addons/a11y/)
    • addon-docs (code/addons/docs/)
    • addon-vitest (code/addons/vitest/)
    • addon-onboarding (code/addons/onboarding/)
    • html-vite (code/frameworks/html-vite/)
  3. All targets have corresponding NX executor definitions in nx.json targetDefaults
  4. Removal of addon-links is intentional—it is not included in the hardcoded implicit dependencies array in the generation script
  5. File output matches script logic exactly—conditional targets are correctly filtered based on template configuration

No issues found. The auto-generated file is correct and consistent with the generation script.

code/sandbox/solid-vite-default-ts/project.json (4)

3-3: Auto-generated configuration notice is appropriate.

The description field clearly marks this file as generated, which aids maintainability.


5-12: Based on my verification, I've found critical information that changes the nature of the review comment:

  1. The dependencies are auto-generated, not manually expanded. The file header states: "Do not edit. Auto generated by scripts/create-nx-sandbox-projects.ts."

  2. The dependency pattern is consistent across all Vite TypeScript sandboxes in the codebase. Every similar sandbox includes: core, cli, addon-a11y, addon-docs, addon-vitest, addon-onboarding (plus framework-specific entries).

  3. addon-links is not present in any of the Vite TS sandboxes, so it was never an implicit dependency in this project—the concern about it being "intentionally dropped" is based on a false premise.


No manual verification needed for auto-generated dependencies. The implicit dependencies list follows the standard pattern across all similar Vite TypeScript sandboxes and is auto-generated by create-nx-sandbox-projects.ts, not manually curated.

The dependencies (cli, addon-a11y, addon-docs, addon-vitest) are consistent with other Vite TypeScript sandboxes and are not subject to the verification concern raised. Note: addon-links does not appear in any Vite TypeScript sandbox, so concerns about it being dropped are unfounded.


14-22: Missing test and integration targets in solid-vite-default-ts compared to similar Vite TS sandboxes.

The review comment's concern is confirmed. The solid-vite-default-ts configuration is missing several targets present in comparable sandboxes:

Missing targets:

  • e2e-tests and e2e-tests-dev (present in react-vite-default-ts, vue3-vite-default-ts, and 33 other sandboxes)
  • vitest-integration (present in react-vite-default-ts, vue3-vite-default-ts)
  • check-sandbox (present in react-vite-default-ts)

Current targets in solid-vite-default-ts: sandbox, prepare-sandbox, dev, build, prepare-build-sandbox, chromatic, serve, test-runner, test-runner-dev (9 targets)

Current targets in react-vite-default-ts: Same 9 targets PLUS check-sandbox, e2e-tests, e2e-tests-dev, vitest-integration (13 targets total)

These are not renamed targets—they are genuinely absent from the solid-vite-default-ts configuration. Clarify whether the configuration should include these targets to maintain parity with other modern framework sandboxes or if solid-vite-default-ts intentionally has a reduced set of targets.

⛔ Skipped due to learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocking only a subset of required dependencies in Vitest tests
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursor/rules/spy-mocking.mdc:0-0
Timestamp: 2025-11-24T17:49:59.279Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Keep mock implementations simple and focused in Vitest tests
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

24-24: Tags are appropriate and consistent with the monorepo's CI categorization.

The ci:merged and ci:daily tags in solid-vite-default-ts/project.json correctly align with the sandbox categorization in code/lib/cli-storybook/src/sandbox-templates.ts:

  • solid-vite/default-ts is explicitly listed in the merged array (post-merge validation workflow)
  • It's implicitly included in the daily array via ...merged (comprehensive daily testing)
  • These tags match the CircleCI workflow definitions (merged.yml and daily.yml) that use them as pull request labels to trigger specific workflows

The tag combination is consistent with peer sandboxes of similar scope (e.g., react-webpack/17-ts, react-webpack/18-ts, nextjs-vite/15-ts, vue3-rsbuild/default-ts).

code/sandbox/lit-vite-default-ts/project.json (3)

3-3: File is correctly auto-generated. Verification confirms the generation script has been properly updated for the monorepo refactor.

The generation script (scripts/create-nx-sandbox-projects.ts) confirms:

  1. Description is correct: Line 18 of the script hardcodes the exact description appearing on line 3 of the project.json file.

  2. Consistency verified: Examined lit-vite-default-ts, lit-vite-default-js, and lit-rsbuild-default-ts project.json files—all follow the same pattern generated by the script. Each includes:

    • Base implicitDependencies array (core, cli, addon-a11y, addon-docs, addon-vitest, addon-onboarding)
    • Framework-specific dependency appended (e.g., "web-components-vite" for lit sandboxes)
    • Targets conditionally generated based on template.skipTasks
  3. Task-based target generation: The presence/absence of tasks like e2e-tests-dev versus e2e-tests is intentional—determined by the template configuration. This is not a discrepancy but expected behavior.

The script uses Prettier for formatting, ensuring consistent output across all generated files.


15-24: The review comment is based on incorrect assumptions about the target structure.

The verification reveals that the target configuration is intentionally generated and properly aligned with the monorepo's NX architecture:

  1. Target naming is intentional, not inconsistent: The generation script (scripts/create-nx-sandbox-projects.ts) conditionally includes targets based on each template's skipTasks configuration. The lit-vite-default-ts template deliberately omits the e2e-tests target while including e2e-tests-dev—this is not an error or inconsistency.

  2. Centralized targets are properly aligned: prepare-sandbox and prepare-build-sandbox are empty placeholder objects in sandbox project.json files because the actual target implementations are defined in the root NX configuration (nx.json). This is standard NX monorepo architecture where sandbox projects inherit target definitions from the workspace root.

  3. Empty targets vs. those with dir options are intentional:

    • sandbox and build targets include dir options specific to each sandbox
    • All other targets are empty because they inherit implementations from root-level targetDefaults
    • This pattern is consistent and correct across all 45+ sandbox configurations

5-13: Based on my comprehensive verification, I can now provide the rewritten review comment:


This is an auto-generated file controlled by scripts/create-nx-sandbox-projects.ts—manual edits will be overwritten.

The implicitDependencies list is not "significantly expanded" but rather reflects the standard dependencies applied uniformly to all sandboxes at generation time (lines 22–29 of the script). These are build/tooling dependencies used by Nx for task ordering and CI/CD, not runtime imports. The lit-vite/default-ts sandbox correctly includes web-components-vite as its framework dependency. To modify implicit dependencies, edit the generation script, not this file.

code/sandbox/internal-react18-webpack-babel/project.json (1)

1-27: Auto-generated project configuration looks good.

This file follows the PR's standardized pattern for sandbox project configurations. The expanded implicitDependencies and directory-scoped targets align with the monorepo refactoring.

Note: Verify that the target set is intentional for this sandbox. Some other sandboxes include e2e-tests and vitest-integration targets; this one has e2e-tests-dev but not e2e-tests. Confirm this aligns with the generation script's logic via code review of scripts/create-nx-sandbox-projects.ts.

code/sandbox/angular-cli-default-ts/project.json (1)

1-28: Auto-generated project configuration looks good.

Properly configured with expanded dependencies and comprehensive target set including both e2e-tests and e2e-tests-dev.

Note: Observe that this sandbox includes e2e-tests (line 22) while some others do not. Ensure the generation script's logic for determining which targets to include per sandbox type is properly validated.

code/sandbox/html-vite-default-ts/project.json (1)

1-27: Auto-generated configuration consistent with sandbox type.

HTML sandbox properly configured with Vite-specific dependencies and appropriate target set.

code/sandbox/react-vite-prerelease-ts/project.json (1)

1-28: New sandbox configuration properly structured.

New prerelease sandbox includes vitest-integration target, which is appropriate for Vite-based testing. Configuration follows the standardized pattern.

code/sandbox/vue3-vite-default-ts/project.json (1)

1-29: Well-structured configuration with comprehensive targets.

Vue3+Vite sandbox properly includes vitest-integration and both e2e-tests variants, reflecting the importance of this framework combination in the test matrix.

code/sandbox/svelte-vite-default-ts/project.json (1)

1-29: Configuration consistent with Vite ecosystem standards.

Svelte+Vite sandbox properly includes vitest integration and comprehensive e2e testing targets.

code/sandbox/bench-react-webpack-18-ts/project.json (1)

1-24: Benchmark sandbox appropriately configured.

The reduced target set (no test-runner, vitest-integration, or e2e-tests) is appropriate for a benchmark-focused sandbox that prioritizes build and serve capabilities.

code/sandbox/ember-3-js/project.json (1)

28-28: Based on my verification, I now have complete clarity on the issue. The empty tags for Ember is intentional and by design, not an oversight.

Rewritten Review Comment:

Empty tags array is intentional for Ember sandboxes marked as in-development.

Both Ember templates (ember/3-js and ember/default-js) are configured with inDevelopment: true in code/lib/cli-storybook/src/sandbox-templates.ts (lines 748, 759). The tag assignment logic in scripts/create-nx-sandbox-projects.ts (lines 94-98) explicitly filters out templates with this flag, resulting in empty tags []. This prevents CI scheduling for templates under active development. Although ember/default-js is listed in the normal CI schedule array (line 1001), the inDevelopment flag takes precedence and blocks CI execution—this is the intended mechanism to exclude experimental or unstable templates from pipelines.

code/sandbox/bench-react-webpack-18-ts-test-build/project.json (1)

3-21: Sandbox project config matches generator and template metadata

The description, implicitDependencies (incl. react-webpack5), dir-scoped sandbox/build targets, and CI tags all line up with the new generator logic and the template’s inclusion in normal, merged, and daily. Looks good.

code/sandbox/react-vite-default-js/project.json (1)

3-25: React Vite JS sandbox targets and deps look consistent

Dir-scoped targets, expanded implicitDependencies, and ["ci:daily"] tags align with the generator and the template’s membership in daily only. No issues from a config/Nx standpoint.

code/sandbox/react-vite-default-ts/project.json (1)

3-27: TS React Vite sandbox config matches the generator’s intent

Presence of check-sandbox, all test/runner targets, proper dir values, and full CI tag set are exactly what the new generator produces for a primary template like react-vite/default-ts. Looks correct.

code/sandbox/bench-react-vite-default-ts-nodocs/project.json (1)

3-21: Bench Vite TS nodocs sandbox config aligns with generator behavior

The dir-scoped sandbox/build targets, expanded implicitDependencies, and full CI tag set line up with the bench template’s presence in normal/merged/daily and its likely skipTasks settings. No changes needed.

code/sandbox/bench-react-vite-default-ts/project.json (1)

3-21: Bench Vite TS sandbox project.json is consistent and correct

Description, implicitDependencies (incl. react-vite), dir-scoped sandbox/build targets, and CI tags mirror the generator logic and template classification. Looks good.

code/sandbox/bench-react-vite-default-ts-test-build/project.json (1)

3-23: Bench Vite TS test‑build sandbox config matches the new generator

The dir value, implicitDependencies, limited target set, and full CI tags are in line with the template’s role as a build‑only benchmark sandbox. No issues spotted.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.circleci/config.yml (2)

1050-1072: Still missing Verdaccio step before prepare-sandbox in test-runner-production

This job now uses yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link, but unlike other sandbox jobs (bench-sandboxes, check-sandboxes, e2e-dev, e2e-production, chromatic-sandboxes), it doesn’t start Verdaccio beforehand.

Given that prepare-sandbox depends on the local registry (per the Nx targets) and the same pattern has been applied elsewhere, this job is likely to fail when it tries to resolve packages from the local registry.

You should add the same Verdaccio background step used in other sandbox jobs immediately before the prepare-sandbox run, for example:

      - run:
          background: true
          command: |
            cd code
            yarn local-registry --open
          name: Verdaccio
      - run:
          command: |
            TEMPLATE=$(yarn get-template --cadence << pipeline.parameters.workflow >> --task test-runner)
            yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link
          name: Install sandbox dependencies

1114-1144: Same Verdaccio gap for vitest-integration before prepare-sandbox

Analogous to test-runner-production, vitest-integration now calls:

TEMPLATE=$(yarn get-template --cadence << pipeline.parameters.workflow >> --task vitest-integration)
yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link

but does not start Verdaccio, unlike other sandbox jobs. If prepare-sandbox assumes a running local registry, this will break when it tries to install/publish packages to the local Verdaccio instance.

Consider inserting the standard Verdaccio background step immediately before the prepare-sandbox run, mirroring the pattern used in bench-sandboxes/e2e-*:

      - run:
          background: true
          command: |
            cd code
            yarn local-registry --open
          name: Verdaccio
      - run:
          command: |
            TEMPLATE=$(yarn get-template --cadence << pipeline.parameters.workflow >> --task vitest-integration)
            yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link
          name: Install sandbox dependencies
🧹 Nitpick comments (3)
.env (1)

1-3: Env defaults look consistent; newline/order nits are optional

The variables and values match the new sandbox behavior and CI usage (telemetry off, sandbox flag on, default ../storybook-sandboxes root). Functionally this is fine.

If you care about dotenv-linter noise, you can:

  • Reorder keys as it suggests, and
  • Add a trailing newline at EOF.

Both are purely cosmetic and can be deferred.

scripts/utils/constants.ts (1)

1-1: Sandbox directory resolution is correct; consider tightening imports and env handling

Logic-wise this does what you want:

  • Unset env ⇒ ${ROOT_DIRECTORY}/../storybook-sandboxes
  • Relative env ⇒ ${ROOT_DIRECTORY}/${relativeValue}
  • Absolute env ⇒ use as-is

Two small, optional cleanups:

  • Avoid mixing node:path and 'path' imports; either use node:path for both and destructure join, or drop node:path and rely on 'path' everywhere, depending on your Node/TS config.
  • Cache process.env.STORYBOOK_SANDBOX_ROOT in a local const to avoid repeating the lookup and to make the branching slightly easier to read.

Also applies to: 8-18, 21-22

.circleci/config.yml (1)

200-245: Build job now correctly targets repo-root Yarn and cache

Using {{ checksum "yarn.lock" }} for the cache key, running yarn from the repo root, and persisting both root and workspace node_modules is consistent with moving the Yarn monorepo root to ..

One follow-up outside this file: docs/contributor guides that still talk about cd code && yarn … should be updated to reflect the new root-level yarn usage. Based on learnings, existing guidance in .github/copilot-instructions.md still points contributors at code/ as the primary Yarn root.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e6a31c and 40cdf8b.

📒 Files selected for processing (4)
  • .circleci/config.yml (14 hunks)
  • .env (1 hunks)
  • .nx/workflows/agents.yaml (1 hunks)
  • scripts/utils/constants.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .nx/workflows/agents.yaml
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use camelCase for variable and function names

Files:

  • scripts/utils/constants.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Enable TypeScript strict mode
Export functions from modules for testing purposes

Files:

  • scripts/utils/constants.ts
**/*.{ts,tsx,js,jsx,json,html,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,json,html,mjs}: Use ESLint and Prettier for code style enforcement
Run 'yarn prettier --write ' to format code after making changes
Run 'yarn lint:js:cmd ' to check for ESLint issues after making changes

Files:

  • scripts/utils/constants.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • scripts/utils/constants.ts
  • .circleci/config.yml
  • .env
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'cd code && yarn storybook:ui' to start the development server for testing UI changes on http://localhost:6006/

Applied to files:

  • .circleci/config.yml
🪛 dotenv-linter (4.0.0)
.env

[warning] 2-2: [UnorderedKey] The IN_STORYBOOK_SANDBOX key should go before the STORYBOOK_DISABLE_TELEMETRY key

(UnorderedKey)


[warning] 3-3: [EndingBlankLine] No blank line at the end of the file

(EndingBlankLine)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (8)
.circleci/config.yml (8)

168-197: Bench sandboxes Verdaccio + shared prepare-sandbox look good

Starting Verdaccio in the background and then using the shared yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link aligns this job with the new sandbox flow and other Verdaccio-using jobs.


246-274: Check job changes are consistent with the new root-level Yarn workflow

Reusing the same root-level Yarn cache (yarn.lock) and invoking yarn + yarn task --task compile from the repo root matches the build job and the new monorepo root arrangement.


275-305: check-sandboxes now follows the Verdaccio + prepare-sandbox pattern

Adding the Verdaccio background step and switching to yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link makes this job consistent with the other sandbox-centric jobs and should avoid registry-related flakiness.


324-352: Confirm intentional use of STORYBOOK_SANDBOX_ROOT=./sandbox in chromatic-sandboxes

Resource bump to medium+, Verdaccio, and the move to prepare-sandbox all look good.

The one thing to double-check: this job explicitly overrides STORYBOOK_SANDBOX_ROOT=./sandbox, whereas the new default is ../storybook-sandboxes. If the intent is that CI chromatic flows still use the in-repo ./sandbox while other flows use the new default, it’d be good to add a brief comment here or in docs; otherwise you may want this job to rely on the shared default instead.


365-405: create-sandboxes: using yarn get-sandbox-dir for cleanup matches the new sandbox layout

Using $(yarn get-sandbox-dir --template $TEMPLATE) to locate each sandbox before rm -rf node_modules is a nice robustness upgrade now that sandboxes can live outside ./code. It keeps the cleanup in sync with the central sandbox path logic.


408-443: e2e-dev and e2e-production now correctly prep sandboxes via Verdaccio + prepare-sandbox

Both jobs now:

  • Start Verdaccio in the background from code/, and
  • Use yarn workspace @storybook/scripts prepare-sandbox --template $TEMPLATE --no-link.

This aligns them with other sandbox jobs and should make their sandbox resolution consistent with the new root-level tooling.


562-585: pretty-docs resource/cache/install tweaks are consistent with root Yarn

Bumping the executor class to medium+, keying the cache off the root yarn.lock, and running yarn install from the repo root before scripts’ Prettier check all match the monorepo-root change and should simplify cache behavior.


987-1021: test-portable-stories resource bump seems reasonable

Increasing the executor class to medium+ for this multi-run job (Jest, Vitest, Playwright CT, Cypress) is a pragmatic capacity improvement and doesn’t alter behavior.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
.circleci/config.yml (1)

1023-1027: [DUPLICATE] Add Verdaccio background service to test-runner-production and vitest-integration jobs.

Both jobs use prepare-sandbox (which depends on run-registry target) but lack the Verdaccio background service step that all other sandbox-related jobs have. Without Verdaccio running, prepare-sandbox will fail when attempting to access the local registry.

Add before the Install sandbox dependencies step in both jobs:

- run:
    background: true
    command: |
      cd code
      yarn local-registry --open
    name: Verdaccio

[scratchpad_end] -->

Also applies to: 1095-1099

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40cdf8b and b4b8b24.

📒 Files selected for processing (29)
  • .circleci/config.yml (40 hunks)
  • .circleci/src/jobs/bench-packages.yml (2 hunks)
  • .circleci/src/jobs/bench-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/build.yml (2 hunks)
  • .circleci/src/jobs/check-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/check.yml (1 hunks)
  • .circleci/src/jobs/chromatic-internal-storybook.yml (1 hunks)
  • .circleci/src/jobs/chromatic-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/coverage.yml (1 hunks)
  • .circleci/src/jobs/create-sandboxes.yml (2 hunks)
  • .circleci/src/jobs/e2e-dev.yml (2 hunks)
  • .circleci/src/jobs/e2e-production.yml (2 hunks)
  • .circleci/src/jobs/e2e-ui-vitest-3.yml (2 hunks)
  • .circleci/src/jobs/e2e-ui.yml (2 hunks)
  • .circleci/src/jobs/knip.yml (1 hunks)
  • .circleci/src/jobs/lint.yml (1 hunks)
  • .circleci/src/jobs/pretty-docs.yml (2 hunks)
  • .circleci/src/jobs/script-checks.yml (2 hunks)
  • .circleci/src/jobs/smoke-test-sandboxes.yml (1 hunks)
  • .circleci/src/jobs/stories-tests.yml (1 hunks)
  • .circleci/src/jobs/test-init-empty-windows.yml (2 hunks)
  • .circleci/src/jobs/test-init-empty.yml (1 hunks)
  • .circleci/src/jobs/test-init-features.yml (1 hunks)
  • .circleci/src/jobs/test-portable-stories.yml (2 hunks)
  • .circleci/src/jobs/test-runner-dev.yml (1 hunks)
  • .circleci/src/jobs/test-runner-production.yml (2 hunks)
  • .circleci/src/jobs/test-yarn-pnp.yml (1 hunks)
  • .circleci/src/jobs/unit-tests.yml (2 hunks)
  • .circleci/src/jobs/vitest-integration.yml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • .circleci/src/jobs/bench-sandboxes.yml
  • .circleci/src/jobs/test-runner-production.yml
  • .circleci/src/jobs/e2e-production.yml
  • .circleci/src/jobs/check-sandboxes.yml
  • .circleci/src/jobs/vitest-integration.yml
  • .circleci/src/jobs/chromatic-sandboxes.yml
  • .circleci/src/jobs/pretty-docs.yml
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • .circleci/src/jobs/stories-tests.yml
  • .circleci/src/jobs/script-checks.yml
  • .circleci/config.yml
  • .circleci/src/jobs/build.yml
  • .circleci/src/jobs/unit-tests.yml
  • .circleci/src/jobs/e2e-ui.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'cd code && yarn storybook:ui' to start the development server for testing UI changes on http://localhost:6006/

Applied to files:

  • .circleci/src/jobs/stories-tests.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • .circleci/src/jobs/smoke-test-sandboxes.yml
  • .circleci/src/jobs/create-sandboxes.yml
  • .circleci/src/jobs/e2e-dev.yml
  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • .circleci/src/jobs/e2e-ui-vitest-3.yml
  • .circleci/config.yml
  • .circleci/src/jobs/unit-tests.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • .circleci/src/jobs/check.yml
  • .circleci/config.yml
  • .circleci/src/jobs/build.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .yarnrc.yml : Use Yarn 4.9.1 as the package manager

Applied to files:

  • .circleci/src/jobs/check.yml
  • .circleci/config.yml
  • .circleci/src/jobs/build.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Run 'yarn task --task check' to verify TypeScript types across all packages before submitting PRs

Applied to files:

  • .circleci/src/jobs/check.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'yarn vitest run --coverage <test-file>' to run tests with coverage reports and aim for 75%+ coverage of statements/lines

Applied to files:

  • .circleci/src/jobs/script-checks.yml
  • .circleci/config.yml
  • .circleci/src/jobs/unit-tests.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to README.md : Update relevant README files for significant changes

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .nvmrc : Use Node.js 22.16.0 as specified in .nvmrc

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-10-02T09:22:13.215Z
Learnt from: JReinhold
Repo: storybookjs/storybook PR: 32607
File: code/package.json:243-243
Timestamp: 2025-10-02T09:22:13.215Z
Learning: The Storybook repository uses Yarn v^4 (any 4.x version) as the package manager, configured via .yarnrc.yml and package.json packageManager field. Specific patch versions within v4 can be upgraded as needed.

Applied to files:

  • .circleci/src/jobs/build.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Core Unit Tests, windows-latest
  • GitHub Check: nx
🔇 Additional comments (23)
.circleci/src/jobs/smoke-test-sandboxes.yml (1)

14-15: Verify test results output path after workspace relocation.

The workspace is now attached to /tmp, and store_test_results is configured to read from storybook/test-results. However, the path is relative to the working_directory. Ensure that the yarn task --task smoke-test command (with the --junit flag) writes results to the expected location at runtime. The change from test-results to storybook/test-results suggests a new output directory structure, but this needs verification to ensure CircleCI can locate and collect the test artifacts.

Also applies to: 22-22

.circleci/src/jobs/test-portable-stories.yml (2)

2-3: Executor resource class upgrade.

The executor class was upgraded from medium to medium+, aligning with the broader resource allocation adjustments in this PR refactor.


12-13: Workspace path update consistent with PR scope.

The workspace attachment point has been updated to /tmp, following the monorepo root refactoring pattern across all CircleCI jobs.

.circleci/src/jobs/script-checks.yml (2)

6-7: Workspace attachment location updated.

Workspace is now attached to /tmp instead of the current directory, consistent with the monorepo root refactoring.


20-24: Verify test result output path alignment with store_test_results.

The store_test_results path is relative to the working directory. The test runs from cd scripts context and likely outputs to scripts/junit.xml, but store_test_results is configured to look in storybook/scripts/junit.xml. Ensure the yarn test --coverage command is configured to output results to storybook/scripts/junit.xml or adjust the store_test_results path accordingly. This mismatch could cause test results to not be collected by CircleCI.

.circleci/src/jobs/test-init-empty-windows.yml (1)

11-12: Workspace relocation for Windows jobs.

The workspace attachment has been moved to /tmp, and subsequent cd code commands will correctly resolve relative to the new workspace root. This maintains compatibility with the monorepo refactoring.

.circleci/src/jobs/test-yarn-pnp.yml (1)

8-9: Workspace path updated consistently.

The workspace attachment point is now /tmp, aligning with the monorepo root refactoring across CircleCI jobs.

.circleci/src/jobs/chromatic-internal-storybook.yml (1)

11-12: Verify Chromatic output is in JUnit format for test result storage.

The job runs yarn storybook:ui:chromatic from the code/ directory, and store_test_results is configured to storybook/test-results. However, Chromatic primarily produces snapshot diff artifacts rather than JUnit test results. Verify that this step should use store_test_results (intended for JUnit XML test metadata) rather than store_artifacts (for general build artifacts). If Chromatic does generate JUnit output, confirm it writes to the storybook/test-results directory.

Also applies to: 16-16, 18-19

.circleci/src/jobs/lint.yml (1)

8-9: Workspace path updated for monorepo root refactoring.

The workspace attachment is now /tmp, consistent with the broader CircleCI configuration updates in this PR. The lint job correctly changes to the code/ directory from this new root.

.circleci/src/jobs/bench-packages.yml (1)

9-9: Verify artifact path and workspace layout consistency.

The attachment point moved to /tmp and the artifact path now includes storybook/ prefix. Ensure that benchmark scripts generate results at storybook/bench/packages/results.json relative to the workspace root. If bench scripts still output to bench/packages/results.json, the artifact store step will fail to find the file.

Also applies to: 59-59

.circleci/src/jobs/test-runner-dev.yml (1)

15-15: Verify test results output path alignment.

The test results store path is now storybook/test-results, but the test-runner-dev task is invoked with --junit flag. Ensure the test runner is configured to output JUnit results to storybook/test-results (or that the prefix is correctly applied by the task runner). Misalignment will cause the artifact store to fail silently, losing test results.

Also applies to: 22-22

.circleci/src/jobs/coverage.yml (1)

8-10: LGTM.

The workspace attachment change is consistent with the broader CI refactoring. Codecov upload should work as expected once the workspace is properly attached.

.circleci/src/jobs/test-init-empty.yml (1)

15-15: Verify directory navigation logic with /tmp workspace root.

The workspace is attached to /tmp, and subsequent cd code commands navigate to /tmp/code. However, the test steps then use cd .. (lines 35, 64, 94, 124) expecting to navigate to the parent directory. From /tmp/code, cd .. goes to /tmp, which is the workspace root—this appears correct. However, verify that:

  1. The /tmp/code directory exists after workspace attachment (i.e., the workspace includes the code/ subdirectory)
  2. The cd .. commands are expected to land in /tmp, not elsewhere
  3. Test artifacts are correctly created in /tmp/empty-* directories

Also applies to: 25-40

.circleci/src/jobs/check.yml (1)

11-19: Verify yarn cache key strategy after monorepo root refactor.

The Yarn cache key has been simplified from checking both code/yarn.lock and scripts/yarn.lock to checking only the root yarn.lock. This is a significant change. Verify:

  1. The root yarn.lock now includes all dependencies for the entire workspace (including code/ and scripts/ subdirectories)
  2. Any separate lockfiles in code/ and scripts/ are no longer used or have been migrated to the root lockfile
  3. The cache invalidation strategy is correct for the new monorepo structure

Additionally, the explicit yarn command (line 18) before yarn task --task compile may be redundant if the task runner already handles dependency installation. Clarify whether this is necessary or can be removed.

.circleci/src/jobs/test-init-features.yml (1)

8-10: Consistent with workspace refactoring pattern.

The workspace attachment to /tmp is consistent with other jobs. Verify that the cd code and subsequent cd .. navigation works correctly as described in test-init-empty.yml review comment.

.circleci/src/jobs/e2e-ui-vitest-3.yml (1)

9-9: Verify artifact paths for nested test-storybooks directory.

The artifact paths use storybook/test-storybooks/... prefix, which appears to be the new convention. Ensure that:

  1. The playwright-e2e task outputs test results to storybook/test-results (line 21, relative to workspace root)
  2. The portable-stories test directory outputs to storybook/test-storybooks/portable-stories-kitchen-sink/react-vitest-3/test-results/ (line 23)
  3. These paths exist after task execution, or the artifact store will silently fail

The double prefixing (e.g., storybook/test-storybooks/... in the artifact path) is consistent with the pattern but should be verified to match actual output locations.

Also applies to: 21-21, 23-23

.circleci/src/jobs/knip.yml (1)

8-10: LGTM.

The workspace attachment change is consistent with the broader refactoring. The cd code command should work correctly once the workspace structure at /tmp is verified (see verification requests in other files).

.circleci/src/jobs/e2e-ui.yml (1)

9-9: Verify artifact paths resolve correctly with workspace root at /tmp.

With attach_workspace at: /tmp, the artifact paths (storybook/test-results, storybook/test-storybooks/...) assume files are located at /tmp/storybook/. Ensure the build job's persist_to_workspace step correctly places these artifacts.

[scratchpad_end] -->

Also applies to: 21-21, 23-23

.circleci/src/jobs/create-sandboxes.yml (1)

34-34: Verify yarn get-sandbox-dir utility is available and works correctly.

Line 34 introduces a new utility command (yarn get-sandbox-dir --template $TEMPLATE) that resolves sandbox paths dynamically. This replaces the hardcoded sandbox/ prefix pattern. Ensure this command:

  1. Is properly exported/defined in the root yarn scripts
  2. Respects the SANDBOX_ROOT environment variable (defaults to ../storybook-sandboxes)
  3. Returns the correct path for the given template

[scratchpad_end] -->

Also applies to: 41-43

.circleci/src/jobs/e2e-dev.yml (1)

15-15: Verify e2e-dev does not require Verdaccio background service.

Unlike bench-sandboxes, check-sandboxes, chromatic-sandboxes, and e2e-production jobs, the e2e-dev job doesn't include a Verdaccio background service step. Confirm this is intentional and that e2e-dev tasks don't depend on a local npm registry.

[scratchpad_end] -->

Also applies to: 20-20

.circleci/src/jobs/build.yml (1)

11-11: Verify single yarn.lock is sufficient for cache invalidation.

The cache keys have been simplified from multi-file checksums (code/yarn.lock + scripts/yarn.lock) to a single root yarn.lock. This assumes all workspace dependencies are locked by the root yarn.lock file. Confirm that:

  1. Root yarn.lock includes entries for all code/ and scripts/ dependencies
  2. No separate lock files exist that could be modified without updating the root lock

[scratchpad_end] -->

Also applies to: 29-29

.circleci/config.yml (2)

320-334: Verify chromatic-sandboxes sandbox handling logic.

The chromatic-sandboxes job uses a unique pattern that differs from other sandbox jobs:

  • Line 324: Copies /tmp/storybook-sandboxes into /tmp/storybook/sandbox
  • Lines 326, 329: Overrides STORYBOOK_SANDBOX_ROOT=./sandbox to use the local copy

This differs from the standard pattern used by bench, check, e2e-dev, e2e-production jobs which directly use yarn get-sandbox-dir --template $TEMPLATE.

Clarify:

  1. Why does chromatic require this copy+override pattern?
  2. Is this intentional to isolate chromatic from the shared sandboxes?
  3. Should the override be STORYBOOK_SANDBOX_ROOT=./sandbox or ../sandbox?

[scratchpad_end] -->


202-202: Verify Yarn cache is warmed before compile tasks.

Cache restoration (line 202, 252) happens before compilation, but now explicit yarn invocations are added in compile steps (lines 206, 256). Confirm this is the intended behavior:

  • Is the explicit yarn meant to update the lock file if dependencies changed?
  • Or should it reinstall node_modules from cache?
  • This differs from the previous pattern and may cause cache redundancy.

[scratchpad_end] -->

Also applies to: 220-220, 252-252, 256-256

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
.circleci/config.yml (2)

1027-1032: Add missing Verdaccio background service to test-runner-production.

The job installs sandbox dependencies (line 1031) which triggers prepare-sandbox, a task that explicitly depends on run-registry per nx.json. However, unlike all other sandbox-preparation jobs (bench-sandboxes, check-sandboxes, chromatic-sandboxes, e2e-dev, e2e-production), this job lacks the Verdaccio background service, causing prepare-sandbox to fail when accessing the local registry.

         - attach_workspace:
             at: /tmp
+        - run:
+            background: true
+            command: |
+                cd code
+                yarn local-registry --open
+            name: Verdaccio
+        - run:
+            command: |
+                cd code
+                yarn wait-on tcp:127.0.0.1:6001
+                yarn wait-on tcp:127.0.0.1:6002
+            name: Wait on Verdaccio
         - run:
             command: |
                 sudo corepack enable

1100-1105: Add missing Verdaccio background service to vitest-integration.

The job installs sandbox dependencies (line 1104) which triggers prepare-sandbox, a task that explicitly depends on run-registry per nx.json. However, unlike all other sandbox-preparation jobs (bench-sandboxes, check-sandboxes, chromatic-sandboxes, e2e-dev, e2e-production), this job lacks the Verdaccio background service, causing prepare-sandbox to fail when accessing the local registry.

         - attach_workspace:
             at: /tmp
+        - run:
+            background: true
+            command: |
+                cd code
+                yarn local-registry --open
+            name: Verdaccio
+        - run:
+            command: |
+                cd code
+                yarn wait-on tcp:127.0.0.1:6001
+                yarn wait-on tcp:127.0.0.1:6002
+            name: Wait on Verdaccio
         - run:
             command: |
                 sudo corepack enable
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 729408e and c7244fa.

📒 Files selected for processing (2)
  • .circleci/config.yml (40 hunks)
  • scripts/tasks/build.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/tasks/build.ts
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Use 'yarn task --task sandbox --template <framework-template>' to generate sandbox test environments for different framework combinations

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Compile packages with 'yarn task --task compile' after making code changes before testing

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: The Storybook repository is a TypeScript/React monorepo with main codebase in 'code/' directory and tooling in 'scripts/' directory

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Use 'yarn vitest run --coverage <test-file>' to run tests with coverage reports and aim for 75%+ coverage of statements/lines

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to **/*.test.{ts,tsx} : Focus test coverage on all branches, conditions, edge cases, error paths, and different input variations

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:47.659Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T17:49:47.659Z
Learning: Applies to .nvmrc : Use Node.js 22.16.0 as specified in .nvmrc

Applied to files:

  • .circleci/config.yml
📚 Learning: 2025-11-24T17:49:31.838Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-24T17:49:31.838Z
Learning: Applies to code/vitest.workspace.ts : Vitest configuration is centralized in `code/vitest.workspace.ts` for workspace setup

Applied to files:

  • .circleci/config.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: nx
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (1)
.circleci/config.yml (1)

325-328: Verify the sandbox copy and STORYBOOK_SANDBOX_ROOT override logic.

The chromatic-sandboxes job copies /tmp/storybook-sandboxes to /tmp/storybook/sandbox (line 326) and then overrides STORYBOOK_SANDBOX_ROOT=./sandbox when calling get-sandbox-dir (line 328). Confirm this pattern is correct: does the copy operation actually create the expected directory structure, and why is the override necessary here when other jobs reference the default sandbox location?

@kasperpeulen kasperpeulen merged commit a381c7d into next Nov 28, 2025
68 checks passed
@kasperpeulen kasperpeulen deleted the kasper/yarn-monorepo-refactor branch November 28, 2025 14:49
@coderabbitai coderabbitai bot mentioned this pull request Nov 28, 2025
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Internal-facing build tooling & test updates ci:normal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants