Skip to content

CLIInitiate: Simplify the CLI init port flag detection#33546

Merged
ndelangen merged 8 commits into
nextfrom
norbert/improve-cli-init-port
Jan 15, 2026
Merged

CLIInitiate: Simplify the CLI init port flag detection#33546
ndelangen merged 8 commits into
nextfrom
norbert/improve-cli-init-port

Conversation

@ndelangen
Copy link
Copy Markdown
Member

@ndelangen ndelangen commented Jan 15, 2026

What I did

We discovered that the previous fix does functionally work, but it's still adding the -p-flag twice.

This is supported by commander (the underlaying library used for storybook CLI, so functionally we're okay.
This PR is meant to cleanup so the -p argument is replaced properly.

When using pnpm the command is shown to the user, and we want it to be displayed correctly.

This is wrong:
image (1)

In my canary testing is discovered that a sbFlag was added to angular empty init, which isn't supported, so I added a clear guard against this happening again in the future.

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

I'm releasing another canary on this PR, and testing with pnpm

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 pull request has been released as version 0.0.0-pr-33546-sha-66ad959a. Try it out in a new sandbox by running npx storybook@0.0.0-pr-33546-sha-66ad959a sandbox or in an existing project with npx storybook@0.0.0-pr-33546-sha-66ad959a upgrade.

More information
Published version 0.0.0-pr-33546-sha-66ad959a
Triggered by @ndelangen
Repository storybookjs/storybook
Branch norbert/improve-cli-init-port
Commit 66ad959a
Datetime Thu Jan 15 11:09:11 UTC 2026 (1768475351)
Workflow run 21029184749

To request a new release of this pull request, mention the @storybookjs/core team.

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

Summary by CodeRabbit

  • New Features

    • Storybook now picks an available port automatically when remapping is needed.
    • Onboarding mode adds an initial onboarding path when enabled.
  • Refactor

    • Internal command argument assembly and process invocation streamlined; no public APIs changed.
  • Bug Fixes

    • Reduced noisy output by adding a quiet mode when port remapping occurs.
  • Tests

    • Added a mock to stabilize server-port behavior in tests.

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

@ndelangen ndelangen self-assigned this Jan 15, 2026
@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Jan 15, 2026

View your CI Pipeline Execution ↗ for commit 629696c

Command Status Duration Result
nx run-many -t compile,check,knip,test,pretty-d... ✅ Succeeded 8m 23s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-15 12:09:35 UTC

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 15, 2026

📝 Walkthrough

Walkthrough

Replaces a separate flags array with a unified parts array derived from storybookCommand.split(' '); computes port via getServerPort and appends -p <port> when needed; conditionally injects --, --silent, --initial-path=/onboarding, and --quiet based on package runner and project type; spawns Storybook with stdio: 'inherit'.

Changes

Cohort / File(s) Summary
Dev command assembly
code/lib/create-storybook/src/initiate.ts
Replace flags with parts from storybookCommand.split(' '); move npm --silent into parts; gate flag injection via supportSbFlags (preserve Angular behavior); conditionally insert standalone -- when required; append -p <port> using getServerPort; add --initial-path=/onboarding and --quiet per conditions; build final args from parts and spawn with stdio: 'inherit'.
Test environment
code/lib/create-storybook/src/initiate.test.ts
Add mock for storybook/internal/core-server providing getServerPort resolved to 6006 to stabilize port-dependent behavior in tests.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as create-storybook CLI
  participant Initiate as initiate.ts
  participant Core as storybook/internal/core-server
  participant Spawn as child_process.spawn
  participant Storybook as Storybook Dev Server

  CLI->>Initiate: invoke start (storybookCommand, options)
  Initiate->>Core: getServerPort(default 6006)
  Core-->>Initiate: availablePort
  Initiate->>Initiate: parts = storybookCommand.split(' ')
  Initiate->>Initiate: conditionally insert `--`, `--silent`, `-p <port>`, `--initial-path=/onboarding`, `--quiet`
  Initiate->>Spawn: spawn(command=parts[0], args=parts[1..], stdio=inherit)
  Spawn->>Storybook: launch dev server on chosen port
  Storybook-->>CLI: runtime output (via inherited stdio)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
code/lib/create-storybook/src/initiate.ts (1)

216-217: Nit: Unnecessary spread operator.

The spread in [...parts] is redundant when destructuring. The simpler form achieves the same result:

-    const [command, ...args] = [...parts];
+    const [command, ...args] = parts;

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f953056 and 629696c.

📒 Files selected for processing (1)
  • code/lib/create-storybook/src/initiate.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx,json,md,html,css,scss}

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

