Repository navigation
CLI: Match storybook ai instances by config dir as well as cwd - #35392
Conversation
Record the resolved configDir in the runtime instance record written by storybook dev, and let storybook ai resolve an instance when either its recorded cwd or its recorded config dir matches the CLI's target, so monorepo instances are found from a different cwd. When nothing matches, the no-instance guidance now lists the running instances with their recorded cwd/config dir and copyable retry invocations. Related to #35359
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR adds optional ChangesconfigDir-aware instance resolution
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
Comment |
Findings from a dual review (subagent + codex gpt-5.5 xhigh): - An explicit --config-dir now restricts matching to records with that exact configDir; previously a same-cwd instance serving a different config could silently win. The defaulted .storybook guess keeps the either-or union. - No-instance retry examples emit --config-dir (not --cwd) for records with a configDir, since a bare --cwd retry fails metadata loading when the config is not at <cwd>/.storybook; paths with whitespace are quoted. - The multi-instance warning no longer claims 'at this cwd' and lists each competing instance's cwd/config dir, since matches can span cwds.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
code/core/src/cli/ai/mcp/resolve-instance.ts (1)
68-98: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick wincode/core/src/cli/ai/mcp/resolve-instance.ts:81-87 — Handle case-insensitive
cwd/configDirmatching.resolve()preserves casing, so exact equality will miss the same directory when the path differs only by case on Windows/macOS. Canonicalize both sides before comparing.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@code/core/src/cli/ai/mcp/resolve-instance.ts` around lines 68 - 98, The current `resolveInstance` matching logic compares `cwd` and `configDir` with exact `resolve()` equality, which can miss the same directory when only path casing differs. Update the `matchesConfigDir` helper and the `projectMatches` filter in `resolveInstance` to compare canonicalized, case-insensitive paths for both `cwd` and `configDir`, so the same location is matched reliably on Windows/macOS.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@code/core/src/cli/ai/mcp/resolve-instance.ts`:
- Around line 68-98: The current `resolveInstance` matching logic compares `cwd`
and `configDir` with exact `resolve()` equality, which can miss the same
directory when only path casing differs. Update the `matchesConfigDir` helper
and the `projectMatches` filter in `resolveInstance` to compare canonicalized,
case-insensitive paths for both `cwd` and `configDir`, so the same location is
matched reliably on Windows/macOS.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5610cde1-e526-4fa3-a728-198f494cbf12
📒 Files selected for processing (6)
code/core/src/cli/ai/mcp/intercepts.test.tscode/core/src/cli/ai/mcp/intercepts.tscode/core/src/cli/ai/mcp/resolve-instance.test.tscode/core/src/cli/ai/mcp/resolve-instance.tscode/core/src/cli/ai/mcp/run-tool.test.tscode/core/src/cli/ai/mcp/run-tool.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- code/core/src/cli/ai/mcp/intercepts.test.ts
- code/core/src/cli/ai/mcp/run-tool.ts
- code/core/src/cli/ai/mcp/run-tool.test.ts
- code/core/src/cli/ai/mcp/intercepts.ts
- code/core/src/cli/ai/mcp/resolve-instance.test.ts
LogDetails |
Related to #35359 (makes
storybook aiinstance resolution robust in monorepos; the static--helpcommand listing from that issue is a separate change). Amends the exact-cwd matching introduced in #34826.What I did
storybook devwrites a runtime instance record to~/.storybook/instances/<instanceId>.json, andstorybook ailooked it up by exact cwd equality only. In a monorepo that breaks in both directions: a dev server started at the repo root with-c packages/ui/.storybookis invisible tostorybook airun frompackages/ui, and one started from the leaf is invisible from the root.Three changes:
Writer (
code/core/src/core-server/utils/runtime-instance-registry.ts, called frombuild-dev.ts): the record now includes the resolved absoluteconfigDirof the running Storybook.Reader (
code/core/src/cli/ai/mcp/): matching rule inresolveInstance:--config-dir, only instances whose recordedconfigDirequals the flag's resolved value match. The flag expresses precise intent — a same-cwd instance serving a different config must not win (previously the cwd fallback could silently route the command to the wrong Storybook, e.g. two package Storybooks both started from the repo root).configDirequals the defaulted<cwd>/.storybookor its recordedcwdequals the target cwd (previous behavior). This is what makes the plainstorybook ai <command>from a monorepo leaf find a root-started dev server.configDiris optional in the reader schema, so records written by older Storybooks still parse and keep matching by cwd (an explicit--config-dircan't select them; the failure guidance offers their--cwdinstead).Actionable no-instance guidance: when nothing matches but Storybooks are running, the intercept markdown lists each instance with its recorded cwd and config dir, plus one copyable retry invocation per instance built from the recorded values (quoted when paths contain whitespace), and states that
--cwd/--config-dirmust be placed before the command name (the program usesenablePositionalOptions/passThroughOptions, so tokens after the command name are command arguments). Records with aconfigDirget a--config-direxample — a bare--cwdretry would fail command-metadata loading whenever the config is not at<cwd>/.storybook:The multi-instance warning was also updated: matches can now span cwds, so each competing instance line carries its own cwd/config dir.
Review notes
The branch was reviewed by two independent automated reviewers (a Claude subagent with verified repros, and codex gpt-5.5 at xhigh reasoning). Their converging finding — explicit
--config-dirbeing overridden by cwd matches — plus the non-copyable--cwdretry example, the stale multi-instance warning wording, and unquoted paths were all fixed in the follow-up commit. Verified fine by review: valibot 1.4.0 strips unknown keys, so old CLIs parse new records (droppingconfigDir) and the new CLI parses old records; the pathe-writer/node:path-reader round-trip also matches on Windows.Note:
code/core/src/cli/ai/mcp/types.tscarries comments saying it is copied from@storybook/mcp-proxy(storybookjs/mcp). That proxy is slated for deletion, so no sync is needed; the stale "keep in sync" comments can be cleaned up when the proxy removal lands.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Suites updated next to each changed file:
resolve-instance.test.ts,registry.test.ts,intercepts.test.ts,run-tool.test.ts,runtime-instance-registry.test.ts(144 tests passing).Manual testing
packages/ui/.storybook), start the dev server from the repo root:npx storybook dev -c packages/ui/.storybookpackages/ui, runSTORYBOOK_FEATURE_AI_CLI=1 npx storybook ai get-changed-stories— the command should reach the running instance (previously: no-instance intercept).storybook devfrompackages/ui, then from the repo root runSTORYBOOK_FEATURE_AI_CLI=1 npx storybook ai --config-dir packages/ui/.storybook get-changed-stories— should also resolve.STORYBOOK_FEATURE_AI_CLI=1 npx storybook ai --config-dir packages/other/.storybook <command>targeting a package whose Storybook is NOT running — you should get the no-instance guidance (not a silent call to the wrong instance), listing the running instance with a copyable--config-dirretry.Documentation
storybook aiis behind the experimentalSTORYBOOK_FEATURE_AI_CLIflag; no public docs yet)Checklist for Maintainers
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsqa:neededorqa:skipSummary by CodeRabbit
New Features
storybook aicommands, including deduped examples and correct quoting; prefers--config-dirwhen available.Bug Fixes
cwd/config directory context.Documentation
--config-dirto reflect correct placement before the command name.