From e68bf678f3aaae17045c713cad0a5231561c8cb2 Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Sat, 23 May 2026 17:59:00 +0800 Subject: [PATCH] Addon MCP: Make endpoint configurable --- .changeset/quiet-rivers-connect.md | 5 + README.md | 2 +- apps/internal-storybook/pnpm-lock.yaml | 144 ++++++------- eval/pnpm-lock.yaml | 98 ++++----- packages/addon-mcp/README.md | 20 ++ packages/addon-mcp/pnpm-lock.yaml | 44 ++-- .../src/auth/composition-auth.test.ts | 6 +- packages/addon-mcp/src/preset.test.ts | 196 ++++++++++++++++-- packages/addon-mcp/src/preset.ts | 42 ++-- packages/addon-mcp/src/types.test.ts | 30 +++ packages/addon-mcp/src/types.ts | 15 ++ packages/mcp/src/types.ts | 2 +- packages/mcp/src/utils/get-manifest.test.ts | 29 +++ packages/mcp/src/utils/get-manifest.ts | 10 +- pnpm-workspace.yaml | 26 +-- 15 files changed, 469 insertions(+), 200 deletions(-) create mode 100644 .changeset/quiet-rivers-connect.md create mode 100644 packages/addon-mcp/src/types.test.ts diff --git a/.changeset/quiet-rivers-connect.md b/.changeset/quiet-rivers-connect.md new file mode 100644 index 00000000..d99221e7 --- /dev/null +++ b/.changeset/quiet-rivers-connect.md @@ -0,0 +1,5 @@ +--- +"@storybook/addon-mcp": minor +--- + +Add an optional MCP endpoint setting for the addon dev server. diff --git a/README.md b/README.md index a4e858bb..120efa14 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ You can start Storybook with: pnpm storybook ``` -This will build everything and start up Storybook with addon-mcp, and you can then connect your coding agent to it at `http://localhost:6006/mcp` and try it out. +This will build everything and start up Storybook with addon-mcp, and you can then connect your coding agent to it at `http://localhost:6006/mcp` (or your configured addon endpoint) and try it out. ### Working with the MCP App diff --git a/apps/internal-storybook/pnpm-lock.yaml b/apps/internal-storybook/pnpm-lock.yaml index 3aae054b..e11dfbc6 100644 --- a/apps/internal-storybook/pnpm-lock.yaml +++ b/apps/internal-storybook/pnpm-lock.yaml @@ -7,20 +7,20 @@ settings: catalogs: default: '@storybook/addon-a11y': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@storybook/addon-docs': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@storybook/addon-themes': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@storybook/addon-vitest': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@storybook/react-vite': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@vitest/browser-playwright': specifier: 4.0.6 version: 4.0.6 @@ -28,8 +28,8 @@ catalogs: specifier: 1.56.1 version: 1.56.1 storybook: - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 vite: specifier: 7.2.2 version: 7.2.2 @@ -43,22 +43,22 @@ importers: devDependencies: '@storybook/addon-a11y': specifier: 'catalog:' - version: 10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@storybook/addon-docs': specifier: 'catalog:' - version: 10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) + version: 10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) '@storybook/addon-mcp': specifier: workspace:* version: link:../../packages/addon-mcp '@storybook/addon-themes': specifier: 'catalog:' - version: 10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@storybook/addon-vitest': specifier: 'catalog:' - version: 10.5.0-alpha.1(@vitest/browser-playwright@4.0.6)(@vitest/browser@4.0.6(vite@7.2.2)(vitest@4.0.6))(@vitest/runner@4.0.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.0.6) + version: 10.5.0-alpha.2(@vitest/browser-playwright@4.0.6)(@vitest/browser@4.0.6(vite@7.2.2)(vitest@4.0.6))(@vitest/runner@4.0.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.0.6) '@storybook/react-vite': specifier: 'catalog:' - version: 10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(vite@7.2.2) + version: 10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(vite@7.2.2) '@types/react': specifier: ^18.2.65 version: 18.3.28 @@ -82,7 +82,7 @@ importers: version: 18.3.1(react@18.3.1) storybook: specifier: 'catalog:' - version: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tinyexec: specifier: ^1.0.2 version: 1.0.2 @@ -937,32 +937,32 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@storybook/addon-a11y@10.5.0-alpha.1': - resolution: {integrity: sha512-PnjJgl0wlpH/w7P4hR1znz1exUrAt6A5DKmLRUtoMQ0cjOvckaFcyJs3SoSfQTe5qqseeTkhFoXbb523pSedog==} + '@storybook/addon-a11y@10.5.0-alpha.2': + resolution: {integrity: sha512-Nw4DwvekQrGJ01lARHTBg+jDWaRo1+nF1XNP60gtKAdvMdo4u8Rk4sOykT3RfyH3KPj5exq8G9d9S+/gWfWblw==} peerDependencies: - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 - '@storybook/addon-docs@10.5.0-alpha.1': - resolution: {integrity: sha512-FhWkTIHtjCg4joIVkshwQPiqYUTPvnqNkpG/3B75GffluzL5YX2Qu9cftpCDql86ImgI1ctKIoDXZWmT40lovA==} + '@storybook/addon-docs@10.5.0-alpha.2': + resolution: {integrity: sha512-Hd4c35sgLe3CjRtmCD1v/ZURuF8yrWoWVS+r9BcCuwwDPDySQInGHnfGrLOI5X1h0CiVdBJqjLPBbrzagtrkdQ==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 peerDependenciesMeta: '@types/react': optional: true - '@storybook/addon-themes@10.5.0-alpha.1': - resolution: {integrity: sha512-HYazKMCn9Qq9oS0H4+nVH4fCJdxjCS/gcuyLlI0e+ew+MR6BvM4rbC+V7fhl9hj2u9R86cJKz4nwGC0ASfywuQ==} + '@storybook/addon-themes@10.5.0-alpha.2': + resolution: {integrity: sha512-JoNpMnqbUwXLo2+U5JmMar7JQVv00G6v7Eu1M1D/CAo2EN4bKK3g4ovbCjdulXeQ21G8OpVGatai+OVt7SWvhw==} peerDependencies: - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 - '@storybook/addon-vitest@10.5.0-alpha.1': - resolution: {integrity: sha512-mbY8a6wcteNnR9p+09uBIxGklc4Qzf7gk0CsOoGUT5re4Q4V7N7lXXoM94MX5uYEZsyKsrOXfBc4FV/H/wb+sg==} + '@storybook/addon-vitest@10.5.0-alpha.2': + resolution: {integrity: sha512-agNzDQGXydQVmmAXLN6NkQ6XFo1ONLBLCgcBBoBpKfPZk27EiYxDJNfAilky5cPv/4+jZQL5veZtdkSdKSK2Ag==} peerDependencies: '@vitest/browser': ^3.0.0 || ^4.0.0 '@vitest/browser-playwright': ^4.0.0 '@vitest/runner': ^3.0.0 || ^4.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vitest: ^3.0.0 || ^4.0.0 peerDependenciesMeta: '@vitest/browser': @@ -974,18 +974,18 @@ packages: vitest: optional: true - '@storybook/builder-vite@10.5.0-alpha.1': - resolution: {integrity: sha512-3kK4MNFXVfoqXOFOsUViCrZEQId50d9QE17UxV1l9jQ+nB787AlAKafEBnpaWtmkLpY11g0GDOgwoFVE1N5m4A==} + '@storybook/builder-vite@10.5.0-alpha.2': + resolution: {integrity: sha512-yzjn/TcKNSOXvdn5S0A5RrkSCtsYa0Ath3aL0EVfgkWbPuwHwOD/u3h91CVWRpjGHAOctjhk6cX1nJJQwDx1kQ==} peerDependencies: - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@storybook/csf-plugin@10.5.0-alpha.1': - resolution: {integrity: sha512-W05MKCtFe8uqUruIK0qx250JTT8Xc/OdsvX7ayibdz1JwqDHCpuUw3dAqU9s3WRlhEqckhCSVD2LfMBkM27+OQ==} + '@storybook/csf-plugin@10.5.0-alpha.2': + resolution: {integrity: sha512-U2eLlrx3PrzwSbUSa8N1rScUqo+QD3T0yATfneWjiKfpQ5gL1O5dK2U/AbfqIdXzLEgco7NDz8iGx45CtFJlmA==} peerDependencies: esbuild: '*' rollup: '*' - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vite: '*' webpack: '*' peerDependenciesMeta: @@ -1007,36 +1007,36 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@storybook/react-dom-shim@10.5.0-alpha.1': - resolution: {integrity: sha512-pkaFTxlRXMs5gpszYn6qiJSFun2aVx5lZHgIFIMLKmCcO56LgQ5GGXDMwuQBCLb9ybblIxYZ3G/7hoVoTJn1PQ==} + '@storybook/react-dom-shim@10.5.0-alpha.2': + resolution: {integrity: sha512-sgi/5dpDKRKqWCizV1GAbpcz/EjeccHqIq1AlD4kVy+3mKVPMhwwSwvRiq0ihYig+2hhw/fQgHwjamjP2wFHUQ==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 peerDependenciesMeta: '@types/react': optional: true '@types/react-dom': optional: true - '@storybook/react-vite@10.5.0-alpha.1': - resolution: {integrity: sha512-8IvABs5m8j+sny2hkMkGXnaqSzAHJAX0OBVk5yhZkecGQj2wOgVXYgjkizWAL5DH73cM82pGUPblo2rfICP70w==} + '@storybook/react-vite@10.5.0-alpha.2': + resolution: {integrity: sha512-FYAuy/k6EQxgxFP7eL/t0phhQN/1ksHYE+lr7pGitdC+ZI/QVts2lS576AoLg/Bm58MoSxz3zjDpJ44q7oCQNg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@storybook/react@10.5.0-alpha.1': - resolution: {integrity: sha512-hXyawu9EraXjlpx0+52X97nIZXkoGpAn1xbsvTZ+pdg3Cjn1nbrSmRxqd89FY9lJgPdahxksZVopsZSlVJGz4A==} + '@storybook/react@10.5.0-alpha.2': + resolution: {integrity: sha512-ewlAlot/+cvylBaMFbtok1WMlZz4B3ZZ/ebIa9cG8e958pClqVWxvkyA+SZ8oYvJJTNwrcK0HMkaRCdS8RxOMg==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 typescript: '>= 4.9.x' peerDependenciesMeta: '@types/react': @@ -1585,8 +1585,8 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - storybook@10.5.0-alpha.1: - resolution: {integrity: sha512-5iTRa0fS1YLF14ZqiePabiCrLp6AnEvF1EiFLjhvXLWH7AUZTxd6BrUXAqD11Ql0R0gPGhST8GSrXknG6kvfEA==} + storybook@10.5.0-alpha.2: + resolution: {integrity: sha512-bxdnOntnglD9loavf1AGELgo36QvIpBFEkypHBHmEEausSZkdyxSHZ4QlC1CTv+5oeg8B7CEo9sGq6JGgIuZzw==} hasBin: true peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2331,21 +2331,21 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@storybook/addon-a11y@10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@storybook/addon-a11y@10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: '@storybook/global': 5.0.0 axe-core: 4.11.1 - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/addon-docs@10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2)': + '@storybook/addon-docs@10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2)': dependencies: '@mdx-js/react': 3.1.1(@types/react@18.3.28)(react@18.3.1) - '@storybook/csf-plugin': 10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) + '@storybook/csf-plugin': 10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) '@storybook/icons': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@storybook/react-dom-shim': 10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@storybook/react-dom-shim': 10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ts-dedent: 2.2.0 optionalDependencies: '@types/react': 18.3.28 @@ -2356,16 +2356,16 @@ snapshots: - vite - webpack - '@storybook/addon-themes@10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@storybook/addon-themes@10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ts-dedent: 2.2.0 - '@storybook/addon-vitest@10.5.0-alpha.1(@vitest/browser-playwright@4.0.6)(@vitest/browser@4.0.6(vite@7.2.2)(vitest@4.0.6))(@vitest/runner@4.0.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.0.6)': + '@storybook/addon-vitest@10.5.0-alpha.2(@vitest/browser-playwright@4.0.6)(@vitest/browser@4.0.6(vite@7.2.2)(vitest@4.0.6))(@vitest/runner@4.0.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vitest@4.0.6)': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: '@vitest/browser': 4.0.6(vite@7.2.2)(vitest@4.0.6) '@vitest/browser-playwright': 4.0.6(playwright@1.56.1)(vite@7.2.2)(vitest@4.0.6) @@ -2375,10 +2375,10 @@ snapshots: - react - react-dom - '@storybook/builder-vite@10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2)': + '@storybook/builder-vite@10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2)': dependencies: - '@storybook/csf-plugin': 10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@storybook/csf-plugin': 10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ts-dedent: 2.2.0 vite: 7.2.2 transitivePeerDependencies: @@ -2386,9 +2386,9 @@ snapshots: - rollup - webpack - '@storybook/csf-plugin@10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2)': + '@storybook/csf-plugin@10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2)': dependencies: - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.3 @@ -2402,28 +2402,28 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/react-dom-shim@10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@storybook/react-dom-shim@10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: '@types/react': 18.3.28 '@types/react-dom': 18.3.7(@types/react@18.3.28) - '@storybook/react-vite@10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(vite@7.2.2)': + '@storybook/react-vite@10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)(vite@7.2.2)': dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@5.9.3)(vite@7.2.2) '@rollup/pluginutils': 5.3.0(rollup@4.57.1) - '@storybook/builder-vite': 10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) - '@storybook/react': 10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3) + '@storybook/builder-vite': 10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(vite@7.2.2) + '@storybook/react': 10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3) empathic: 2.0.0 magic-string: 0.30.21 react: 18.3.1 react-docgen: 8.0.2 react-dom: 18.3.1(react@18.3.1) resolve: 1.22.11 - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tsconfig-paths: 4.2.0 vite: 7.2.2 transitivePeerDependencies: @@ -2435,15 +2435,15 @@ snapshots: - typescript - webpack - '@storybook/react@10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)': + '@storybook/react@10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(typescript@5.9.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.5.0-alpha.1(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@storybook/react-dom-shim': 10.5.0-alpha.2(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) react: 18.3.1 react-docgen: 8.0.2 react-docgen-typescript: 2.4.0(typescript@5.9.3) react-dom: 18.3.1(react@18.3.1) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: '@types/react': 18.3.28 '@types/react-dom': 18.3.7(@types/react@18.3.28) @@ -3087,7 +3087,7 @@ snapshots: std-env@3.10.0: {} - storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) diff --git a/eval/pnpm-lock.yaml b/eval/pnpm-lock.yaml index 910f1dff..a5c8af52 100644 --- a/eval/pnpm-lock.yaml +++ b/eval/pnpm-lock.yaml @@ -7,17 +7,17 @@ settings: catalogs: default: '@storybook/addon-a11y': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@storybook/react-vite': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 playwright: specifier: 1.56.1 version: 1.56.1 storybook: - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 valibot: specifier: 1.2.0 version: 1.2.0 @@ -49,13 +49,13 @@ importers: version: 1.1.11(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@storybook/addon-a11y': specifier: 'catalog:' - version: 10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + version: 10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/mcp': specifier: workspace:* version: link:../packages/mcp '@storybook/react-vite': specifier: 'catalog:' - version: 10.5.0-alpha.1(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.12)) + version: 10.5.0-alpha.2(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.12)) '@tsconfig/node-ts': specifier: ^23.6.1 version: 23.6.3 @@ -127,10 +127,10 @@ importers: version: 5.83.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) storybook: specifier: 'catalog:' - version: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) storybook-addon-test-codegen: specifier: ^3.0.0 - version: 3.0.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + version: 3.0.1(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) tinyexec: specifier: ^1.0.1 version: 1.0.2 @@ -1762,23 +1762,23 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - '@storybook/addon-a11y@10.5.0-alpha.1': - resolution: {integrity: sha512-PnjJgl0wlpH/w7P4hR1znz1exUrAt6A5DKmLRUtoMQ0cjOvckaFcyJs3SoSfQTe5qqseeTkhFoXbb523pSedog==} + '@storybook/addon-a11y@10.5.0-alpha.2': + resolution: {integrity: sha512-Nw4DwvekQrGJ01lARHTBg+jDWaRo1+nF1XNP60gtKAdvMdo4u8Rk4sOykT3RfyH3KPj5exq8G9d9S+/gWfWblw==} peerDependencies: - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 - '@storybook/builder-vite@10.5.0-alpha.1': - resolution: {integrity: sha512-3kK4MNFXVfoqXOFOsUViCrZEQId50d9QE17UxV1l9jQ+nB787AlAKafEBnpaWtmkLpY11g0GDOgwoFVE1N5m4A==} + '@storybook/builder-vite@10.5.0-alpha.2': + resolution: {integrity: sha512-yzjn/TcKNSOXvdn5S0A5RrkSCtsYa0Ath3aL0EVfgkWbPuwHwOD/u3h91CVWRpjGHAOctjhk6cX1nJJQwDx1kQ==} peerDependencies: - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@storybook/csf-plugin@10.5.0-alpha.1': - resolution: {integrity: sha512-W05MKCtFe8uqUruIK0qx250JTT8Xc/OdsvX7ayibdz1JwqDHCpuUw3dAqU9s3WRlhEqckhCSVD2LfMBkM27+OQ==} + '@storybook/csf-plugin@10.5.0-alpha.2': + resolution: {integrity: sha512-U2eLlrx3PrzwSbUSa8N1rScUqo+QD3T0yATfneWjiKfpQ5gL1O5dK2U/AbfqIdXzLEgco7NDz8iGx45CtFJlmA==} peerDependencies: esbuild: '*' rollup: '*' - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vite: '*' webpack: '*' peerDependenciesMeta: @@ -1800,36 +1800,36 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@storybook/react-dom-shim@10.5.0-alpha.1': - resolution: {integrity: sha512-pkaFTxlRXMs5gpszYn6qiJSFun2aVx5lZHgIFIMLKmCcO56LgQ5GGXDMwuQBCLb9ybblIxYZ3G/7hoVoTJn1PQ==} + '@storybook/react-dom-shim@10.5.0-alpha.2': + resolution: {integrity: sha512-sgi/5dpDKRKqWCizV1GAbpcz/EjeccHqIq1AlD4kVy+3mKVPMhwwSwvRiq0ihYig+2hhw/fQgHwjamjP2wFHUQ==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 peerDependenciesMeta: '@types/react': optional: true '@types/react-dom': optional: true - '@storybook/react-vite@10.5.0-alpha.1': - resolution: {integrity: sha512-8IvABs5m8j+sny2hkMkGXnaqSzAHJAX0OBVk5yhZkecGQj2wOgVXYgjkizWAL5DH73cM82pGUPblo2rfICP70w==} + '@storybook/react-vite@10.5.0-alpha.2': + resolution: {integrity: sha512-FYAuy/k6EQxgxFP7eL/t0phhQN/1ksHYE+lr7pGitdC+ZI/QVts2lS576AoLg/Bm58MoSxz3zjDpJ44q7oCQNg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - '@storybook/react@10.5.0-alpha.1': - resolution: {integrity: sha512-hXyawu9EraXjlpx0+52X97nIZXkoGpAn1xbsvTZ+pdg3Cjn1nbrSmRxqd89FY9lJgPdahxksZVopsZSlVJGz4A==} + '@storybook/react@10.5.0-alpha.2': + resolution: {integrity: sha512-ewlAlot/+cvylBaMFbtok1WMlZz4B3ZZ/ebIa9cG8e958pClqVWxvkyA+SZ8oYvJJTNwrcK0HMkaRCdS8RxOMg==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 '@types/react-dom': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 typescript: '>= 4.9.x' peerDependenciesMeta: '@types/react': @@ -3152,8 +3152,8 @@ packages: peerDependencies: storybook: ^0.0.0-0 || ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 - storybook@10.5.0-alpha.1: - resolution: {integrity: sha512-5iTRa0fS1YLF14ZqiePabiCrLp6AnEvF1EiFLjhvXLWH7AUZTxd6BrUXAqD11Ql0R0gPGhST8GSrXknG6kvfEA==} + storybook@10.5.0-alpha.2: + resolution: {integrity: sha512-bxdnOntnglD9loavf1AGELgo36QvIpBFEkypHBHmEEausSZkdyxSHZ4QlC1CTv+5oeg8B7CEo9sGq6JGgIuZzw==} hasBin: true peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -4748,16 +4748,16 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/addon-a11y@10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/addon-a11y@10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@storybook/global': 5.0.0 axe-core: 4.11.1 - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/builder-vite@10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12))': + '@storybook/builder-vite@10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12))': dependencies: - '@storybook/csf-plugin': 10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12)) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@storybook/csf-plugin': 10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12)) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ts-dedent: 2.2.0 vite: 7.3.1(@types/node@24.10.12) transitivePeerDependencies: @@ -4765,9 +4765,9 @@ snapshots: - rollup - webpack - '@storybook/csf-plugin@10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12))': + '@storybook/csf-plugin@10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12))': dependencies: - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.3 @@ -4781,27 +4781,27 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/react-dom-shim@10.5.0-alpha.1(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/react-dom-shim@10.5.0-alpha.2(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: '@types/react': 18.3.28 - '@storybook/react-vite@10.5.0-alpha.1(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.12))': + '@storybook/react-vite@10.5.0-alpha.2(@types/react@18.3.28)(esbuild@0.27.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.12))': dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.12)) '@rollup/pluginutils': 5.3.0(rollup@4.57.1) - '@storybook/builder-vite': 10.5.0-alpha.1(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12)) - '@storybook/react': 10.5.0-alpha.1(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) + '@storybook/builder-vite': 10.5.0-alpha.2(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vite@7.3.1(@types/node@24.10.12)) + '@storybook/react': 10.5.0-alpha.2(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3) empathic: 2.0.0 magic-string: 0.30.21 react: 19.2.4 react-docgen: 8.0.2 react-dom: 19.2.4(react@19.2.4) resolve: 1.22.11 - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) tsconfig-paths: 4.2.0 vite: 7.3.1(@types/node@24.10.12) transitivePeerDependencies: @@ -4813,15 +4813,15 @@ snapshots: - typescript - webpack - '@storybook/react@10.5.0-alpha.1(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': + '@storybook/react@10.5.0-alpha.2(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 10.5.0-alpha.1(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + '@storybook/react-dom-shim': 10.5.0-alpha.2(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) react: 19.2.4 react-docgen: 8.0.2 react-docgen-typescript: 2.4.0(typescript@5.9.3) react-dom: 19.2.4(react@19.2.4) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) optionalDependencies: '@types/react': 18.3.28 typescript: 5.9.3 @@ -6222,11 +6222,11 @@ snapshots: space-separated-tokens@2.0.2: {} - storybook-addon-test-codegen@3.0.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)): + storybook-addon-test-codegen@3.0.1(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)): dependencies: - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/react@18.3.28)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) diff --git a/packages/addon-mcp/README.md b/packages/addon-mcp/README.md index 0a00a12c..8f123cbf 100644 --- a/packages/addon-mcp/README.md +++ b/packages/addon-mcp/README.md @@ -8,4 +8,24 @@ Storybook addon for MCP-powered UI development workflows. See [documentation](https://storybook.js.org/docs/next/ai/mcp/overview/?ref=readme) for installation instructions, usage examples, APIs, and more. +## Configuration + +By default, the addon exposes its MCP server at `/mcp`. You can configure a +different literal endpoint path in `.storybook/main.ts`: + +```ts +export default { + addons: [ + { + name: '@storybook/addon-mcp', + options: { + endpoint: '/custom-mcp', + }, + }, + ], +}; +``` + +The endpoint must be a URL pathname such as `/custom-mcp` or `/tools/mcp`. + Learn more about Storybook at [storybook.js.org](https://storybook.js.org/?ref=readme). diff --git a/packages/addon-mcp/pnpm-lock.yaml b/packages/addon-mcp/pnpm-lock.yaml index a9a726c8..d2402df6 100644 --- a/packages/addon-mcp/pnpm-lock.yaml +++ b/packages/addon-mcp/pnpm-lock.yaml @@ -7,11 +7,11 @@ settings: catalogs: default: '@storybook/addon-a11y': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@storybook/addon-vitest': - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 '@tmcp/adapter-valibot': specifier: ^0.1.5 version: 0.1.5 @@ -19,8 +19,8 @@ catalogs: specifier: ^0.8.5 version: 0.8.5 storybook: - specifier: 10.5.0-alpha.1 - version: 10.5.0-alpha.1 + specifier: 10.5.0-alpha.2 + version: 10.5.0-alpha.2 tmcp: specifier: ^1.19.4 version: 1.19.4 @@ -53,13 +53,13 @@ importers: devDependencies: '@storybook/addon-a11y': specifier: 'catalog:' - version: 10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + version: 10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) '@storybook/addon-vitest': specifier: 'catalog:' - version: 10.5.0-alpha.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) + version: 10.5.0-alpha.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) storybook: specifier: 'catalog:' - version: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) packages: @@ -490,18 +490,18 @@ packages: '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@storybook/addon-a11y@10.5.0-alpha.1': - resolution: {integrity: sha512-PnjJgl0wlpH/w7P4hR1znz1exUrAt6A5DKmLRUtoMQ0cjOvckaFcyJs3SoSfQTe5qqseeTkhFoXbb523pSedog==} + '@storybook/addon-a11y@10.5.0-alpha.2': + resolution: {integrity: sha512-Nw4DwvekQrGJ01lARHTBg+jDWaRo1+nF1XNP60gtKAdvMdo4u8Rk4sOykT3RfyH3KPj5exq8G9d9S+/gWfWblw==} peerDependencies: - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 - '@storybook/addon-vitest@10.5.0-alpha.1': - resolution: {integrity: sha512-mbY8a6wcteNnR9p+09uBIxGklc4Qzf7gk0CsOoGUT5re4Q4V7N7lXXoM94MX5uYEZsyKsrOXfBc4FV/H/wb+sg==} + '@storybook/addon-vitest@10.5.0-alpha.2': + resolution: {integrity: sha512-agNzDQGXydQVmmAXLN6NkQ6XFo1ONLBLCgcBBoBpKfPZk27EiYxDJNfAilky5cPv/4+jZQL5veZtdkSdKSK2Ag==} peerDependencies: '@vitest/browser': ^3.0.0 || ^4.0.0 '@vitest/browser-playwright': ^4.0.0 '@vitest/runner': ^3.0.0 || ^4.0.0 - storybook: ^10.5.0-alpha.1 + storybook: ^10.5.0-alpha.2 vitest: ^3.0.0 || ^4.0.0 peerDependenciesMeta: '@vitest/browser': @@ -768,8 +768,8 @@ packages: sqids@0.3.0: resolution: {integrity: sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==} - storybook@10.5.0-alpha.1: - resolution: {integrity: sha512-5iTRa0fS1YLF14ZqiePabiCrLp6AnEvF1EiFLjhvXLWH7AUZTxd6BrUXAqD11Ql0R0gPGhST8GSrXknG6kvfEA==} + storybook@10.5.0-alpha.2: + resolution: {integrity: sha512-bxdnOntnglD9loavf1AGELgo36QvIpBFEkypHBHmEEausSZkdyxSHZ4QlC1CTv+5oeg8B7CEo9sGq6JGgIuZzw==} hasBin: true peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -1084,17 +1084,17 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@storybook/addon-a11y@10.5.0-alpha.1(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/addon-a11y@10.5.0-alpha.2(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@storybook/global': 5.0.0 axe-core: 4.11.1 - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/addon-vitest@10.5.0-alpha.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': + '@storybook/addon-vitest@10.5.0-alpha.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))': dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - storybook: 10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + storybook: 10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) transitivePeerDependencies: - react - react-dom @@ -1397,7 +1397,7 @@ snapshots: sqids@0.3.0: {} - storybook@10.5.0-alpha.1(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + storybook@10.5.0-alpha.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@storybook/global': 5.0.0 '@storybook/icons': 2.0.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) diff --git a/packages/addon-mcp/src/auth/composition-auth.test.ts b/packages/addon-mcp/src/auth/composition-auth.test.ts index 61f02c90..2de08b7e 100644 --- a/packages/addon-mcp/src/auth/composition-auth.test.ts +++ b/packages/addon-mcp/src/auth/composition-auth.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { CompositionAuth, extractBearerToken } from './composition-auth.ts'; describe('CompositionAuth', () => { @@ -6,6 +6,10 @@ describe('CompositionAuth', () => { vi.restoreAllMocks(); }); + afterEach(() => { + vi.unstubAllGlobals(); + }); + describe('extractBearerToken', () => { it('extracts token from valid Bearer header', () => { expect(extractBearerToken('Bearer abc123')).toBe('abc123'); diff --git a/packages/addon-mcp/src/preset.test.ts b/packages/addon-mcp/src/preset.test.ts index 2dba0538..5df48aff 100644 --- a/packages/addon-mcp/src/preset.test.ts +++ b/packages/addon-mcp/src/preset.test.ts @@ -1,6 +1,7 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import type { Options } from 'storybook/internal/types'; import { experimental_devServer } from './preset.ts'; +import * as mcpHandlerModule from './mcp-handler.ts'; import * as runStoryTests from './tools/run-story-tests.ts'; describe('experimental_devServer', () => { @@ -9,6 +10,8 @@ describe('experimental_devServer', () => { let mcpHandler: any; beforeEach(() => { + vi.restoreAllMocks(); + mockApp = { post: vi.fn((path, handler) => { mcpHandler = handler; @@ -28,6 +31,10 @@ describe('experimental_devServer', () => { } as unknown as Options; }); + afterEach(() => { + vi.unstubAllGlobals(); + }); + it('should register /mcp POST endpoint', async () => { await (experimental_devServer as any)(mockApp, mockOptions); @@ -41,6 +48,154 @@ describe('experimental_devServer', () => { expect(mockApp.get).toHaveBeenCalledWith('/mcp', expect.any(Function)); }); + it('should use a configured MCP endpoint for the dev server route', async () => { + const customOptions = { + ...mockOptions, + endpoint: '/custom-mcp', + } as unknown as Options; + + await (experimental_devServer as any)(mockApp, customOptions); + + expect(mockApp.post).toHaveBeenCalledWith('/custom-mcp', expect.any(Function)); + expect(mockApp.get).toHaveBeenCalledWith('/custom-mcp', expect.any(Function)); + }); + + it('should leave manifest fetching on the core default provider for the default endpoint', async () => { + const handlers: Record = {}; + mockApp.get = vi.fn((path: string, handler: any) => { + handlers[path] = handler; + }); + + const mcpServerHandler = vi + .spyOn(mcpHandlerModule, 'mcpServerHandler') + .mockResolvedValue(undefined); + + const options = { + ...mockOptions, + port: 6006, + } as unknown as Options; + + await (experimental_devServer as any)(mockApp, options); + await handlers['/mcp']( + { + headers: { accept: 'application/json' }, + }, + {}, + ); + + expect(mcpServerHandler).toHaveBeenCalledWith( + expect.objectContaining({ + manifestProvider: undefined, + sources: undefined, + }), + ); + }); + + it('should leave manifest fetching on the core default provider for a custom endpoint without refs', async () => { + const handlers: Record = {}; + mockApp.get = vi.fn((path: string, handler: any) => { + handlers[path] = handler; + }); + + const mcpServerHandler = vi + .spyOn(mcpHandlerModule, 'mcpServerHandler') + .mockResolvedValue(undefined); + + const customOptions = { + ...mockOptions, + port: 6006, + endpoint: '/custom-mcp', + } as unknown as Options; + + await (experimental_devServer as any)(mockApp, customOptions); + await handlers['/custom-mcp']( + { + headers: { accept: 'application/json' }, + }, + {}, + ); + + expect(mcpServerHandler).toHaveBeenCalledWith( + expect.objectContaining({ + addonOptions: expect.objectContaining({ + endpoint: '/custom-mcp', + }), + manifestProvider: undefined, + sources: undefined, + }), + ); + }); + + it('should use localhost manifests for the local source when refs are configured', async () => { + const handlers: Record = {}; + mockApp.get = vi.fn((path: string, handler: any) => { + handlers[path] = handler; + }); + + const mcpServerHandler = vi + .spyOn(mcpHandlerModule, 'mcpServerHandler') + .mockResolvedValue(undefined); + const fetchMock = vi.fn().mockResolvedValue({ + ok: true, + text: () => Promise.resolve('{"v":1,"components":{}}'), + }); + vi.stubGlobal('fetch', fetchMock); + + const optionsWithRefs = { + ...mockOptions, + port: 6006, + endpoint: '/custom-mcp', + presets: { + apply: vi.fn((key: string) => { + if (key === 'refs') { + return Promise.resolve({ + 'design-system': { + title: 'Design System', + url: 'https://ds.example.com/storybook', + }, + }); + } + if (key === 'features') { + return Promise.resolve({ componentsManifest: false }); + } + return Promise.resolve(undefined); + }), + }, + } as unknown as Options; + + await (experimental_devServer as any)(mockApp, optionsWithRefs); + await handlers['/custom-mcp']( + { + headers: { accept: 'application/json' }, + }, + {}, + ); + + const firstCall = mcpServerHandler.mock.calls[0]; + if (!firstCall) { + throw new Error('Expected mcpServerHandler to be called'); + } + const { manifestProvider } = firstCall[0]; + if (!manifestProvider) { + throw new Error('Expected refs to create a manifest provider'); + } + + await manifestProvider( + new Request('http://localhost:6006/custom-mcp?transport=sse'), + './manifests/components.json', + { id: 'local', title: 'Local' }, + ); + + expect(fetchMock).toHaveBeenLastCalledWith( + 'http://localhost:6006/manifests/components.json', + expect.objectContaining({ + headers: expect.objectContaining({ + Accept: 'application/json', + }), + }), + ); + }); + it('should serve HTML for browser GET requests', async () => { let getHandler: any; mockApp.get = vi.fn((path, handler) => { @@ -254,28 +409,37 @@ describe('experimental_devServer', () => { }); it('should parse refs from storybook config', async () => { + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue({ + ok: true, + status: 200, + headers: new Headers(), + text: () => Promise.resolve('{"v":1,"components":{}}'), + }), + ); + + const apply = vi.fn((key: string) => { + if (key === 'refs') { + return Promise.resolve({ + 'my-lib': { title: 'My Library', url: 'https://my-lib.example.com' }, + 'design-system': { url: 'https://ds.example.com' }, + }); + } + if (key === 'features') { + return Promise.resolve({ componentsManifest: false }); + } + return Promise.resolve(undefined); + }); const optionsWithRefs = { port: 6006, - presets: { - apply: vi.fn((key: string) => { - if (key === 'refs') { - return Promise.resolve({ - 'my-lib': { title: 'My Library', url: 'https://my-lib.example.com' }, - 'design-system': { url: 'https://ds.example.com' }, - }); - } - if (key === 'features') { - return Promise.resolve({ componentsManifest: false }); - } - return Promise.resolve(undefined); - }), - }, + presets: { apply }, } as unknown as Options; await (experimental_devServer as any)(mockApp, optionsWithRefs); // The preset should have called presets.apply('refs') - expect(optionsWithRefs.presets.apply).toHaveBeenCalledWith('refs', {}); + expect(apply).toHaveBeenCalledWith('refs', {}); }); it('should handle refs config returning non-object gracefully', async () => { diff --git a/packages/addon-mcp/src/preset.ts b/packages/addon-mcp/src/preset.ts index c30e13cb..45cad3a9 100644 --- a/packages/addon-mcp/src/preset.ts +++ b/packages/addon-mcp/src/preset.ts @@ -1,15 +1,23 @@ import { mcpServerHandler } from './mcp-handler.ts'; -import type { PresetPropertyFn } from 'storybook/internal/types'; -import { AddonOptions } from './types.ts'; +import type { PresetPropertyFn, StorybookConfigRaw } from 'storybook/internal/types'; +import { AddonOptions, type AddonOptionsInput } from './types.ts'; import * as v from 'valibot'; import { getManifestStatus } from './tools/is-manifest-available.ts'; import { getAddonVitestConstants } from './tools/run-story-tests.ts'; import { isAddonA11yEnabled } from './utils/is-addon-a11y-enabled.ts'; import htmlTemplate from './template.html'; import path from 'node:path'; -import { CompositionAuth, extractBearerToken, type ComposedRef } from './auth/index.ts'; +import { + CompositionAuth, + extractBearerToken, + type ComposedRef, + type ManifestProvider, +} from './auth/index.ts'; import { logger } from 'storybook/internal/node-logger'; import type { Source } from '@storybook/mcp'; +import type { IncomingMessage, ServerResponse } from 'node:http'; + +const DEFAULT_MCP_ENDPOINT = '/mcp'; export const previewAnnotations: PresetPropertyFn<'previewAnnotations'> = async ( existingAnnotations = [], @@ -17,27 +25,28 @@ export const previewAnnotations: PresetPropertyFn<'previewAnnotations'> = async return [...existingAnnotations, path.join(import.meta.dirname, 'preview.js')]; }; -export const experimental_devServer: PresetPropertyFn<'experimental_devServer'> = async ( - app, - options, -) => { +export const experimental_devServer: PresetPropertyFn< + 'experimental_devServer', + StorybookConfigRaw, + AddonOptionsInput +> = async (app, options) => { // There is no error handling here. This can make the whole storybook app crash with: // ValiError: Invalid type: Expected boolean but received "false" const addonOptions = v.parse(AddonOptions, { - toolsets: 'toolsets' in options ? options.toolsets : {}, + endpoint: options.endpoint, + toolsets: options.toolsets ?? {}, }); const origin = `http://localhost:${options.port}`; + const endpoint = addonOptions.endpoint ?? DEFAULT_MCP_ENDPOINT; // Get composed Storybook refs from config const refs = await getRefsFromConfig(options); const compositionAuth = new CompositionAuth(); - // Build sources and manifest provider only if refs are configured + // Build sources and manifest provider let sources: Source[] | undefined; - let manifestProvider: - | ((request: Request | undefined, path: string, source?: Source) => Promise) - | undefined; + let manifestProvider: ManifestProvider | undefined; if (refs.length > 0) { logger.info(`Initializing composition with ${refs.length} remote Storybook(s)`); @@ -67,10 +76,7 @@ export const experimental_devServer: PresetPropertyFn<'experimental_devServer'> res.end(JSON.stringify(wellKnown)); }); - const requireAuth = ( - req: import('node:http').IncomingMessage, - res: import('node:http').ServerResponse, - ): boolean => { + const requireAuth = (req: IncomingMessage, res: ServerResponse): boolean => { const token = extractBearerToken(req.headers['authorization']); if (compositionAuth.requiresAuth && !token) { res.writeHead(401, { @@ -83,7 +89,7 @@ export const experimental_devServer: PresetPropertyFn<'experimental_devServer'> return false; }; - app!.post('/mcp', (req, res) => { + app!.post(endpoint, (req, res) => { if (requireAuth(req, res)) return; return mcpServerHandler({ @@ -105,7 +111,7 @@ export const experimental_devServer: PresetPropertyFn<'experimental_devServer'> const isDocsEnabled = manifestStatus.available && (addonOptions.toolsets?.docs ?? true); const isTestEnabled = !!addonVitestConstants && (addonOptions.toolsets?.test ?? true); - app!.get('/mcp', (req, res) => { + app!.get(endpoint, (req, res) => { if (!req.headers['accept']?.includes('text/html')) { if (requireAuth(req, res)) return; diff --git a/packages/addon-mcp/src/types.test.ts b/packages/addon-mcp/src/types.test.ts new file mode 100644 index 00000000..a40482f4 --- /dev/null +++ b/packages/addon-mcp/src/types.test.ts @@ -0,0 +1,30 @@ +import * as v from 'valibot'; +import { describe, expect, it } from 'vitest'; +import { AddonOptions } from './types.ts'; + +describe('AddonOptions', () => { + it.each(['/custom-mcp', '/tools/mcp'])('accepts endpoint pathname %s', (endpoint) => { + expect(v.parse(AddonOptions, { endpoint })).toEqual({ + endpoint, + toolsets: { + dev: true, + docs: true, + test: true, + }, + }); + }); + + it.each([ + 'custom-mcp', + '//custom-mcp', + '/', + '/custom-mcp?query=1', + '/custom-mcp#hash', + '/custom mcp', + '/foo/../custom-mcp', + ])('rejects non-pathname endpoint %s', (endpoint) => { + expect(() => v.parse(AddonOptions, { endpoint })).toThrow( + 'Endpoint must be a literal URL pathname', + ); + }); +}); diff --git a/packages/addon-mcp/src/types.ts b/packages/addon-mcp/src/types.ts index d8083920..8a020643 100644 --- a/packages/addon-mcp/src/types.ts +++ b/packages/addon-mcp/src/types.ts @@ -3,7 +3,22 @@ import type { Options } from 'storybook/internal/types'; import { GET_TOOL_NAME, LIST_TOOL_NAME, type StorybookContext } from '@storybook/mcp'; import { GET_UI_BUILDING_INSTRUCTIONS_TOOL_NAME } from './tools/tool-names.ts'; +const isLiteralEndpointPathname = (endpoint: string) => { + try { + const { pathname } = new URL(endpoint, 'http://storybook.local'); + return pathname === endpoint && pathname !== '/'; + } catch { + return false; + } +}; + export const AddonOptions = v.object({ + endpoint: v.optional( + v.pipe( + v.string(), + v.check(isLiteralEndpointPathname, 'Endpoint must be a literal URL pathname'), + ), + ), toolsets: v.optional( v.object({ dev: v.exactOptional(v.boolean(), true), diff --git a/packages/mcp/src/types.ts b/packages/mcp/src/types.ts index 9adbbf05..f0c64c89 100644 --- a/packages/mcp/src/types.ts +++ b/packages/mcp/src/types.ts @@ -39,7 +39,7 @@ export type StorybookContext = { * The function receives the request object, a path to the manifest file, and optionally * a source (in multi-source mode). * The default provider requires a request object and constructs the manifest URL from the request origin, - * replacing /mcp with /manifests/components.json. + * using the top-level manifest path such as /manifests/components.json. * Custom providers can use the request parameter to determine the manifest source, or ignore it entirely. */ manifestProvider?: ( diff --git a/packages/mcp/src/utils/get-manifest.test.ts b/packages/mcp/src/utils/get-manifest.test.ts index bc865608..59fa58bc 100644 --- a/packages/mcp/src/utils/get-manifest.test.ts +++ b/packages/mcp/src/utils/get-manifest.test.ts @@ -270,6 +270,35 @@ Invalid key: Expected "v" but received undefined]`); expect(global.fetch).toHaveBeenCalledWith('https://example.com/manifests/docs.json'); }); + it.each([ + ['https://example.com/mcp', 'https://example.com'], + ['https://example.com/mcp/', 'https://example.com'], + ['https://example.com/tools/mcp?transport=sse', 'https://example.com'], + ['https://example.com/storybook/tools/mcp', 'https://example.com'], + ['http://localhost:6006/custom-mcp', 'http://localhost:6006'], + ])('should derive manifest URLs from the request origin for %s', async (requestUrl, origin) => { + const validManifest: ComponentManifestMap = { + v: 1, + components: { + button: { + id: 'button', + path: 'src/components/Button.tsx', + name: 'Button', + description: 'A button component', + }, + }, + }; + + global.fetch = createFetchMock({ components: validManifest }); + + const request = createMockRequest(requestUrl); + const result = await getManifests(request); + + expect(result).toEqual({ componentManifest: validManifest }); + expect(global.fetch).toHaveBeenCalledWith(`${origin}/manifests/components.json`); + expect(global.fetch).toHaveBeenCalledWith(`${origin}/manifests/docs.json`); + }); + it('should successfully fetch and parse both component and docs manifests', async () => { const validComponentManifest: ComponentManifestMap = { v: 1, diff --git a/packages/mcp/src/utils/get-manifest.ts b/packages/mcp/src/utils/get-manifest.ts index 6d764db8..1f94faed 100644 --- a/packages/mcp/src/utils/get-manifest.ts +++ b/packages/mcp/src/utils/get-manifest.ts @@ -162,20 +162,16 @@ export async function getManifests( } /** - * Constructs the manifest URL from a request by replacing /mcp with the provided path + * Constructs the manifest URL from the request origin and the top-level manifest path. */ function getManifestUrlFromRequest(request: Request, path: string): string { - const url = new URL(request.url); - // Replace /mcp endpoint with the provided path (e.g., './manifests/components.json') - // Remove leading './' from path if present const normalizedPath = path.replace(/^\.\//, ''); - url.pathname = url.pathname.replace(/\/mcp\/?$/, `/${normalizedPath}`); - return url.toString(); + return new URL(`/${normalizedPath}`, request.url).toString(); } /** * Default manifest provider that fetches from the same origin as the request, - * replacing /mcp with the provided path + * using Storybook's top-level manifest path. */ async function defaultManifestProvider( request: Request | undefined, diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 334d2977..13a8aed1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,18 +6,18 @@ packages: - '!eval/tasks/*/trials/*/project' catalog: - '@storybook/addon-a11y': 10.5.0-alpha.1 - '@storybook/addon-docs': 10.5.0-alpha.1 - '@storybook/addon-themes': 10.5.0-alpha.1 - '@storybook/addon-vitest': 10.5.0-alpha.1 - '@storybook/react-vite': 10.5.0-alpha.1 + '@storybook/addon-a11y': 10.5.0-alpha.2 + '@storybook/addon-docs': 10.5.0-alpha.2 + '@storybook/addon-themes': 10.5.0-alpha.2 + '@storybook/addon-vitest': 10.5.0-alpha.2 + '@storybook/react-vite': 10.5.0-alpha.2 '@tmcp/adapter-valibot': ^0.1.5 '@tmcp/transport-http': ^0.8.5 '@tmcp/transport-stdio': ^0.4.3 '@vitest/browser-playwright': 4.0.6 - eslint-plugin-storybook: 10.5.0-alpha.1 + eslint-plugin-storybook: 10.5.0-alpha.2 playwright: 1.56.1 - storybook: 10.5.0-alpha.1 + storybook: 10.5.0-alpha.2 tmcp: ^1.19.4 tsdown: ^0.15.12 typescript: ^5.9.3 @@ -28,10 +28,10 @@ catalog: catalogs: trials: '@eslint/js': 9.39.1 - '@storybook/addon-a11y': 10.5.0-alpha.1 - '@storybook/addon-docs': 10.5.0-alpha.1 - '@storybook/addon-vitest': 10.5.0-alpha.1 - '@storybook/react-vite': 10.5.0-alpha.1 + '@storybook/addon-a11y': 10.5.0-alpha.2 + '@storybook/addon-docs': 10.5.0-alpha.2 + '@storybook/addon-vitest': 10.5.0-alpha.2 + '@storybook/react-vite': 10.5.0-alpha.2 '@types/node': 24.10.1 '@types/react': 19.2.6 '@types/react-dom': 19.2.3 @@ -40,11 +40,11 @@ catalogs: eslint: 9.39.1 eslint-plugin-react-hooks: 7.0.1 eslint-plugin-react-refresh: 0.4.24 - eslint-plugin-storybook: 10.5.0-alpha.1 + eslint-plugin-storybook: 10.5.0-alpha.2 globals: 16.5.0 react: 19.2.0 react-dom: 19.2.0 - storybook: 10.5.0-alpha.1 + storybook: 10.5.0-alpha.2 typescript: 5.9.3 typescript-eslint: 8.47.0 vite: 7.2.2