Format code using Prettier with yarn prettier --write <file>

Files:

  • code/lib/create-storybook/src/initiate.ts
**/*.{js,jsx,json,html,ts,tsx,mjs}

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

Run ESLint checks using yarn lint:js:cmd <file> or the full command cross-env NODE_ENV=production eslint --cache --cache-location=../.cache/eslint --ext .js,.jsx,.json,.html,.ts,.tsx,.mjs --report-unused-disable-directives to fix linting errors before committing

Files:

  • code/lib/create-storybook/src/initiate.ts
**/*.{ts,tsx}

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

Enable TypeScript strict mode across all packages

Files:

  • code/lib/create-storybook/src/initiate.ts
**/*.{ts,tsx,js,jsx}

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

**/*.{ts,tsx,js,jsx}: Export functions from modules if they need to be tested
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/lib/create-storybook/src/initiate.ts
code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx}

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

Use logger from storybook/internal/node-logger for server-side logging in Node.js code

Files:

  • code/lib/create-storybook/src/initiate.ts
🧠 Learnings (4)
📚 Learning: 2025-12-22T22:03:40.123Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-22T22:03:40.123Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not use `console.log`, `console.warn`, or `console.error` directly unless in isolated files where importing loggers would significantly increase bundle size

Applied to files:

  • code/lib/create-storybook/src/initiate.ts
📚 Learning: 2025-12-22T22:03:40.123Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-22T22:03:40.123Z
Learning: Applies to code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx} : Use `logger` from `storybook/internal/node-logger` for server-side logging in Node.js code

Applied to files:

  • code/lib/create-storybook/src/initiate.ts
📚 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/lib/create-storybook/src/initiate.ts
📚 Learning: 2025-12-22T22:03:40.123Z
Learnt from: CR
Repo: storybookjs/storybook PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-22T22:03:40.123Z
Learning: Applies to code/{renderers}/**/*.{ts,tsx,js,jsx} : Use `logger` from `storybook/internal/client-logger` for client-side logging in browser code

Applied to files:

  • code/lib/create-storybook/src/initiate.ts
🧬 Code graph analysis (1)
code/lib/create-storybook/src/initiate.ts (2)
code/core/src/core-server/index.ts (1)
  • getServerPort (34-34)
code/lib/create-storybook/src/services/FeatureCompatibilityService.ts (1)
  • supportsOnboarding (29-33)
⏰ 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 (3)
code/lib/create-storybook/src/initiate.ts (3)

179-183: LGTM on parts array initialization and npm silent flag.

The --silent flag is correctly positioned for npm to suppress npm's output before the -- separator is added. This works correctly for all project types since it's an npm flag, not a storybook flag.


185-196: LGTM on Angular guard and argument separator logic.

The supportSbFlags guard correctly prevents Storybook-specific flags from being passed to Angular's ng run command. The -- separator is appropriately added for npm and bun to forward arguments to the underlying script.


198-211: Verify: Onboarding path is only added when port is remapped.

The --initial-path=/onboarding flag is nested inside if (useAlternativePort), meaning new users won't be directed to the onboarding page when the default port 6006 is available. This seems unintentional—shouldn't onboarding be shown to new users regardless of whether a port remap occurred?

If the intent is to only add --quiet when port remapping happens (to suppress the "port in use" message), consider restructuring:

♻️ Suggested refactor
       if (useAlternativePort) {
         parts.push(`-p`, `${availablePort}`);
+        parts.push('--quiet');
+      }

-        if (supportsOnboarding && shouldOnboard) {
-          parts.push('--initial-path=/onboarding');
-        }
-
-        parts.push('--quiet');
+      if (supportsOnboarding && shouldOnboard) {
+        parts.push('--initial-path=/onboarding');
       }

Please confirm whether the current behavior (onboarding path only on port remap) is intentional.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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

Copy link
Copy Markdown
Member

@yannbf yannbf left a comment

Choose a reason for hiding this comment

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

LGTM, as long as you test the canary and make sure things work as intended. Because the change made affects every single project and the storybookCommand logic, I'd advise to at least try on 3 different projects, one being Angular.

…e same argument twice)

Add a wrapper preventing adding any sbFLags when this is not supported (angular was broken)
…'t actually include the `-p` part, it just has `npm run storybook` in it, so the duplicate `-p` argument is unavoidable
Copy link
Copy Markdown
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

🤖 Fix all issues with AI agents
In `@code/lib/create-storybook/src/initiate.ts`:
- Around line 216-218: Remove the debug console.log call that prints args;
replace it with the project logger or remove entirely: remove the line
"console.log({ args })" inside the block where "const [command, ...args] =
[...parts]" is defined, and if logging is required use the storybook logger
(import logger from 'storybook/internal/node-logger') and call
logger.info/logger.debug with a clear message referencing command and args
(e.g., logger.debug({ command, args })); ensure you add the import if you use
logger.
- Around line 198-210: The port flag is being added as a single string token
(parts.push(`-p ${availablePort}`)) which will be passed as one argument to the
spawned process; change the logic that builds the parts array so the port flag
and its value are pushed as two separate arguments (e.g., push the flag token
and the port value separately) where availablePort is used, ensuring the spawned
CLI receives '-p' and the port number as distinct arguments; keep the existing
conditions around supportsOnboarding and shouldOnboard and leave other pushes
(like '--initial-path=/onboarding' and '--quiet') unchanged.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 817fbda and f953056.

📒 Files selected for processing (1)
  • code/lib/create-storybook/src/initiate.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx,json,md,html,css,scss}

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

Format code using Prettier with yarn prettier --write <file>

Files:

  • code/lib/create-storybook/src/initiate.ts
**/*.{js,jsx,json,html,ts,tsx,mjs}

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

Run ESLint checks using yarn lint:js:cmd <file> or the full command cross-env NODE_ENV=production eslint --cache --cache-location=../.cache/eslint --ext .js,.jsx,.json,.html,.ts,.tsx,.mjs --report-unused-disable-directives to fix linting errors before committing

Files:

  • code/lib/create-storybook/src/initiate.ts
**/*.{ts,tsx}

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

Enable TypeScript strict mode across all packages

Files:

  • code/lib/create-storybook/src/initiate.ts
**/*.{ts,tsx,js,jsx}

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

**/*.{ts,tsx,js,jsx}: Export functions from modules if they need to be tested
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/lib/create-storybook/src/initiate.ts
code/{core,lib,addons,builders,frameworks,presets}/**/*.{ts,tsx,js,jsx}

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

Use logger from storybook/internal/node-logger for server-side logging in Node.js code

Files:

  • code/lib/create-storybook/src/initiate.ts
🧬 Code graph analysis (1)
code/lib/create-storybook/src/initiate.ts (2)
code/core/src/core-server/index.ts (1)
  • getServerPort (34-34)
code/lib/create-storybook/src/services/FeatureCompatibilityService.ts (1)
  • supportsOnboarding (29-33)
⏰ 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 (1)
code/lib/create-storybook/src/initiate.ts (1)

179-183: LGTM!

The parts-based approach for building the command is cleaner than maintaining a separate flags array. The --silent flag is correctly pushed as a single argument.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread code/lib/create-storybook/src/initiate.ts
Comment thread code/lib/create-storybook/src/initiate.ts Outdated
@ndelangen
Copy link
Copy Markdown
Member Author

@yannbf unfortunately the double -p argument is unavoidable, as the first one is inside the user's package.json script.

I think we do not actually want to configure/initialize the project any differently based on if the port was taken.
I foresee that causing very unexpected behavior.

So I'd say considering the double -p argument isn't broken, and only shows up occasionally, and isn't harmful, just slighlty confusing, I suggest merging as-is.

I've tested angular, and actually found a bug, and fixed it (not related to the port flag)

@ndelangen ndelangen merged commit 30baaad into next Jan 15, 2026
68 checks passed
@ndelangen ndelangen deleted the norbert/improve-cli-init-port branch January 15, 2026 12:42
@coderabbitai coderabbitai Bot mentioned this pull request Jan 21, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants