@storybook/cli 10.4.0-alpha.15 → 10.4.0-alpha.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/_node-chunks/{block-dependencies-versions-3JQG5RZL.js → block-dependencies-versions-2FTSXOV4.js} +11 -11
  2. package/dist/_node-chunks/{block-experimental-addon-test-DYNRVKQS.js → block-experimental-addon-test-MBAWHIVX.js} +9 -9
  3. package/dist/_node-chunks/{block-major-version-WUJ2IYKH.js → block-major-version-GLL4GDWB.js} +9 -9
  4. package/dist/_node-chunks/{block-node-version-ML6OV5FZ.js → block-node-version-RVJJJ4XR.js} +9 -9
  5. package/dist/_node-chunks/{block-webpack5-frameworks-IY3NOB6J.js → block-webpack5-frameworks-XEU7EO2R.js} +11 -11
  6. package/dist/_node-chunks/{chunk-522W525H.js → chunk-34WT6WHN.js} +6 -6
  7. package/dist/_node-chunks/{chunk-MNTUL4IJ.js → chunk-3FXXXDDK.js} +7 -7
  8. package/dist/_node-chunks/chunk-6HOHNSVJ.js +810 -0
  9. package/dist/_node-chunks/{chunk-TQZC6S4H.js → chunk-C2UHYVPK.js} +7 -7
  10. package/dist/_node-chunks/{chunk-KMODVRZU.js → chunk-CXC2V53L.js} +15 -15
  11. package/dist/_node-chunks/chunk-INX3KICK.js +20 -0
  12. package/dist/_node-chunks/chunk-JNFHA3R2.js +23 -0
  13. package/dist/_node-chunks/chunk-RXAW6T4J.js +527 -0
  14. package/dist/_node-chunks/chunk-SIZ5DHPZ.js +11 -0
  15. package/dist/_node-chunks/{globby-PFUJPJPH.js → globby-N46UCCVS.js} +8 -8
  16. package/dist/_node-chunks/monorepo-TVSJOSCW.js +111 -0
  17. package/dist/_node-chunks/optimized-tests-V6WOQ2XH.js +107 -0
  18. package/dist/_node-chunks/{p-limit-FVG52ILT.js → p-limit-BGPAPMNJ.js} +7 -7
  19. package/dist/_node-chunks/pattern-copy-play-6YIEGMCW.js +20 -0
  20. package/dist/_node-chunks/relaxed-limits-YQA6Y4DQ.js +107 -0
  21. package/dist/_node-chunks/{run-KUMQEGOH.js → run-IPZ5VOW3.js} +357 -1042
  22. package/dist/_node-chunks/{setup-VZ6IVNC4.js → setup-HAYJDL6K.js} +10 -10
  23. package/dist/bin/index.js +7 -7
  24. package/package.json +4 -4
  25. package/dist/_node-chunks/chunk-WSXOTENG.js +0 -11
@@ -1,14 +1,19 @@
1
- import CJS_COMPAT_NODE_URL_mvql93cv2wm from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_mvql93cv2wm from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_mvql93cv2wm from "node:module";
1
+ import CJS_COMPAT_NODE_URL_cy5uq3ou7e from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_cy5uq3ou7e from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_cy5uq3ou7e from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_mvql93cv2wm.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_mvql93cv2wm.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_mvql93cv2wm.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_cy5uq3ou7e.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_cy5uq3ou7e.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_cy5uq3ou7e.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
11
11
  // ------------------------------------------------------------
12
+ import {
13
+ instructions
14
+ } from "./chunk-6HOHNSVJ.js";
15
+ import "./chunk-JNFHA3R2.js";
16
+ import "./chunk-INX3KICK.js";
12
17
  import {
13
18
  bannerComment,
14
19
  containsDirnameUsage,
@@ -26,18 +31,18 @@ import {
26
31
  up,
27
32
  updateMainConfig,
28
33
  upgradeStorybookDependencies
29
- } from "./chunk-KMODVRZU.js";
34
+ } from "./chunk-CXC2V53L.js";
30
35
  import {
31
36
  slash
32
- } from "./chunk-TQZC6S4H.js";
37
+ } from "./chunk-C2UHYVPK.js";
33
38
  import {
34
39
  require_semver
35
- } from "./chunk-MNTUL4IJ.js";
40
+ } from "./chunk-3FXXXDDK.js";
36
41
  import {
37
42
  __commonJS,
38
43
  __require,
39
44
  __toESM
40
- } from "./chunk-522W525H.js";
45
+ } from "./chunk-34WT6WHN.js";
41
46
 
42
47
  // ../../../node_modules/envinfo/dist/envinfo.js
43
48
  var require_envinfo = __commonJS({
@@ -4418,9 +4423,9 @@ var require_isexe = __commonJS({
4418
4423
  if (typeof options == "function" && (cb = options, options = {}), !cb) {
4419
4424
  if (typeof Promise != "function")
4420
4425
  throw new TypeError("callback not provided");
4421
- return new Promise(function(resolve4, reject) {
4426
+ return new Promise(function(resolve5, reject) {
4422
4427
  isexe(path4, options || {}, function(er, is) {
4423
- er ? reject(er) : resolve4(is);
4428
+ er ? reject(er) : resolve5(is);
4424
4429
  });
4425
4430
  });
4426
4431
  }
@@ -4457,22 +4462,22 @@ var require_which = __commonJS({
4457
4462
  };
4458
4463
  }, which = (cmd, opt, cb) => {
4459
4464
  typeof opt == "function" && (cb = opt, opt = {}), opt || (opt = {});
4460
- let { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt), found = [], step = (i) => new Promise((resolve4, reject) => {
4465
+ let { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt), found = [], step = (i) => new Promise((resolve5, reject) => {
4461
4466
  if (i === pathEnv.length)
4462
- return opt.all && found.length ? resolve4(found) : reject(getNotFoundError(cmd));
4467
+ return opt.all && found.length ? resolve5(found) : reject(getNotFoundError(cmd));
4463
4468
  let ppRaw = pathEnv[i], pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw, pCmd = path4.join(pathPart, cmd), p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
4464
- resolve4(subStep(p, i, 0));
4465
- }), subStep = (p, i, ii) => new Promise((resolve4, reject) => {
4469
+ resolve5(subStep(p, i, 0));
4470
+ }), subStep = (p, i, ii) => new Promise((resolve5, reject) => {
4466
4471
  if (ii === pathExt.length)
4467
- return resolve4(step(i + 1));
4472
+ return resolve5(step(i + 1));
4468
4473
  let ext = pathExt[ii];
4469
4474
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
4470
4475
  if (!er && is)
4471
4476
  if (opt.all)
4472
4477
  found.push(p + ext);
4473
4478
  else
4474
- return resolve4(p + ext);
4475
- return resolve4(subStep(p, i, ii + 1));
4479
+ return resolve5(p + ext);
4480
+ return resolve5(subStep(p, i, ii + 1));
4476
4481
  });
4477
4482
  });
4478
4483
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -4719,7 +4724,7 @@ import {
4719
4724
  versions as versions5
4720
4725
  } from "storybook/internal/common";
4721
4726
  import { withTelemetry } from "storybook/internal/core-server";
4722
- import { CLI_COLORS as CLI_COLORS5, logTracker as logTracker4, logger as logger24 } from "storybook/internal/node-logger";
4727
+ import { CLI_COLORS as CLI_COLORS5, logTracker as logTracker4, logger as logger25 } from "storybook/internal/node-logger";
4723
4728
  import { addToGlobalContext, telemetry as telemetry3 } from "storybook/internal/telemetry";
4724
4729
  import { Option, program } from "commander";
4725
4730
 
@@ -4761,7 +4766,7 @@ function leven(first, second, options) {
4761
4766
  var import_picocolors17 = __toESM(require_picocolors(), 1);
4762
4767
 
4763
4768
  // package.json
4764
- var version = "10.4.0-alpha.15";
4769
+ var version = "10.4.0-alpha.17";
4765
4770
 
4766
4771
  // src/add.ts
4767
4772
  var import_semver = __toESM(require_semver(), 1);
@@ -5001,9 +5006,9 @@ var DIR_CWD = process.cwd(), require2 = createRequire2(DIR_CWD), postinstallAddo
5001
5006
  } catch {
5002
5007
  return;
5003
5008
  }
5004
- let postinstall = moduledLoaded?.default || moduledLoaded?.postinstall || moduledLoaded, logger25 = options.logger;
5009
+ let postinstall = moduledLoaded?.default || moduledLoaded?.postinstall || moduledLoaded, logger26 = options.logger;
5005
5010
  if (!postinstall || typeof postinstall != "function") {
5006
- logger25.error(`Error finding postinstall function for ${addonName}`);
5011
+ logger26.error(`Error finding postinstall function for ${addonName}`);
5007
5012
  return;
5008
5013
  }
5009
5014
  try {
@@ -5024,7 +5029,7 @@ async function add(addon, {
5024
5029
  configDir: userSpecifiedConfigDir,
5025
5030
  yes,
5026
5031
  skipInstall
5027
- }, logger25 = nodeLogger) {
5032
+ }, logger26 = nodeLogger) {
5028
5033
  let [addonName, inputVersion] = getVersionSpecifier(addon), { mainConfig, mainConfigPath, configDir, previewConfigPath, packageManager } = await getStorybookData({
5029
5034
  configDir: userSpecifiedConfigDir,
5030
5035
  packageManagerName: pkgMgr
@@ -5034,16 +5039,16 @@ async function add(addon, {
5034
5039
  Unable to find storybook config directory. Please specify your Storybook config directory with the --config-dir flag.
5035
5040
  `);
5036
5041
  if (!mainConfigPath) {
5037
- logger25.error("Unable to find Storybook main.js config");
5042
+ logger26.error("Unable to find Storybook main.js config");
5038
5043
  return;
5039
5044
  }
5040
5045
  let shouldAddToMain = !0;
5041
- if (checkInstalled(addonName, mainConfig) && (shouldAddToMain = !1, !yes && (logger25.log(`The Storybook addon "${addonName}" is already present in ${mainConfigPath}.`), !await prompt.confirm({
5046
+ if (checkInstalled(addonName, mainConfig) && (shouldAddToMain = !1, !yes && (logger26.log(`The Storybook addon "${addonName}" is already present in ${mainConfigPath}.`), !await prompt.confirm({
5042
5047
  message: "Do you wish to install it again?"
5043
5048
  }))))
5044
5049
  return;
5045
5050
  let main = await readConfig(mainConfigPath);
5046
- logger25.log(`Verifying ${addonName}`);
5051
+ logger26.log(`Verifying ${addonName}`);
5047
5052
  let version2 = inputVersion;
5048
5053
  if (!version2 && isCoreAddon(addonName) && (version2 = versions.storybook), !version2) {
5049
5054
  let latestVersion = await packageManager.latestVersion(addonName);
@@ -5052,14 +5057,14 @@ async function add(addon, {
5052
5057
  version2 = latestVersion;
5053
5058
  }
5054
5059
  let storybookVersion = versions.storybook, versionIsStorybook = version2 === versions.storybook;
5055
- isCoreAddon(addonName) && !versionIsStorybook && logger25.warn(
5060
+ isCoreAddon(addonName) && !versionIsStorybook && logger26.warn(
5056
5061
  `The version of ${addonName} (${version2}) you are installing is not the same as the version of Storybook you are using (${storybookVersion}). This may lead to unexpected behavior.`
5057
5062
  );
5058
5063
  let versionRange = packageManager.getDependencyVersion("storybook")?.match(/^[~^]/)?.[0] ?? "", addonWithVersion = versionIsStorybook ? `${addonName}@${versionRange}${storybookVersion}` : isValidVersion(version2) && !version2.includes("-pr-") ? `${addonName}@^${version2}` : `${addonName}@${version2}`;
5059
- logger25.log(`Installing ${addonWithVersion}`), await packageManager.addDependencies(
5064
+ logger26.log(`Installing ${addonWithVersion}`), await packageManager.addDependencies(
5060
5065
  { type: "devDependencies", writeOutputToFile: !1, skipInstall },
5061
5066
  [addonWithVersion]
5062
- ), shouldAddToMain && (logger25.log(`Adding '${addon}' to the "addons" field in ${mainConfigPath}`), await setupAddonInConfig({
5067
+ ), shouldAddToMain && (logger26.log(`Adding '${addon}' to the "addons" field in ${mainConfigPath}`), await setupAddonInConfig({
5063
5068
  addonName,
5064
5069
  mainConfigCSFFile: main,
5065
5070
  previewConfigPath,
@@ -5068,7 +5073,7 @@ async function add(addon, {
5068
5073
  packageManager: packageManager.type,
5069
5074
  configDir,
5070
5075
  yes,
5071
- logger: logger25,
5076
+ logger: logger26,
5072
5077
  prompt,
5073
5078
  skipInstall
5074
5079
  });
@@ -5080,7 +5085,7 @@ function isValidVersion(version2) {
5080
5085
  // src/automigrate/index.ts
5081
5086
  var import_picocolors14 = __toESM(require_picocolors(), 1);
5082
5087
  import { versions as versions3 } from "storybook/internal/common";
5083
- import { logTracker as logTracker2, logger as logger16, prompt as prompt3 } from "storybook/internal/node-logger";
5088
+ import { logTracker as logTracker2, logger as logger17, prompt as prompt3 } from "storybook/internal/node-logger";
5084
5089
  import { AutomigrateError } from "storybook/internal/server-errors";
5085
5090
 
5086
5091
  // ../../../node_modules/tiny-invariant/dist/esm/tiny-invariant.js
@@ -5625,7 +5630,7 @@ import { logger as logger3 } from "storybook/internal/node-logger";
5625
5630
  import { promises as fs } from "fs";
5626
5631
  var maxConcurrentTasks = Math.max(1, os.cpus().length - 1);
5627
5632
  async function runCodemod(globPattern = "**/*.{stories,story}.{js,jsx,ts,tsx,mjs,mjsx,mts,mtsx}", transform, { dryRun = !1, skipFormatting = !1 } = {}) {
5628
- let modifiedCount = 0, unmodifiedCount = 0, errorCount = 0, { globby } = await import("./globby-PFUJPJPH.js"), files = await globby(slash(globPattern), {
5633
+ let modifiedCount = 0, unmodifiedCount = 0, errorCount = 0, { globby } = await import("./globby-N46UCCVS.js"), files = await globby(slash(globPattern), {
5629
5634
  followSymbolicLinks: !0,
5630
5635
  ignore: ["**/node_modules/**", "**/dist/**", "**/storybook-static/**", "**/build/**"]
5631
5636
  });
@@ -5636,7 +5641,7 @@ Please try a different pattern.
5636
5641
  `
5637
5642
  ), new Error("No files matched");
5638
5643
  try {
5639
- let pLimit = (await import("./p-limit-FVG52ILT.js")).default, limit = pLimit(maxConcurrentTasks);
5644
+ let pLimit = (await import("./p-limit-BGPAPMNJ.js")).default, limit = pLimit(maxConcurrentTasks);
5640
5645
  await Promise.all(
5641
5646
  files.map(
5642
5647
  (file) => limit(async () => {
@@ -6479,7 +6484,7 @@ var addonA11yParameters = {
6479
6484
  errors.push({ file: previewFileToUpdate, error });
6480
6485
  }
6481
6486
  }
6482
- let { default: pLimit } = await import("./p-limit-FVG52ILT.js"), limit = pLimit(10);
6487
+ let { default: pLimit } = await import("./p-limit-BGPAPMNJ.js"), limit = pLimit(10);
6483
6488
  if (await Promise.all(
6484
6489
  storyFilesToUpdate.map(
6485
6490
  (file) => limit(async () => {
@@ -6633,7 +6638,7 @@ var addonGlobalsApi = {
6633
6638
  }
6634
6639
  };
6635
6640
  async function transformStoryFiles(files, options, dryRun) {
6636
- let errors = [], { default: pLimit } = await import("./p-limit-FVG52ILT.js"), limit = pLimit(10);
6641
+ let errors = [], { default: pLimit } = await import("./p-limit-BGPAPMNJ.js"), limit = pLimit(10);
6637
6642
  return await Promise.all(
6638
6643
  files.map(
6639
6644
  (file) => limit(async () => {
@@ -6825,7 +6830,7 @@ function transformPackageJson(content) {
6825
6830
  return hasChanges ? JSON.stringify(packageJson, null, 2) : null;
6826
6831
  }
6827
6832
  var transformPackageJsonFiles = async (files, dryRun) => {
6828
- let errors = [], { default: pLimit } = await import("./p-limit-FVG52ILT.js"), limit = pLimit(10);
6833
+ let errors = [], { default: pLimit } = await import("./p-limit-BGPAPMNJ.js"), limit = pLimit(10);
6829
6834
  return await Promise.all(
6830
6835
  files.map(
6831
6836
  (file) => limit(async () => {
@@ -6864,7 +6869,7 @@ var transformPackageJsonFiles = async (files, dryRun) => {
6864
6869
  dryRun
6865
6870
  );
6866
6871
  errors.push(...packageJsonErrors);
6867
- let { globby } = await import("./globby-PFUJPJPH.js"), configFiles = await globby([`${configDir}/**/*`]), importErrors = await transformImportFiles(
6872
+ let { globby } = await import("./globby-N46UCCVS.js"), configFiles = await globby([`${configDir}/**/*`]), importErrors = await transformImportFiles(
6868
6873
  [...storiesPaths, ...configFiles].filter(Boolean),
6869
6874
  {
6870
6875
  ...consolidatedPackages,
@@ -7220,7 +7225,7 @@ var VITE_DEFAULT_VERSION = "^7.0.0", transformMainConfig = async (mainConfigPath
7220
7225
  ]);
7221
7226
  }
7222
7227
  mainConfigPath && (logger11.debug("Updating main config file..."), await transformMainConfig(mainConfigPath, dryRun)), logger11.debug("Scanning and updating import statements...");
7223
- let { globby } = await import("./globby-PFUJPJPH.js"), configFiles = await globby([`${configDir}/**/*`]), allFiles = [...storiesPaths, ...configFiles].filter(Boolean), transformErrors = await transformImportFiles2(
7228
+ let { globby } = await import("./globby-N46UCCVS.js"), configFiles = await globby([`${configDir}/**/*`]), allFiles = [...storiesPaths, ...configFiles].filter(Boolean), transformErrors = await transformImportFiles2(
7224
7229
  allFiles,
7225
7230
  {
7226
7231
  "@storybook/nextjs": "@storybook/nextjs-vite"
@@ -7430,7 +7435,7 @@ var getAllDependencies = (packageJson) => Object.keys({
7430
7435
  let regex = new RegExp(`(['"])${renderer}(['"])`, "g");
7431
7436
  return regex.test(source) ? source.replace(regex, `$1${framework}$2`) : null;
7432
7437
  }, transformSourceFiles = async (files, renderer, framework, dryRun) => {
7433
- let errors = [], { default: pLimit } = await import("./p-limit-FVG52ILT.js"), limit = pLimit(10);
7438
+ let errors = [], { default: pLimit } = await import("./p-limit-BGPAPMNJ.js"), limit = pLimit(10);
7434
7439
  return await Promise.all(
7435
7440
  files.map(
7436
7441
  (file) => limit(async () => {
@@ -7497,7 +7502,7 @@ var getAllDependencies = (packageJson) => Object.keys({
7497
7502
  continue;
7498
7503
  logger13.debug(`
7499
7504
  Migrating ${rendererPackage} to ${selectedFramework}`);
7500
- let { globby } = await import("./globby-PFUJPJPH.js"), configFiles = await globby([`${configDir}/**/*`]);
7505
+ let { globby } = await import("./globby-N46UCCVS.js"), configFiles = await globby([`${configDir}/**/*`]);
7501
7506
  await transformSourceFiles(
7502
7507
  [...storiesPaths, ...configFiles].filter(Boolean),
7503
7508
  rendererPackage,
@@ -7512,16 +7517,87 @@ Migrating ${rendererPackage} to ${selectedFramework}`);
7512
7517
  }
7513
7518
  };
7514
7519
 
7515
- // src/automigrate/fixes/rnstorybook-config.ts
7520
+ // src/automigrate/fixes/rn-ondevice-addons-to-device-addons.ts
7516
7521
  import { existsSync as existsSync2 } from "node:fs";
7517
- import { readFile as readFile8, rename, writeFile as writeFile7 } from "node:fs/promises";
7518
- import { join as join2 } from "node:path";
7519
- import { dedent as dedent9 } from "ts-dedent";
7522
+ import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute2, join as join2, resolve as resolve2 } from "node:path";
7523
+ import { findConfigFile, loadMainConfig } from "storybook/internal/common";
7524
+ import { logger as logger14 } from "storybook/internal/node-logger";
7520
7525
 
7521
7526
  // ../../core/src/shared/constants/config-folder.ts
7522
7527
  var RN_STORYBOOK_DIR = ".rnstorybook";
7523
7528
 
7529
+ // src/automigrate/fixes/rn-ondevice-addons-to-device-addons.ts
7530
+ var resolveAbsoluteConfigDir = (configDir) => isAbsolute2(configDir) ? configDir : join2(process.cwd(), configDir), getSiblingStorybookConfigDir = (configDirAbs) => {
7531
+ let base = basename2(configDirAbs), parent = dirname2(configDirAbs);
7532
+ if (base === ".storybook") {
7533
+ let rn = join2(parent, RN_STORYBOOK_DIR);
7534
+ return existsSync2(rn) ? rn : null;
7535
+ }
7536
+ if (base === RN_STORYBOOK_DIR) {
7537
+ let web = join2(parent, ".storybook");
7538
+ return existsSync2(web) ? web : null;
7539
+ }
7540
+ return null;
7541
+ }, isReactNativeMain = (mainConfigPath, mainConfig) => basename2(dirname2(mainConfigPath)) === RN_STORYBOOK_DIR ? !0 : getFrameworkPackageName(mainConfig) === "@storybook/react-native", hasAddonsToRename = (cfg) => {
7542
+ let addons = cfg.addons;
7543
+ return !(!Array.isArray(addons) || addons.length === 0 || cfg.deviceAddons !== void 0);
7544
+ }, rnOndeviceAddonsToDeviceAddons = {
7545
+ id: "rn-ondevice-addons-to-device-addons",
7546
+ link: "https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#react-native-on-device-addons-moved-to-deviceaddons",
7547
+ async check({ mainConfig, packageManager, configDir, mainConfigPath }) {
7548
+ if (!packageManager.getAllDependencies()["@storybook/react-native"])
7549
+ return null;
7550
+ let candidateDirs = [];
7551
+ if (configDir) {
7552
+ let absConfigDir = resolveAbsoluteConfigDir(configDir);
7553
+ candidateDirs.push(absConfigDir);
7554
+ let siblingConfigDir = getSiblingStorybookConfigDir(absConfigDir);
7555
+ siblingConfigDir && candidateDirs.push(siblingConfigDir);
7556
+ }
7557
+ let targets = [], seenResolvedMainPaths = /* @__PURE__ */ new Set();
7558
+ if (candidateDirs.length > 0)
7559
+ for (let dir of candidateDirs) {
7560
+ let mainPath = findConfigFile("main", dir);
7561
+ if (!mainPath)
7562
+ continue;
7563
+ let resolvedMain = resolve2(mainPath);
7564
+ if (seenResolvedMainPaths.has(resolvedMain))
7565
+ continue;
7566
+ seenResolvedMainPaths.add(resolvedMain);
7567
+ let cfg;
7568
+ if (mainConfigPath && resolve2(mainConfigPath) === resolvedMain)
7569
+ cfg = mainConfig;
7570
+ else
7571
+ try {
7572
+ cfg = await loadMainConfig({ configDir: dir });
7573
+ } catch (e) {
7574
+ logger14.debug(
7575
+ `Failed to load Storybook main config at ${dir}: ${e instanceof Error ? e.message : String(e)}`
7576
+ );
7577
+ continue;
7578
+ }
7579
+ isReactNativeMain(mainPath, cfg) && hasAddonsToRename(cfg) && targets.push({ mainConfigPath: mainPath });
7580
+ }
7581
+ else mainConfigPath && isReactNativeMain(mainConfigPath, mainConfig) && hasAddonsToRename(mainConfig) && targets.push({ mainConfigPath });
7582
+ return targets.length === 0 ? null : { targets };
7583
+ },
7584
+ prompt() {
7585
+ return "Renaming `addons` to `deviceAddons` in your React Native Storybook config (on-device addons must not be evaluated as Node.js presets).";
7586
+ },
7587
+ async run({ result, dryRun }) {
7588
+ for (let { mainConfigPath } of result.targets)
7589
+ await updateMainConfig({ mainConfigPath, dryRun: !!dryRun }, (main) => {
7590
+ let node = main.getFieldNode(["addons"]);
7591
+ node && (main.setFieldNode(["deviceAddons"], node), main.removeField(["addons"]));
7592
+ });
7593
+ }
7594
+ };
7595
+
7524
7596
  // src/automigrate/fixes/rnstorybook-config.ts
7597
+ import { existsSync as existsSync3 } from "node:fs";
7598
+ import { readFile as readFile8, rename, writeFile as writeFile7 } from "node:fs/promises";
7599
+ import { join as join3 } from "node:path";
7600
+ import { dedent as dedent9 } from "ts-dedent";
7525
7601
  async function renameInFile(filePath, oldText, newText) {
7526
7602
  try {
7527
7603
  let updatedContent = (await readFile8(filePath, "utf8")).replaceAll(oldText, newText);
@@ -7532,7 +7608,7 @@ async function renameInFile(filePath, oldText, newText) {
7532
7608
  }
7533
7609
  var getDotStorybookReferences = async (searchDir) => {
7534
7610
  try {
7535
- let { globby } = await import("./globby-PFUJPJPH.js"), { readFile: readFile10 } = await import("node:fs/promises"), files = await globby(`${searchDir}/**/*`, {
7611
+ let { globby } = await import("./globby-N46UCCVS.js"), { readFile: readFile10 } = await import("node:fs/promises"), files = await globby(`${searchDir}/**/*`, {
7536
7612
  onlyFiles: !0,
7537
7613
  gitignore: !0
7538
7614
  }), referencedFiles = [];
@@ -7553,8 +7629,8 @@ var getDotStorybookReferences = async (searchDir) => {
7553
7629
  async check({ packageManager, mainConfigPath }) {
7554
7630
  if (!packageManager.getAllDependencies()["@storybook/react-native"])
7555
7631
  return null;
7556
- let projectDir = mainConfigPath ? join2(mainConfigPath, "..", "..") : process.cwd(), storybookDir = join2(projectDir, ".storybook"), rnStorybookDir = join2(projectDir, RN_STORYBOOK_DIR), { globby } = await import("./globby-PFUJPJPH.js"), requiresFiles = await globby(join2(storybookDir, "storybook.requires.*"));
7557
- return existsSync2(storybookDir) && requiresFiles.length > 0 && !existsSync2(rnStorybookDir) ? { storybookDir, rnStorybookDir } : null;
7632
+ let projectDir = mainConfigPath ? join3(mainConfigPath, "..", "..") : process.cwd(), storybookDir = join3(projectDir, ".storybook"), rnStorybookDir = join3(projectDir, RN_STORYBOOK_DIR), { globby } = await import("./globby-N46UCCVS.js"), requiresFiles = await globby(join3(storybookDir, "storybook.requires.*"));
7633
+ return existsSync3(storybookDir) && requiresFiles.length > 0 && !existsSync3(rnStorybookDir) ? { storybookDir, rnStorybookDir } : null;
7558
7634
  },
7559
7635
  prompt() {
7560
7636
  return dedent9`We'll rename your .storybook directory to .rnstorybook and update all references to it.`;
@@ -7597,9 +7673,9 @@ var storybookPackageNameConflict = {
7597
7673
  // src/automigrate/fixes/upgrade-storybook-related-dependencies.ts
7598
7674
  var import_semver5 = __toESM(require_semver(), 1);
7599
7675
  import { readFileSync as readFileSync4 } from "node:fs";
7600
- import { dirname as dirname2 } from "node:path";
7676
+ import { dirname as dirname3 } from "node:path";
7601
7677
  import { isCorePackage, isSatelliteAddon } from "storybook/internal/common";
7602
- import { logger as logger14 } from "storybook/internal/node-logger";
7678
+ import { logger as logger15 } from "storybook/internal/node-logger";
7603
7679
  import { dedent as dedent11 } from "ts-dedent";
7604
7680
  async function getLatestVersions(packageManager, packages) {
7605
7681
  return Promise.all(
@@ -7611,14 +7687,14 @@ async function getLatestVersions(packageManager, packages) {
7611
7687
  );
7612
7688
  }
7613
7689
  function isValidVersionType(packageName, specifier) {
7614
- return specifier.startsWith("patch:") || specifier.startsWith("file:") || specifier.startsWith("link:") || specifier.startsWith("portal:") || specifier.startsWith("git:") || specifier.startsWith("git+") || specifier.startsWith("http:") || specifier.startsWith("https:") || specifier.startsWith("workspace:") ? (logger14.debug(`Skipping ${packageName} as it does not have a valid version type: ${specifier}`), !1) : !0;
7690
+ return specifier.startsWith("patch:") || specifier.startsWith("file:") || specifier.startsWith("link:") || specifier.startsWith("portal:") || specifier.startsWith("git:") || specifier.startsWith("git+") || specifier.startsWith("http:") || specifier.startsWith("https:") || specifier.startsWith("workspace:") ? (logger15.debug(`Skipping ${packageName} as it does not have a valid version type: ${specifier}`), !1) : !0;
7615
7691
  }
7616
7692
  var upgradeStorybookRelatedDependencies = {
7617
7693
  id: "upgrade-storybook-related-dependencies",
7618
7694
  promptType: "auto",
7619
7695
  defaultSelected: !1,
7620
7696
  async check({ packageManager, storybookVersion }) {
7621
- logger14.debug("Checking for incompatible storybook packages...");
7697
+ logger15.debug("Checking for incompatible storybook packages...");
7622
7698
  let analyzedPackages = await getIncompatibleStorybookPackages({
7623
7699
  currentStorybookVersion: storybookVersion,
7624
7700
  packageManager,
@@ -7639,7 +7715,7 @@ var upgradeStorybookRelatedDependencies = {
7639
7715
  },
7640
7716
  async run({ result: { upgradable }, packageManager, dryRun }) {
7641
7717
  if (dryRun) {
7642
- logger14.log(dedent11`
7718
+ logger15.log(dedent11`
7643
7719
  The following would have been upgraded:
7644
7720
  ${upgradable.map(
7645
7721
  ({ packageName, afterVersion, beforeVersion }) => `${packageName}: ${beforeVersion} => ${afterVersion}`
@@ -7655,7 +7731,7 @@ var upgradeStorybookRelatedDependencies = {
7655
7731
  return;
7656
7732
  let { packageName, afterVersion: version2 } = item, prefixed = `^${version2}`;
7657
7733
  packageJson.dependencies?.[packageName] && (packageJson.dependencies[packageName] = prefixed), packageJson.devDependencies?.[packageName] && (packageJson.devDependencies[packageName] = prefixed), packageJson.peerDependencies?.[packageName] && (packageJson.peerDependencies[packageName] = prefixed);
7658
- }), packageManager.writePackageJson(packageJson, dirname2(packageJsonPath));
7734
+ }), packageManager.writePackageJson(packageJson, dirname3(packageJsonPath));
7659
7735
  });
7660
7736
  }
7661
7737
  };
@@ -7717,6 +7793,7 @@ var allFixes = [
7717
7793
  consolidatedImports,
7718
7794
  addonExperimentalTest,
7719
7795
  rnstorybookConfig,
7796
+ rnOndeviceAddonsToDeviceAddons,
7720
7797
  migrateAddonConsole,
7721
7798
  nextjsToNextjsVite,
7722
7799
  removeAddonInteractions,
@@ -7732,7 +7809,7 @@ var commandFixes = [csfFactories];
7732
7809
 
7733
7810
  // src/automigrate/helpers/logMigrationSummary.ts
7734
7811
  var import_picocolors13 = __toESM(require_picocolors(), 1);
7735
- import { CLI_COLORS as CLI_COLORS2, logger as logger15 } from "storybook/internal/node-logger";
7812
+ import { CLI_COLORS as CLI_COLORS2, logger as logger16 } from "storybook/internal/node-logger";
7736
7813
  import { dedent as dedent13 } from "ts-dedent";
7737
7814
  var messageDivider2 = `
7738
7815
 
@@ -7770,21 +7847,21 @@ function logMigrationSummary({
7770
7847
  let hasNoFixes = Object.values(fixResults).every((r) => r === "unnecessary" /* UNNECESSARY */), hasFailures2 = Object.values(fixResults).some(
7771
7848
  (r) => r === "failed" /* FAILED */ || r === "check_failed" /* CHECK_FAILED */
7772
7849
  );
7773
- hasNoFixes ? logger15.warn("No migrations were applicable to your project") : hasFailures2 ? logger15.error("Migration check ran with failures") : logger15.step(CLI_COLORS2.success("Migration check ran successfully")), logger15.log(messages2.filter(Boolean).join(segmentDivider));
7850
+ hasNoFixes ? logger16.warn("No migrations were applicable to your project") : hasFailures2 ? logger16.error("Migration check ran with failures") : logger16.step(CLI_COLORS2.success("Migration check ran successfully")), logger16.log(messages2.filter(Boolean).join(segmentDivider));
7774
7851
  }
7775
7852
 
7776
7853
  // src/automigrate/index.ts
7777
7854
  var logAvailableMigrations = () => {
7778
7855
  let availableFixes = [...allFixes, ...commandFixes].map((f) => import_picocolors14.default.yellow(f.id)).map((x) => `- ${x}`).join(`
7779
7856
  `);
7780
- logger16.log(dedent14`
7857
+ logger17.log(dedent14`
7781
7858
  The following migrations are available:
7782
7859
  ${availableFixes}
7783
7860
  `);
7784
7861
  }, hasFailures = (fixResults) => Object.values(fixResults || {}).some(
7785
7862
  (r) => r === "failed" /* FAILED */ || r === "check_failed" /* CHECK_FAILED */
7786
7863
  ), doAutomigrate = async (options) => {
7787
- logger16.debug("Extracting storybook data...");
7864
+ logger17.debug("Extracting storybook data...");
7788
7865
  let {
7789
7866
  mainConfig,
7790
7867
  mainConfigPath,
@@ -7847,7 +7924,7 @@ var logAvailableMigrations = () => {
7847
7924
  return logAvailableMigrations(), null;
7848
7925
  let commandFix = commandFixes.find((f) => f.id === fixId);
7849
7926
  if (commandFix)
7850
- return logger16.step(`Running migration ${import_picocolors14.default.magenta(fixId)}..`), await commandFix.run({
7927
+ return logger17.step(`Running migration ${import_picocolors14.default.magenta(fixId)}..`), await commandFix.run({
7851
7928
  mainConfigPath,
7852
7929
  previewConfigPath,
7853
7930
  packageManager,
@@ -7862,8 +7939,8 @@ var logAvailableMigrations = () => {
7862
7939
  }), null;
7863
7940
  let selectedFixes = inputFixes || allFixes.filter((fix) => !(fix.id === upgradeStorybookRelatedDependencies.id && isLatest === !1 && fixId !== upgradeStorybookRelatedDependencies.id)), fixes = fixId ? selectedFixes.filter((f) => f.id === fixId) : selectedFixes;
7864
7941
  if (fixId && fixes.length === 0)
7865
- return logger16.log(`\u{1F4ED} No migrations found for ${import_picocolors14.default.magenta(fixId)}.`), logAvailableMigrations(), null;
7866
- logger16.step("Checking possible migrations..");
7942
+ return logger17.log(`\u{1F4ED} No migrations found for ${import_picocolors14.default.magenta(fixId)}.`), logAvailableMigrations(), null;
7943
+ logger17.step("Checking possible migrations..");
7867
7944
  let { fixResults, fixSummary, preCheckFailure } = await runFixes({
7868
7945
  fixes,
7869
7946
  packageManager,
@@ -7904,7 +7981,7 @@ async function runFixes({
7904
7981
  for (let i = 0; i < fixes.length; i += 1) {
7905
7982
  let f = fixes[i], result;
7906
7983
  try {
7907
- logger16.debug(`Running ${import_picocolors14.default.cyan(f.id)} migration checks`), result = await f.check({
7984
+ logger17.debug(`Running ${import_picocolors14.default.cyan(f.id)} migration checks`), result = await f.check({
7908
7985
  packageManager,
7909
7986
  configDir,
7910
7987
  rendererPackage,
@@ -7914,14 +7991,14 @@ async function runFixes({
7914
7991
  mainConfigPath,
7915
7992
  storiesPaths,
7916
7993
  hasCsfFactoryPreview
7917
- }), logger16.debug(`End of ${import_picocolors14.default.cyan(f.id)} migration checks`);
7994
+ }), logger17.debug(`End of ${import_picocolors14.default.cyan(f.id)} migration checks`);
7918
7995
  } catch (error) {
7919
- logger16.warn(`\u26A0\uFE0F failed to check fix ${import_picocolors14.default.bold(f.id)}`), error instanceof Error && (logger16.error(`
7996
+ logger17.warn(`\u26A0\uFE0F failed to check fix ${import_picocolors14.default.bold(f.id)}`), error instanceof Error && (logger17.error(`
7920
7997
  ${error.stack}`), fixSummary.failed[f.id] = error.message), fixResults[f.id] = "check_failed" /* CHECK_FAILED */;
7921
7998
  }
7922
7999
  if (result) {
7923
8000
  let promptType = typeof f.promptType == "function" ? await f.promptType(result) : f.promptType ?? "auto";
7924
- logger16.log(`\u{1F50E} found a '${import_picocolors14.default.cyan(f.id)}' migration:`);
8001
+ logger17.log(`\u{1F50E} found a '${import_picocolors14.default.cyan(f.id)}' migration:`);
7925
8002
  let getTitle = () => {
7926
8003
  switch (promptType) {
7927
8004
  case "auto":
@@ -7935,7 +8012,7 @@ ${error.stack}`), fixSummary.failed[f.id] = error.message), fixResults[f.id] = "
7935
8012
  id: `automigrate-task-${f.id}`,
7936
8013
  title: `${getTitle()}: ${import_picocolors14.default.cyan(f.id)}`
7937
8014
  });
7938
- logger16.logBox(f.prompt());
8015
+ logger17.logBox(f.prompt());
7939
8016
  let runAnswer;
7940
8017
  try {
7941
8018
  if (dryRun)
@@ -7997,7 +8074,7 @@ ${error.stack}`), fixSummary.failed[f.id] = error.message), fixResults[f.id] = "
7997
8074
  storybookVersion,
7998
8075
  storiesPaths,
7999
8076
  yes
8000
- }), logger16.log(`\u2705 ran ${import_picocolors14.default.cyan(f.id)} migration`), fixResults[f.id] = "succeeded" /* SUCCEEDED */, fixSummary.succeeded.push(f.id), currentTaskLogger.success(`Ran ${import_picocolors14.default.cyan(f.id)} migration`);
8077
+ }), logger17.log(`\u2705 ran ${import_picocolors14.default.cyan(f.id)} migration`), fixResults[f.id] = "succeeded" /* SUCCEEDED */, fixSummary.succeeded.push(f.id), currentTaskLogger.success(`Ran ${import_picocolors14.default.cyan(f.id)} migration`);
8001
8078
  } catch (error) {
8002
8079
  fixResults[f.id] = "failed" /* FAILED */;
8003
8080
  let errorMessage = error instanceof Error ? error.message : "Failed to run migration";
@@ -8014,9 +8091,9 @@ ${error.stack}`), fixSummary.failed[f.id] = error.message), fixResults[f.id] = "
8014
8091
  // src/link.ts
8015
8092
  var import_cross_spawn = __toESM(require_cross_spawn(), 1);
8016
8093
  import { mkdir, readFile as readFile9, writeFile as writeFile8 } from "node:fs/promises";
8017
- import { basename as basename2, extname as extname2, join as join3 } from "node:path";
8094
+ import { basename as basename3, extname as extname2, join as join4 } from "node:path";
8018
8095
  import { executeCommand } from "storybook/internal/common";
8019
- import { logger as logger17 } from "storybook/internal/node-logger";
8096
+ import { logger as logger18 } from "storybook/internal/node-logger";
8020
8097
  var link = async ({ target, local, start }) => {
8021
8098
  let storybookDir = process.cwd();
8022
8099
  try {
@@ -8025,14 +8102,14 @@ var link = async ({ target, local, start }) => {
8025
8102
  } catch {
8026
8103
  throw new Error("Expected to run link from the root of the storybook monorepo");
8027
8104
  }
8028
- let reproDir = target, reproName = basename2(target);
8105
+ let reproDir = target, reproName = basename3(target);
8029
8106
  if (!local) {
8030
- let reprosDir = join3(storybookDir, "../storybook-repros");
8031
- logger17.info(`Ensuring directory ${reprosDir}`), await mkdir(reprosDir, { recursive: !0 }), logger17.info(`Cloning ${target}`), await executeCommand({
8107
+ let reprosDir = join4(storybookDir, "../storybook-repros");
8108
+ logger18.info(`Ensuring directory ${reprosDir}`), await mkdir(reprosDir, { recursive: !0 }), logger18.info(`Cloning ${target}`), await executeCommand({
8032
8109
  command: "git",
8033
8110
  args: ["clone", target],
8034
8111
  cwd: reprosDir
8035
- }), reproName = basename2(target, extname2(target)), reproDir = join3(reprosDir, reproName);
8112
+ }), reproName = basename3(target, extname2(target)), reproDir = join4(reprosDir, reproName);
8036
8113
  }
8037
8114
  let version2 = (0, import_cross_spawn.sync)("yarn", ["--version"], {
8038
8115
  cwd: reproDir,
@@ -8040,16 +8117,16 @@ var link = async ({ target, local, start }) => {
8040
8117
  shell: !0
8041
8118
  }).stdout.toString();
8042
8119
  if (!/^[2-4]\./.test(version2)) {
8043
- logger17.warn(`\u{1F6A8} Expected yarn 2 or higher in ${reproDir}!`), logger17.warn(""), logger17.warn("Please set it up with `yarn set version berry`,"), logger17.warn(`then link '${reproDir}' with the '--local' flag.`);
8120
+ logger18.warn(`\u{1F6A8} Expected yarn 2 or higher in ${reproDir}!`), logger18.warn(""), logger18.warn("Please set it up with `yarn set version berry`,"), logger18.warn(`then link '${reproDir}' with the '--local' flag.`);
8044
8121
  return;
8045
8122
  }
8046
- logger17.info(`Linking ${reproDir}`), await executeCommand({
8123
+ logger18.info(`Linking ${reproDir}`), await executeCommand({
8047
8124
  command: "yarn",
8048
8125
  args: ["link", "--all", "--relative", storybookDir],
8049
8126
  cwd: reproDir
8050
- }), logger17.info(`Installing ${reproName}`);
8127
+ }), logger18.info(`Installing ${reproName}`);
8051
8128
  let reproPackageJson = JSON.parse(
8052
- await readFile9(join3(reproDir, "package.json"), { encoding: "utf8" })
8129
+ await readFile9(join4(reproDir, "package.json"), { encoding: "utf8" })
8053
8130
  );
8054
8131
  reproPackageJson.devDependencies?.vite || (reproPackageJson.devDependencies = {
8055
8132
  ...reproPackageJson.devDependencies,
@@ -8057,11 +8134,11 @@ var link = async ({ target, local, start }) => {
8057
8134
  }), reproPackageJson.devDependencies = {
8058
8135
  ...reproPackageJson.devDependencies,
8059
8136
  "@types/node": "^22"
8060
- }, await writeFile8(join3(reproDir, "package.json"), JSON.stringify(reproPackageJson, null, 2)), await executeCommand({
8137
+ }, await writeFile8(join4(reproDir, "package.json"), JSON.stringify(reproPackageJson, null, 2)), await executeCommand({
8061
8138
  command: "yarn",
8062
8139
  args: ["install"],
8063
8140
  cwd: reproDir
8064
- }), start && (logger17.info(`Running ${reproName} storybook`), await executeCommand({
8141
+ }), start && (logger18.info(`Running ${reproName} storybook`), await executeCommand({
8065
8142
  command: "yarn",
8066
8143
  args: ["run", "storybook"],
8067
8144
  cwd: reproDir
@@ -8069,22 +8146,22 @@ var link = async ({ target, local, start }) => {
8069
8146
  };
8070
8147
 
8071
8148
  // src/migrate.ts
8072
- import { logger as logger18 } from "storybook/internal/node-logger";
8149
+ import { logger as logger19 } from "storybook/internal/node-logger";
8073
8150
  import { listCodemods, runCodemod as runCodemod2 } from "@storybook/codemod";
8074
8151
  async function migrate(migration, { glob, dryRun, list, rename: rename2, parser }) {
8075
8152
  if (list)
8076
- listCodemods().forEach((key) => logger18.log(key));
8153
+ listCodemods().forEach((key) => logger19.log(key));
8077
8154
  else if (migration)
8078
- await runCodemod2(migration, { glob, dryRun, logger: logger18, rename: rename2, parser });
8155
+ await runCodemod2(migration, { glob, dryRun, logger: logger19, rename: rename2, parser });
8079
8156
  else
8080
8157
  throw new Error("Migrate: please specify a migration name or --list");
8081
8158
  }
8082
8159
 
8083
8160
  // src/sandbox.ts
8084
8161
  var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
8085
- import { existsSync as existsSync3 } from "node:fs";
8162
+ import { existsSync as existsSync4 } from "node:fs";
8086
8163
  import { mkdir as mkdir2, readdir, rm } from "node:fs/promises";
8087
- import { isAbsolute as isAbsolute2 } from "node:path";
8164
+ import { isAbsolute as isAbsolute3 } from "node:path";
8088
8165
  import { PackageManagerName } from "storybook/internal/common";
8089
8166
  import {
8090
8167
  JsPackageManagerFactory,
@@ -8092,7 +8169,7 @@ import {
8092
8169
  optionalEnvToBoolean as optionalEnvToBoolean2,
8093
8170
  versions as versions4
8094
8171
  } from "storybook/internal/common";
8095
- import { logger as logger19, prompt as prompt4 } from "storybook/internal/node-logger";
8172
+ import { logger as logger20, prompt as prompt4 } from "storybook/internal/node-logger";
8096
8173
  var import_picocolors15 = __toESM(require_picocolors(), 1), import_semver6 = __toESM(require_semver(), 1);
8097
8174
  import { dedent as dedent15 } from "ts-dedent";
8098
8175
 
@@ -8475,6 +8552,46 @@ var baseTemplates = {
8475
8552
  },
8476
8553
  skipTasks: ["e2e-tests", "e2e-tests-dev", "bench", "vitest-integration"]
8477
8554
  },
8555
+ "tanstack-react-router/default-ts": {
8556
+ name: "TanStack React Router Latest (Vite | TypeScript)",
8557
+ script: "npx @tanstack/cli@latest create {{beforeDir}} --tailwind --router-only",
8558
+ expected: {
8559
+ framework: "@storybook/tanstack-react",
8560
+ renderer: "@storybook/react",
8561
+ builder: "@storybook/builder-vite"
8562
+ },
8563
+ modifications: {
8564
+ useCsfFactory: !0,
8565
+ extraDependencies: ["prop-types"],
8566
+ mainConfig: {
8567
+ framework: "@storybook/tanstack-react",
8568
+ features: {
8569
+ experimentalTestSyntax: !0
8570
+ }
8571
+ }
8572
+ },
8573
+ skipTasks: ["bench"]
8574
+ },
8575
+ "tanstack-react-start/default-ts": {
8576
+ name: "TanStack React Start Latest (Vite | TypeScript)",
8577
+ script: "npx @tanstack/cli@latest create {{beforeDir}} --tailwind",
8578
+ expected: {
8579
+ framework: "@storybook/tanstack-react",
8580
+ renderer: "@storybook/react",
8581
+ builder: "@storybook/builder-vite"
8582
+ },
8583
+ modifications: {
8584
+ useCsfFactory: !0,
8585
+ extraDependencies: ["prop-types"],
8586
+ mainConfig: {
8587
+ framework: "@storybook/tanstack-react",
8588
+ features: {
8589
+ experimentalTestSyntax: !0
8590
+ }
8591
+ }
8592
+ },
8593
+ skipTasks: ["bench"]
8594
+ },
8478
8595
  "vue3-vite/default-js": {
8479
8596
  name: "Vue v3 (Vite | JavaScript)",
8480
8597
  script: "npm create vite --yes {{beforeDir}} -- --template vue",
@@ -8958,7 +9075,9 @@ var baseTemplates = {
8958
9075
  "bench/react-vite-default-ts-test-build",
8959
9076
  "bench/react-webpack-18-ts-test-build",
8960
9077
  // 'ember/default-js',
8961
- "react-rsbuild/default-ts"
9078
+ "react-rsbuild/default-ts",
9079
+ "tanstack-react-router/default-ts",
9080
+ "tanstack-react-start/default-ts"
8962
9081
  ], merged = [
8963
9082
  ...normal,
8964
9083
  "react-webpack/18-ts",
@@ -9017,7 +9136,7 @@ var toChoices = (c) => ({ label: allTemplates[c].name, value: c }), sandbox = as
9017
9136
  ),
9018
9137
  prerelease: import_picocolors15.default.yellow("This is a pre-release version.")
9019
9138
  };
9020
- if (logger19.logBox(
9139
+ if (logger20.logBox(
9021
9140
  [messages2.welcome].concat(isOutdated && !isPrerelease ? [messages2.notLatest] : []).concat(init && (isOutdated || isPrerelease) ? [messages2.longInitTime] : []).concat(isPrerelease ? [messages2.prerelease] : []).join(`
9022
9141
  `),
9023
9142
  {
@@ -9028,7 +9147,7 @@ var toChoices = (c) => ({ label: allTemplates[c].name, value: c }), sandbox = as
9028
9147
  let current = allTemplates[group];
9029
9148
  return (!filterValue || current.name.match(filterRegex) || group.match(filterRegex) || current.expected.builder.match(filterRegex) || current.expected.framework.match(filterRegex) || current.expected.renderer.match(filterRegex)) && acc.push(group), acc;
9030
9149
  }, []);
9031
- if (choices.length === 0 && (logger19.logBox(
9150
+ if (choices.length === 0 && (logger20.logBox(
9032
9151
  dedent15`
9033
9152
  🔎 You filtered out all templates. 🔍
9034
9153
 
@@ -9041,7 +9160,7 @@ var toChoices = (c) => ({ label: allTemplates[c].name, value: c }), sandbox = as
9041
9160
  `)}
9042
9161
  `.trim(),
9043
9162
  { borderStyle: "round", padding: 1, borderColor: "#F1618C" }
9044
- ), process.exit(1)), choices.length === 1 ? [templateId] = choices : (logger19.logBox(
9163
+ ), process.exit(1)), choices.length === 1 ? [templateId] = choices : (logger20.logBox(
9045
9164
  dedent15`
9046
9165
  🤗 Welcome to ${import_picocolors15.default.yellow("sb sandbox")}! 🤗
9047
9166
 
@@ -9054,28 +9173,28 @@ var toChoices = (c) => ({ label: allTemplates[c].name, value: c }), sandbox = as
9054
9173
  `.trim(),
9055
9174
  { borderStyle: "round", padding: 1, borderColor: "#F1618C" }
9056
9175
  ), templateId = await promptSelectedTemplate(choices)), !!!(templateId ?? null)) {
9057
- logger19.error("Somehow we got no templates. Please rerun this command!");
9176
+ logger20.error("Somehow we got no templates. Please rerun this command!");
9058
9177
  return;
9059
9178
  }
9060
9179
  if (selectedConfig = templateId ? allTemplates[templateId] : void 0, !selectedConfig)
9061
9180
  throw new Error("\u{1F6A8} Sandbox: please specify a valid template type");
9062
9181
  }
9063
9182
  let selectedDirectory = outputDirectory, outputDirectoryName = outputDirectory || templateId;
9064
- selectedDirectory && existsSync3(`${selectedDirectory}`) && (logger19.log(`\u26A0\uFE0F ${selectedDirectory} already exists! Overwriting...`), await rm(selectedDirectory, { recursive: !0, force: !0 })), selectedDirectory || (selectedDirectory = await prompt4.text(
9183
+ selectedDirectory && existsSync4(`${selectedDirectory}`) && (logger20.log(`\u26A0\uFE0F ${selectedDirectory} already exists! Overwriting...`), await rm(selectedDirectory, { recursive: !0, force: !0 })), selectedDirectory || (selectedDirectory = await prompt4.text(
9065
9184
  {
9066
9185
  message: "Enter the output directory",
9067
9186
  initialValue: outputDirectoryName ?? void 0,
9068
- validate: (directoryName) => directoryName && existsSync3(directoryName) ? `${directoryName} already exists. Please choose another name.` : void 0
9187
+ validate: (directoryName) => directoryName && existsSync4(directoryName) ? `${directoryName} already exists. Please choose another name.` : void 0
9069
9188
  },
9070
9189
  {
9071
9190
  onCancel: () => {
9072
- logger19.log("Command cancelled by the user. Exiting..."), process.exit(1);
9191
+ logger20.log("Command cancelled by the user. Exiting..."), process.exit(1);
9073
9192
  }
9074
9193
  }
9075
9194
  )), invariant(selectedDirectory);
9076
9195
  try {
9077
- let templateDestination = isAbsolute2(selectedDirectory) ? selectedDirectory : join(process.cwd(), selectedDirectory);
9078
- logger19.log(`\u{1F3C3} Adding ${selectedConfig.name} into ${templateDestination}`), logger19.log(`\u{1F4E6} Downloading sandbox template (${import_picocolors15.default.bold(downloadType)})...`);
9196
+ let templateDestination = isAbsolute3(selectedDirectory) ? selectedDirectory : join(process.cwd(), selectedDirectory);
9197
+ logger20.log(`\u{1F3C3} Adding ${selectedConfig.name} into ${templateDestination}`), logger20.log(`\u{1F4E6} Downloading sandbox template (${import_picocolors15.default.bold(downloadType)})...`);
9079
9198
  try {
9080
9199
  let gitPath = `storybookjs/sandboxes/tree/${branch}/${templateId}/${downloadType}`;
9081
9200
  if (await mkdir2(templateDestination, { recursive: !0 }), (0, import_cross_spawn2.sync)("npx", ["gitpick@4.12.4", gitPath, templateDestination, "-o"], {
@@ -9099,13 +9218,13 @@ var toChoices = (c) => ({ label: allTemplates[c].name, value: c }), sandbox = as
9099
9218
  }), process.chdir(before);
9100
9219
  }
9101
9220
  } catch (err) {
9102
- throw logger19.error(`\u{1F6A8} Failed to download sandbox template: ${String(err)}`), err;
9221
+ throw logger20.error(`\u{1F6A8} Failed to download sandbox template: ${String(err)}`), err;
9103
9222
  }
9104
9223
  let initMessage = init ? import_picocolors15.default.yellow(dedent15`
9105
9224
  yarn install
9106
9225
  yarn storybook
9107
9226
  `) : `Recreate your setup, then ${import_picocolors15.default.yellow("npx storybook@latest init")}`;
9108
- logger19.logBox(
9227
+ logger20.logBox(
9109
9228
  dedent15`
9110
9229
  🎉 Your Storybook reproduction project is ready to use! 🎉
9111
9230
 
@@ -9123,7 +9242,7 @@ var toChoices = (c) => ({ label: allTemplates[c].name, value: c }), sandbox = as
9123
9242
  { rounded: !0 }
9124
9243
  );
9125
9244
  } catch (error) {
9126
- throw logger19.error("\u{1F6A8} Failed to create sandbox"), error;
9245
+ throw logger20.error("\u{1F6A8} Failed to create sandbox"), error;
9127
9246
  }
9128
9247
  };
9129
9248
  async function promptSelectedTemplate(choices) {
@@ -9135,33 +9254,28 @@ async function promptSelectedTemplate(choices) {
9135
9254
 
9136
9255
  // src/ai/index.ts
9137
9256
  import { writeFile as writeFile9 } from "node:fs/promises";
9138
- import { resolve as resolve3 } from "node:path";
9139
- import { cache } from "storybook/internal/common";
9140
- import { logger as logger21 } from "storybook/internal/node-logger";
9141
- import {
9142
- getSessionId,
9143
- isTelemetryModuleEnabled,
9144
- snapshotPreviewFile,
9145
- telemetry
9146
- } from "storybook/internal/telemetry";
9257
+ import { resolve as resolve4 } from "node:path";
9258
+ import { cache, getPrettyPackageManagerName } from "storybook/internal/common";
9259
+ import { logger as logger22 } from "storybook/internal/node-logger";
9260
+ import { telemetry } from "storybook/internal/telemetry";
9147
9261
  import { SupportedLanguage as SupportedLanguage2 } from "storybook/internal/types";
9148
9262
 
9149
9263
  // ../create-storybook/src/services/ProjectTypeService.ts
9150
- import { existsSync as existsSync5 } from "node:fs";
9151
- import { resolve as resolve2 } from "node:path";
9264
+ import { existsSync as existsSync6 } from "node:fs";
9265
+ import { resolve as resolve3 } from "node:path";
9152
9266
  import { ProjectType as ProjectType2 } from "storybook/internal/cli";
9153
9267
  import { HandledError, getProjectRoot } from "storybook/internal/common";
9154
- import { logger as logger20 } from "storybook/internal/node-logger";
9268
+ import { logger as logger21 } from "storybook/internal/node-logger";
9155
9269
  import { NxProjectDetectedError } from "storybook/internal/server-errors";
9156
9270
  import { SupportedLanguage } from "storybook/internal/types";
9157
9271
 
9158
9272
  // ../../../node_modules/empathic/find.mjs
9159
- import { join as join4 } from "node:path";
9160
- import { existsSync as existsSync4, statSync } from "node:fs";
9273
+ import { join as join5 } from "node:path";
9274
+ import { existsSync as existsSync5, statSync } from "node:fs";
9161
9275
  function up2(name, options) {
9162
9276
  let dir, tmp, start = options && options.cwd || "";
9163
9277
  for (dir of up(start, options))
9164
- if (tmp = join4(dir, name), existsSync4(tmp)) return tmp;
9278
+ if (tmp = join5(dir, name), existsSync5(tmp)) return tmp;
9165
9279
  }
9166
9280
 
9167
9281
  // ../create-storybook/src/services/ProjectTypeService.ts
@@ -9179,6 +9293,11 @@ var ProjectTypeService = class {
9179
9293
  dependencies: ["nuxt"],
9180
9294
  matcherFunction: ({ dependencies }) => dependencies?.every(Boolean) ?? !0
9181
9295
  },
9296
+ {
9297
+ preset: ProjectType2.TANSTACK_REACT,
9298
+ dependencies: ["@tanstack/start", "@tanstack/react-start", "@tanstack/react-router"],
9299
+ matcherFunction: ({ dependencies }) => dependencies?.some(Boolean) ?? !1
9300
+ },
9182
9301
  {
9183
9302
  preset: ProjectType2.VUE3,
9184
9303
  dependencies: {
@@ -9204,7 +9323,7 @@ var ProjectTypeService = class {
9204
9323
  },
9205
9324
  {
9206
9325
  preset: ProjectType2.REACT_NATIVE,
9207
- dependencies: ["react-native", "react-native-scripts"],
9326
+ dependencies: ["react-native", "react-native-scripts", "expo"],
9208
9327
  matcherFunction: ({ dependencies }) => dependencies?.some(Boolean) ?? !1
9209
9328
  },
9210
9329
  {
@@ -9255,15 +9374,15 @@ var ProjectTypeService = class {
9255
9374
  }
9256
9375
  ];
9257
9376
  }
9258
- isStorybookInstantiated(configDir = resolve2(process.cwd(), ".storybook")) {
9259
- return existsSync5(configDir);
9377
+ isStorybookInstantiated(configDir = resolve3(process.cwd(), ".storybook")) {
9378
+ return existsSync6(configDir);
9260
9379
  }
9261
9380
  async validateProvidedType(projectTypeProvided) {
9262
9381
  if (Object.values(ProjectType2).filter(
9263
9382
  (t10) => !["undetected", "unsupported", "nx"].includes(String(t10))
9264
9383
  ).includes(projectTypeProvided))
9265
9384
  return projectTypeProvided;
9266
- throw logger20.error(
9385
+ throw logger21.error(
9267
9386
  `The provided project type ${projectTypeProvided} was not recognized by Storybook`
9268
9387
  ), new HandledError(`Unknown project type supplied: ${projectTypeProvided}`);
9269
9388
  }
@@ -9271,7 +9390,7 @@ var ProjectTypeService = class {
9271
9390
  try {
9272
9391
  let detectedType = await this.detectProjectType(options);
9273
9392
  if (detectedType === ProjectType2.UNDETECTED || detectedType === null)
9274
- throw logger20.error(dedent16`
9393
+ throw logger21.error(dedent16`
9275
9394
  Unable to initialize Storybook in this directory.
9276
9395
 
9277
9396
  Storybook couldn't detect a supported framework or configuration for your project. Make sure you're inside a framework project (e.g., React, Vue, Svelte, Angular, Next.js) and that its dependencies are installed.
@@ -9284,12 +9403,12 @@ var ProjectTypeService = class {
9284
9403
  throw new NxProjectDetectedError();
9285
9404
  return detectedType;
9286
9405
  } catch (err) {
9287
- throw err instanceof HandledError || err instanceof NxProjectDetectedError ? err : (logger20.error(String(err)), new HandledError(err instanceof Error ? err.message : String(err)));
9406
+ throw err instanceof HandledError || err instanceof NxProjectDetectedError ? err : (logger21.error(String(err)), new HandledError(err instanceof Error ? err.message : String(err)));
9288
9407
  }
9289
9408
  }
9290
9409
  async detectLanguage() {
9291
9410
  let language = SupportedLanguage.JAVASCRIPT;
9292
- if (existsSync5("jsconfig.json"))
9411
+ if (existsSync6("jsconfig.json"))
9293
9412
  return language;
9294
9413
  let isTypescriptDirectDependency = !!this.jsPackageManager.getAllDependencies().typescript, getModulePackageJSONVersion = async (pkg) => (await this.jsPackageManager.getModulePackageJSON(pkg))?.version ?? null, [
9295
9414
  typescriptVersion,
@@ -9304,9 +9423,9 @@ var ProjectTypeService = class {
9304
9423
  getModulePackageJSONVersion("@typescript-eslint/parser"),
9305
9424
  getModulePackageJSONVersion("eslint-plugin-storybook")
9306
9425
  ]), satisfies = (version2, range) => version2 ? import_semver7.default.satisfies(version2, range, { includePrerelease: !0 }) : !1;
9307
- return isTypescriptDirectDependency && typescriptVersion ? satisfies(typescriptVersion, ">=4.9.0") && (!prettierVersion || import_semver7.default.gte(prettierVersion, "2.8.0")) && (!babelPluginTransformTypescriptVersion || satisfies(babelPluginTransformTypescriptVersion, ">=7.20.0")) && (!typescriptEslintParserVersion || satisfies(typescriptEslintParserVersion, ">=5.44.0")) && (!eslintPluginStorybookVersion || satisfies(eslintPluginStorybookVersion, ">=0.6.8")) ? language = SupportedLanguage.TYPESCRIPT : logger20.warn(
9426
+ return isTypescriptDirectDependency && typescriptVersion ? satisfies(typescriptVersion, ">=4.9.0") && (!prettierVersion || import_semver7.default.gte(prettierVersion, "2.8.0")) && (!babelPluginTransformTypescriptVersion || satisfies(babelPluginTransformTypescriptVersion, ">=7.20.0")) && (!typescriptEslintParserVersion || satisfies(typescriptEslintParserVersion, ">=5.44.0")) && (!eslintPluginStorybookVersion || satisfies(eslintPluginStorybookVersion, ">=0.6.8")) ? language = SupportedLanguage.TYPESCRIPT : logger21.warn(
9308
9427
  "Detected TypeScript < 4.9 or incompatible tooling, populating with JavaScript examples"
9309
- ) : existsSync5("tsconfig.json") && (language = SupportedLanguage.TYPESCRIPT), language;
9428
+ ) : existsSync6("tsconfig.json") && (language = SupportedLanguage.TYPESCRIPT), language;
9310
9429
  }
9311
9430
  eqMajor(versionRange, major) {
9312
9431
  return import_semver7.default.validRange(versionRange) ? import_semver7.default.minVersion(versionRange)?.major === major : !1;
@@ -9349,7 +9468,7 @@ var ProjectTypeService = class {
9349
9468
  let peerDependencySearches = [];
9350
9469
  return Array.isArray(peerDependencies) ? peerDependencySearches = peerDependencies.map((name) => [name, void 0]) : typeof peerDependencies == "object" && (peerDependencySearches = Object.entries(peerDependencies)), peerDependencySearches.length > 0 && (matcher.peerDependencies = peerDependencySearches.map(
9351
9470
  ([name, matchFn]) => this.hasPeerDependency(packageJson, name, matchFn)
9352
- )), Array.isArray(files) && files.length > 0 && (matcher.files = files.map((name) => existsSync5(name))), matcherFunction(matcher) ? preset : null;
9471
+ )), Array.isArray(files) && files.length > 0 && (matcher.files = files.map((name) => existsSync6(name))), matcherFunction(matcher) ? preset : null;
9353
9472
  }
9354
9473
  hasDependency(packageJson, name, matcher) {
9355
9474
  let version2 = packageJson.dependencies?.[name] || packageJson.devDependencies?.[name];
@@ -9364,876 +9483,74 @@ var ProjectTypeService = class {
9364
9483
  }
9365
9484
  };
9366
9485
 
9367
- // src/ai/prompt.ts
9368
- import { dedent as dedent18 } from "ts-dedent";
9369
-
9370
- // src/ai/setup-prompts/pattern-copy-play.ts
9486
+ // src/ai/setup-prompts/index.ts
9371
9487
  import { dedent as dedent17 } from "ts-dedent";
9372
- function getDocsMarkdownUrl(path4, projectInfo) {
9373
- let { majorVersion, renderer = "react", language = "ts" } = projectInfo ?? {}, versionSegment = majorVersion ? `/${majorVersion}` : "", params = new URLSearchParams();
9374
- renderer && params.set("renderer", renderer), params.set("language", language);
9375
- let query = params.toString();
9376
- return `https://storybook.js.org/docs${versionSegment}/${path4}.md${query ? `?${query}` : ""}`;
9377
- }
9378
- function getTypeImportSource(projectInfo) {
9379
- return projectInfo.framework || projectInfo.rendererPackage || "@storybook/react";
9380
- }
9381
- function getDocsReferenceSection(projectInfo) {
9382
- let docsUrl = (path4) => getDocsMarkdownUrl(path4, projectInfo);
9383
- return dedent17`
9384
- ### Storybook Documentation Reference
9385
-
9386
- Use the following references to look up Storybook APIs, concepts, or examples:
9387
-
9388
- - Full docs index: https://storybook.js.org/llms.txt
9389
- - See code snippets only with codeOnly=true param e.g. ${docsUrl("writing-stories")}&codeOnly=true
9390
-
9391
- Key documentation pages for this task:
9392
- - Writing stories: ${docsUrl("writing-stories")}
9393
- - Decorators: ${docsUrl("writing-stories/decorators")}
9394
- - Args: ${docsUrl("writing-stories/args")}
9395
- - Play functions: ${docsUrl("writing-stories/play-function")}
9396
- - Vitest integration: ${docsUrl("writing-tests/vitest-plugin")}
9397
-
9398
- Fetch these URLs directly when you need guidance on Storybook APIs or patterns.
9399
- `;
9400
- }
9401
- function getPreviewConfigExample(projectInfo) {
9402
- let configDir = projectInfo.configDir, typeImport = getTypeImportSource(projectInfo);
9403
- return projectInfo.hasCsfFactoryPreview ? dedent17`
9404
- \`\`\`tsx
9405
- // ${configDir}/preview.tsx
9406
- import '../src/index.css'; // import global styles
9407
- import MockDate from 'mockdate';
9408
-
9409
- import { definePreview } from 'storybook/preview';
9410
- import { SessionProvider } from '../src/contexts/SessionContext';
9411
-
9412
- export default definePreview({
9413
- decorators: [
9414
- (Story) => (
9415
- <SessionProvider>
9416
- <Story />
9417
- </SessionProvider>
9418
- ),
9419
- ],
9420
- async beforeEach() {
9421
- localStorage.setItem('theme', 'dark');
9422
- localStorage.setItem('sidebar:open', 'true');
9423
- MockDate.set('2024-04-01T12:00:00Z');
9424
- },
9425
- });
9426
- \`\`\`
9427
- ` : dedent17`
9428
- \`\`\`tsx
9429
- // ${configDir}/preview.tsx
9430
- import type { Preview } from '${typeImport}';
9431
- import MockDate from 'mockdate';
9432
- import '../src/index.css'; // import global styles
9433
- import { SessionProvider } from '../src/contexts/SessionContext';
9434
-
9435
- const preview: Preview = {
9436
- decorators: [
9437
- (Story) => (
9438
- <SessionProvider>
9439
- <Story />
9440
- </SessionProvider>
9441
- ),
9442
- ],
9443
- async beforeEach() {
9444
- localStorage.setItem('theme', 'dark');
9445
- localStorage.setItem('sidebar:open', 'true');
9446
- MockDate.set('2024-04-01T12:00:00Z');
9447
- },
9448
- };
9449
-
9450
- export default preview;
9451
- \`\`\`
9452
- `;
9453
- }
9454
- function getMockDateExample(projectInfo) {
9455
- let typeImport = getTypeImportSource(projectInfo);
9456
- return projectInfo.hasCsfFactoryPreview ? dedent17`
9457
- \`\`\`tsx
9458
- import MockDate from 'mockdate';
9459
- import { definePreview } from 'storybook/preview';
9460
-
9461
- export default definePreview({
9462
- async beforeEach() {
9463
- MockDate.set('2024-04-01T12:00:00Z');
9464
- },
9465
- });
9466
- \`\`\`
9467
- ` : dedent17`
9468
- \`\`\`tsx
9469
- import type { Preview } from '${typeImport}';
9470
- import MockDate from 'mockdate';
9471
-
9472
- const preview: Preview = {
9473
- async beforeEach() {
9474
- MockDate.set('2024-04-01T12:00:00Z');
9475
- },
9476
- };
9477
-
9478
- export default preview;
9479
- \`\`\`
9480
- `;
9481
- }
9482
- function getMswPreviewExample(projectInfo) {
9483
- let configDir = projectInfo.configDir, typeImport = getTypeImportSource(projectInfo);
9484
- return projectInfo.hasCsfFactoryPreview ? dedent17`
9485
- \`\`\`tsx
9486
- // ${configDir}/preview.tsx
9487
- import { definePreview } from 'storybook/preview';
9488
- import { initialize, mswLoader } from 'msw-storybook-addon';
9489
- import { mswHandlers } from './msw-handlers';
9490
-
9491
- initialize({
9492
- onUnhandledRequest: 'bypass',
9493
- });
9494
-
9495
- export default definePreview({
9496
- loaders: [mswLoader],
9497
- parameters: {
9498
- msw: {
9499
- handlers: mswHandlers,
9500
- },
9501
- },
9502
- });
9503
- \`\`\`
9504
- ` : dedent17`
9505
- \`\`\`tsx
9506
- // ${configDir}/preview.tsx
9507
- import type { Preview } from '${typeImport}';
9508
- import { initialize, mswLoader } from 'msw-storybook-addon';
9509
- import { mswHandlers } from './msw-handlers';
9510
-
9511
- initialize({
9512
- onUnhandledRequest: 'bypass',
9513
- });
9514
-
9515
- const preview: Preview = {
9516
- loaders: [mswLoader],
9517
- parameters: {
9518
- msw: {
9519
- handlers: mswHandlers,
9520
- },
9521
- },
9522
- };
9523
-
9524
- export default preview;
9525
- \`\`\`
9526
- `;
9527
- }
9528
- function getStoryExample(projectInfo) {
9529
- if (projectInfo.hasCsfFactoryPreview)
9530
- return dedent17`
9531
- \`\`\`tsx
9532
- import preview from '#.storybook/preview';
9533
- import { expect } from 'storybook/test';
9534
- import { SomeComponent } from './SomeComponent';
9535
-
9536
- const meta = preview.meta({
9537
- component: SomeComponent,
9538
- tags: ['ai-generated'],
9539
- });
9540
-
9541
- export const Default = meta.story({
9542
- render: () => <SomeComponent variant="primary" disabled={false} />,
9543
- play: async ({ canvas }) => {
9544
- await expect(canvas.getByRole('button')).toBeVisible();
9545
- },
9546
- });
9547
- \`\`\`
9548
- `;
9549
- let typeImport = getTypeImportSource(projectInfo);
9550
- return dedent17`
9551
- \`\`\`tsx
9552
- import type { Meta, StoryObj } from '${typeImport}';
9553
- import { expect } from 'storybook/test';
9554
- import { SomeComponent } from './SomeComponent';
9555
-
9556
- const meta = {
9557
- component: SomeComponent,
9558
- tags: ['ai-generated'],
9559
- } satisfies Meta<typeof SomeComponent>;
9560
-
9561
- export default meta;
9562
- type Story = StoryObj<typeof meta>;
9563
-
9564
- export const Default: Story = {
9565
- render: () => <SomeComponent variant="primary" disabled={false} />,
9566
- play: async ({ canvas }) => {
9567
- await expect(canvas.getByRole('button')).toBeVisible();
9568
- },
9569
- };
9570
- \`\`\`
9571
- `;
9572
- }
9573
- function getNeedsWorkTagExample(projectInfo) {
9574
- return projectInfo.hasCsfFactoryPreview ? dedent17`
9575
- \`\`\`ts
9576
- const meta = preview.meta({
9577
- component: SomeComponent,
9578
- tags: ['ai-generated', 'needs-work'],
9579
- });
9580
- \`\`\`
9581
- ` : dedent17`
9582
- \`\`\`ts
9583
- const meta = {
9584
- component: SomeComponent,
9585
- tags: ['ai-generated', 'needs-work'],
9586
- } satisfies Meta<typeof SomeComponent>;
9587
- \`\`\`
9588
- `;
9589
- }
9590
- function getArgsStoryExample(projectInfo) {
9591
- if (projectInfo.hasCsfFactoryPreview)
9592
- return dedent17`
9593
- \`\`\`tsx
9594
- import preview from '#.storybook/preview';
9595
- import { expect } from 'storybook/test';
9596
- import { Button } from './Button';
9597
-
9598
- const meta = preview.meta({
9599
- component: Button,
9600
- tags: ['ai-generated'],
9601
- });
9602
-
9603
- export const Primary = meta.story({
9604
- args: {
9605
- variant: 'primary',
9606
- children: 'Save',
9607
- },
9608
- play: async ({ canvas }) => {
9609
- await expect(canvas.getByRole('button', { name: /save/i })).toBeVisible();
9610
- },
9611
- });
9612
-
9613
- export const Disabled = meta.story({
9614
- args: {
9615
- variant: 'primary',
9616
- disabled: true,
9617
- children: 'Save',
9618
- },
9619
- play: async ({ canvas }) => {
9620
- await expect(canvas.getByRole('button')).toBeDisabled();
9621
- },
9622
- });
9623
- \`\`\`
9624
- `;
9625
- let typeImport = getTypeImportSource(projectInfo);
9626
- return dedent17`
9627
- \`\`\`tsx
9628
- import type { Meta, StoryObj } from '${typeImport}';
9629
- import { expect } from 'storybook/test';
9630
- import { Button } from './Button';
9631
-
9632
- const meta = {
9633
- component: Button,
9634
- tags: ['ai-generated'],
9635
- } satisfies Meta<typeof Button>;
9636
-
9637
- export default meta;
9638
- type Story = StoryObj<typeof meta>;
9639
-
9640
- export const Primary: Story = {
9641
- args: {
9642
- variant: 'primary',
9643
- children: 'Save',
9644
- },
9645
- play: async ({ canvas }) => {
9646
- await expect(canvas.getByRole('button', { name: /save/i })).toBeVisible();
9647
- },
9648
- };
9649
-
9650
- export const Disabled: Story = {
9651
- args: {
9652
- variant: 'primary',
9653
- disabled: true,
9654
- children: 'Save',
9655
- },
9656
- play: async ({ canvas }) => {
9657
- await expect(canvas.getByRole('button')).toBeDisabled();
9658
- },
9659
- };
9660
- \`\`\`
9661
- `;
9662
- }
9663
- function getRenderCompositionExample(projectInfo) {
9664
- if (projectInfo.hasCsfFactoryPreview)
9665
- return dedent17`
9666
- \`\`\`tsx
9667
- import preview from '#.storybook/preview';
9668
- import { expect } from 'storybook/test';
9669
- import { Button } from './Button';
9670
- import { Card } from './Card';
9671
-
9672
- const meta = preview.meta({
9673
- component: Button,
9674
- tags: ['ai-generated'],
9675
- });
9676
-
9677
- export const InsideCard = meta.story({
9678
- render: () => (
9679
- <Card>
9680
- <Button disabled={false}>Save</Button>
9681
- </Card>
9682
- ),
9683
- play: async ({ canvas, userEvent }) => {
9684
- await expect(canvas.getByRole('button', { name: /save/i })).toBeVisible();
9685
- await userEvent.click(canvas.getByRole('button', { name: /save/i }));
9686
- },
9687
- });
9688
- \`\`\`
9689
- `;
9690
- let typeImport = getTypeImportSource(projectInfo);
9691
- return dedent17`
9692
- \`\`\`tsx
9693
- import type { Meta, StoryObj } from '${typeImport}';
9694
- import { expect } from 'storybook/test';
9695
- import { Button } from './Button';
9696
- import { Card } from './Card';
9697
-
9698
- const meta = {
9699
- component: Button,
9700
- tags: ['ai-generated'],
9701
- } satisfies Meta<typeof Button>;
9702
-
9703
- export default meta;
9704
- type Story = StoryObj<typeof meta>;
9705
-
9706
- export const InsideCard: Story = {
9707
- render: () => (
9708
- <Card>
9709
- <Button disabled={false}>Save</Button>
9710
- </Card>
9711
- ),
9712
- play: async ({ canvas, userEvent }) => {
9713
- await expect(canvas.getByRole('button', { name: /save/i })).toBeVisible();
9714
- await userEvent.click(canvas.getByRole('button', { name: /save/i }));
9715
- },
9716
- };
9717
- \`\`\`
9718
- `;
9719
- }
9720
- function getPageStoryExample(projectInfo) {
9721
- if (projectInfo.hasCsfFactoryPreview)
9722
- return dedent17`
9723
- \`\`\`tsx
9724
- import preview from '#.storybook/preview';
9725
- import { expect } from 'storybook/test';
9726
- import { ProductPage } from './ProductPage';
9727
-
9728
- const meta = preview.meta({
9729
- component: ProductPage,
9730
- tags: ['ai-generated'],
9731
- });
9732
-
9733
- export const Default = meta.story({
9734
- render: () => <ProductPage />,
9735
- play: async ({ canvas }) => {
9736
- await expect(
9737
- canvas.getByRole('heading', { name: /products/i }),
9738
- ).toBeVisible();
9739
- },
9740
- });
9741
- \`\`\`
9742
- `;
9743
- let typeImport = getTypeImportSource(projectInfo);
9744
- return dedent17`
9745
- \`\`\`tsx
9746
- import type { Meta, StoryObj } from '${typeImport}';
9747
- import { expect } from 'storybook/test';
9748
- import { ProductPage } from './ProductPage';
9749
-
9750
- const meta = {
9751
- component: ProductPage,
9752
- tags: ['ai-generated'],
9753
- } satisfies Meta<typeof ProductPage>;
9754
-
9755
- export default meta;
9756
- type Story = StoryObj<typeof meta>;
9757
-
9758
- export const Default: Story = {
9759
- render: () => <ProductPage />,
9760
- play: async ({ canvas }) => {
9761
- await expect(
9762
- canvas.getByRole('heading', { name: /products/i }),
9763
- ).toBeVisible();
9764
- },
9765
- };
9766
- \`\`\`
9767
- `;
9768
- }
9769
- function instructions(projectInfo) {
9770
- let configDir = projectInfo.configDir, typeImport = getTypeImportSource(projectInfo);
9771
- return dedent17`
9772
- Attention: The following instructions must be followed in order to successfully set up Storybook in this project. Do not skip steps or attempt to do them out of order.
9773
-
9774
- Your goal is to make Storybook fully functional in this project by analyzing the codebase,
9775
- configuring the preview with the right decorators, and writing stories for some components.
9776
-
9777
- The end state should be a Storybook where any component — from a small button to a full page — can be added without story-specific workarounds. All necessary providers, CSS, browser state, and network mocks should live in the shared preview so that just rendering the component in the story is enough.
9778
-
9779
- After each created story, run Vitest to verify it renders.
9780
- If the test fails, read the error, fix the issue, and re-run until it passes before moving on.
9781
-
9782
- - Copy real patterns from the codebase
9783
- - Keep the app code unchanged
9784
- - Put the default setup in \`${configDir}/preview.tsx\`
9785
- - Keep app mocking and runtime setup in \`${configDir}/preview.tsx\`, not in the stories
9786
-
9787
- ${getDocsReferenceSection(projectInfo)}
9788
-
9789
- ### Step 1: Analyze the codebase
9790
-
9791
- Read enough of the app to understand the full runtime environment before writing any stories.
9792
-
9793
- Do not stop at \`main.tsx\` or \`App.tsx\`.
9794
- Follow imports into providers, pages, hooks, and shared components until you know:
9795
-
9796
- - which providers exist
9797
- - which CSS files are injected
9798
- - which queries fetch data
9799
- - which browser-state reads happen
9800
- - which portals and portal roots exist
9801
- - which pages and components show the real usage patterns
9802
-
9803
- Example of what to copy:
9804
-
9805
- \`\`\`tsx
9806
- // src/main.tsx
9807
- import "./index.css";
9808
- import App from "./App";
9809
- import { SessionProvider } from "./contexts/SessionContext";
9810
-
9811
- createRoot(document.getElementById("root")!).render(
9812
- <SessionProvider>
9813
- <App />
9814
- </SessionProvider>,
9815
- );
9816
- \`\`\`
9817
-
9818
- That means Storybook should copy:
9819
-
9820
- - the \`index.css\` import
9821
- - the \`SessionProvider\`
9822
- - the same provider order
9823
-
9824
- Example of tracing the app deeper:
9825
-
9826
- \`\`\`tsx
9827
- // src/App.tsx
9828
- function App() {
9829
- const { products, loadMoreProducts } = useProducts();
9830
- const { currentUser, signOut } = useSession();
9831
- // ...
9832
- }
9833
- \`\`\`
9834
-
9835
- \`\`\`ts
9836
- // src/hooks/useProducts.ts
9837
- const response = await fetch(apiBaseUrl + "/products?page=1");
9838
- \`\`\`
9839
-
9840
- \`\`\`ts
9841
- // src/hooks/useTheme.ts
9842
- const savedTheme = localStorage.getItem("theme");
9843
- \`\`\`
9844
-
9845
- That means the default Storybook setup should discover and prepare:
9846
-
9847
- - provider state
9848
- - MSW handlers for queries
9849
- - browser-state values that are actually read during render
9850
-
9851
- ### Step 2: Build one default app environment in preview
9852
-
9853
- Set up Storybook once so most stories work without story-specific setup.
9854
-
9855
- Start with the smallest faithful environment:
9856
-
9857
- - the real provider tree
9858
- - the real root CSS
9859
- - seeded browser state if the app reads it during render
9860
- - MSW for network/data queries
9861
-
9862
- It is fine to seed browser state such as \`localStorage\`, \`sessionStorage\`, and cookies when the app reads them during render.
9863
- Seed only the specific app-owned keys and values you need.
9864
- Do not clear all \`localStorage\`, \`sessionStorage\`, or cookies, and do not reset Storybook's own state.
9865
- Do not mock or redefine the browser runtime itself.
9866
- The stories run in Vitest browser mode, so the real browser environment should already exist.
9867
-
9868
- ${getPreviewConfigExample(projectInfo)}
9869
-
9870
- Use this same idea for:
9871
-
9872
- - providers
9873
- - root CSS
9874
- - browser state
9875
- - dates, and if the app logic depends on them during render then always use \`mockdate\`
9876
-
9877
- Example with the \`mockdate\` package:
9878
-
9879
- ${getMockDateExample(projectInfo)}
9880
-
9881
- ### Step 3: Support portals with preview-body.html
9882
-
9883
- If the app uses portals, copy that setup into Storybook too.
9884
-
9885
- Look for patterns like:
9886
-
9887
- - \`createPortal(...)\`
9888
- - modal, dialog, drawer, popover, tooltip, toast, or dropdown portal components
9889
- - hard-coded roots such as \`#portal-root\`, \`#modal-root\`, \`#drawer-root\`, or \`#toast-root\`
9890
-
9891
- Example of what to copy:
9892
-
9893
- \`\`\`tsx
9894
- // real component
9895
- return createPortal(<ModalContent />, document.getElementById("portal-root")!);
9896
- \`\`\`
9897
-
9898
- That means Storybook should create the same portal root in \`${configDir}/preview-body.html\`:
9899
-
9900
- \`\`\`html
9901
- <!-- ${configDir}/preview-body.html -->
9902
- <div id="portal-root"></div>
9903
- \`\`\`
9904
-
9905
- If the app uses multiple portal roots, create all of them there:
9906
-
9907
- \`\`\`html
9908
- <!-- ${configDir}/preview-body.html -->
9909
- <div id="modal-root"></div>
9910
- <div id="drawer-root"></div>
9911
- <div id="toast-root"></div>
9912
- \`\`\`
9913
-
9914
- If a library portals directly to \`document.body\`, do not add extra roots for it.
9915
- Make sure the copied page shell, CSS, and layout still allow overlays, fixed positioning, and z-index stacking to render correctly.
9916
-
9917
- ### Step 4: Mock side effects globally
9918
-
9919
- All network/data queries should be handled by the default Storybook environment.
9920
-
9921
- - Always use \`msw-storybook-addon\` for query mocking.
9922
- - If you introduce MSW, run \`npx msw init ./public --save\` to create the worker file.
9923
- - Make sure Storybook serves \`./public\` as a static dir so \`mockServiceWorker.js\` is available.
9924
- - Do not mock \`fetch\` directly.
9925
- - Network/data queries should return deterministic mock data.
9926
- - If you need to change dependencies, first check the lockfile and use that package manager for the change.
9927
-
9928
- Example of copying a real fetch pattern into shared handlers:
9929
-
9930
- \`\`\`ts
9931
- // real app hook
9932
- const response = await fetch(
9933
- apiBaseUrl +
9934
- "/products?" +
9935
- new URLSearchParams({
9936
- page: "1",
9937
- sort: "featured",
9938
- }),
9939
- );
9940
- \`\`\`
9941
-
9942
- \`\`\`ts
9943
- // ${configDir}/msw-handlers.ts
9944
- import { http, HttpResponse } from "msw";
9945
-
9946
- export const mswHandlers = {
9947
- products: [
9948
- http.get("https://api.example.com/products", () =>
9949
- HttpResponse.json({
9950
- items: [
9951
- {
9952
- id: "product-1",
9953
- name: "Example product",
9954
- description: "Mock product description",
9955
- imageUrl: "https://images.example.com/product.jpg",
9956
- price: 42,
9957
- },
9958
- ],
9959
- }),
9960
- ),
9961
- ],
9962
- };
9963
- \`\`\`
9964
-
9965
- ${getMswPreviewExample(projectInfo)}
9966
-
9967
- \`\`\`ts
9968
- // ${configDir}/main.ts
9969
- import type { StorybookConfig } from "${typeImport}";
9970
-
9971
- const config: StorybookConfig = {
9972
- staticDirs: ["../public"],
9973
- };
9974
-
9975
- export default config;
9976
- \`\`\`
9977
-
9978
- Keep these mocks global.
9979
- Do not put fetch mocks in individual stories.
9980
- Only add handlers for requests that the shared preview setup or the stories actually use.
9981
- Do not add catch-all handlers that can hide unrelated failures.
9982
- If the defaults are not enough, improve the shared default setup instead.
9983
- Seed browser state when needed, but do not mock \`window\`, \`document\`, \`navigator\`, observers, or similar runtime APIs.
9984
- The only exception is \`mockdate\` when date-based rendering exists.
9985
-
9986
- ### Step 5: Write stories
9987
-
9988
- Try to find around 10 good candidate components for story files.
9989
- Write colocated stories for top-level components, from low-level reusable components up to page components.
9990
- Write up to 10 story files, or fewer only if the codebase clearly has fewer meaningful targets.
9991
-
9992
- The stories should use JSX copied from real usage patterns in:
9993
-
9994
- - pages
9995
- - app shells
9996
- - routes
9997
- - tests
9998
- - existing feature code
9999
-
10000
- As a rule of thumb, each story file should have around 3 story exports when the component or page has enough meaningful states.
10001
- It can have more when the real usage supports it, up to 10 story exports in one file.
10002
-
10003
- Always show all imports explicitly in story and preview files.
10004
- Do not rely on omitted or implied imports in examples or generated code.
10005
9488
 
10006
- #### Story tags
10007
-
10008
- Every story meta must include the \`ai-generated\` tag to identify AI-created stories:
10009
-
10010
- ${getStoryExample(projectInfo)}
10011
-
10012
- If a story could not be fully fixed after the self-healing loop (the test still fails
10013
- or the rendering is incomplete), add the \`needs-work\` tag alongside \`ai-generated\`:
10014
-
10015
- ${getNeedsWorkTagExample(projectInfo)}
10016
-
10017
- #### Args vs render
10018
-
10019
- For simple components where props drive the state, prefer \`args\` stories — no \`render\` function needed:
10020
-
10021
- ${getArgsStoryExample(projectInfo)}
10022
-
10023
- Use \`render\` when the story needs composition — wrapping the component in layout, combining multiple components, or passing children as JSX:
10024
-
10025
- ${getRenderCompositionExample(projectInfo)}
10026
-
10027
- Keep app mocking and runtime setup in preview, not in the stories.
10028
- Do not build large story-specific harnesses.
10029
- Do not write story files for subcomponents, hooks, contexts, or helpers.
10030
- Do not create new application components.
10031
- Do not add a custom \`title\`.
10032
- Do not stop after only a few easy targets if the codebase has more meaningful components or pages available.
10033
-
10034
- ### Step 6: Write a play function for every story
10035
-
10036
- Every named story export must have a \`play\` function.
10037
- The \`play\` function is not optional, even for simple stories.
10038
-
10039
- The purpose of the \`play\` function is to prove that the story actually works in the copied Storybook environment:
10040
-
10041
- - the story renders something real and non-empty
10042
- - the decorators provide the needed context
10043
- - the CSS is applied well enough for the intended state to be visible
10044
- - the MSW mocks or seeded browser state are actually being used
10045
- - important interactions, async loading states, and portals behave correctly
10046
-
10047
- Use \`play\` functions to verify behavior, not just to click around.
10048
- A story without assertions is incomplete.
10049
-
10050
- Use tools from \`storybook/test\` such as:
10051
-
10052
- - \`expect\`
10053
- - \`waitFor\`
10054
-
10055
- Prefer \`canvas\` and \`userEvent\` from the \`play\` context.
10056
- Do not destructure \`canvasElement\` just to create \`const canvas = within(canvasElement)\`.
10057
- Do not import \`userEvent\` from \`storybook/test\`; use \`userEvent\` from the \`play\` context instead.
10058
- Only use \`canvasElement.ownerDocument\` when you need to query outside the canvas, such as for portals.
10059
-
10060
- Example:
10061
-
10062
- \`\`\`tsx
10063
- import type { StoryObj } from "${typeImport}";
10064
-
10065
- export const FilledForm: Story = {
10066
- play: async ({ canvas, userEvent }) => {
10067
- const emailInput = canvas.getByLabelText("email", {
10068
- selector: "input",
10069
- });
10070
-
10071
- await userEvent.type(emailInput, "example-email@email.com", {
10072
- delay: 100,
10073
- });
10074
-
10075
- const passwordInput = canvas.getByLabelText("password", {
10076
- selector: "input",
10077
- });
10078
-
10079
- await userEvent.type(passwordInput, "ExamplePassword", {
10080
- delay: 100,
10081
- });
10082
-
10083
- const submitButton = canvas.getByRole("button");
10084
- await userEvent.click(submitButton);
10085
- },
10086
- };
10087
- \`\`\`
10088
-
10089
- The assertions should match the real pattern you copied:
10090
-
10091
- - for provider-backed stories, assert the provider-dependent UI appears correctly
10092
- - for mocked-data stories, wait for the mocked data to appear and assert on it
10093
- - for CSS-sensitive states, assert on visibility, text layout, class-driven states, or meaningful computed styles
10094
- - for routing or navigation stories, assert the routed state or navigation outcome
10095
- - for portal stories, query from \`canvasElement.ownerDocument\` when the UI renders outside the canvas
10096
-
10097
- Examples of useful checks:
10098
-
10099
- - a themed button has the expected label and is visibly enabled or disabled
10100
- - a modal opened through a decorator or provider is visible in the portal root
10101
- - mocked API data appears in the page instead of a loading spinner forever
10102
- - a selected tab actually shows the selected panel
10103
- - a toast, alert, or badge has the expected accessible text and visual state
10104
- - a CSS class or computed style confirms the real state that matters
10105
-
10106
- ### Step 7: Prove CSS is loaded in exactly one story named \`CssCheck\`
10107
-
10108
- In exactly one story, named \`CssCheck\`, assert a component-specific computed style. \`toBeVisible\` passes on an unstyled component; a concrete style value proves the shared preview loaded the app's CSS.
10109
-
10110
- Pick a visually distinctive component, read a styling value from its source, and assert it with \`getComputedStyle\`:
10111
-
10112
- \`\`\`tsx
10113
- export const CssCheck: Story = {
10114
- args: { children: "Submit" },
10115
- play: async ({ canvas }) => {
10116
- const button = canvas.getByRole("button", { name: /submit/i });
10117
- // PrimaryButton uses bg-blue-600 — fails if Tailwind / global CSS did not load.
10118
- await expect(getComputedStyle(button).backgroundColor).toBe("rgb(37, 99, 235)");
10119
- },
10120
- };
10121
- \`\`\`
10122
-
10123
- ### Step 8: Cover the patterns you found
10124
-
10125
- Write stories for the real patterns in the codebase, for example:
10126
-
10127
- - a low-level reusable component in real JSX usage
10128
- - a provider-backed component
10129
- - a browser-state-backed component
10130
- - a fetched-data component
10131
- - a real page component
10132
-
10133
- Use \`App.tsx\` to inspect the real provider tree and usage patterns, but do not make a story for \`App\` when the codebase has actual page components.
10134
-
10135
- Example page story:
10136
-
10137
- ${getPageStoryExample(projectInfo)}
10138
-
10139
- ### Step 9: Verify both rendering and types
10140
-
10141
- As you work, verify the stories with Vitest:
10142
-
10143
- \`\`\`bash
10144
- npx vitest --project storybook <path-to-story-file>
10145
- \`\`\`
10146
-
10147
- Also verify types so you catch missing required props, broken imports, and preview typing issues. Run the same TypeScript command the project itself uses.
10148
-
10149
- \`\`\`bash
10150
- <project-specific-typescript-command>
10151
- \`\`\`
10152
-
10153
- After verification passes, review every changed file and remove anything that is not needed for the final solution, especially debug fixes, overly broad mocks, unnecessary dependencies, and eval artifacts.
10154
-
10155
- Keep iterating until:
10156
-
10157
- - every story you wrote passes
10158
- - every story you wrote has a meaningful passing \`play\` function
10159
- - the changed stories and preview setup pass the project's real TypeScript check
10160
- - the rendered output looks sensible
10161
- - the default global mocked environment is strong enough that stories do not need manual fetch overrides
10162
- - stories no longer fail because the shared preview setup and story JSX are fixed
10163
- - all passing stories have \`tags: ['ai-generated']\` in their meta
10164
- - any stories that still need work have \`tags: ['ai-generated', 'needs-work']\` in their meta
10165
- `;
9489
+ // src/ai/utils/project-overview.ts
9490
+ function getProjectOverview(projectInfo) {
9491
+ let rows = [
9492
+ ["Version", projectInfo.storybookVersion || "unknown"],
9493
+ ["Renderer", projectInfo.rendererPackage || "unknown"],
9494
+ ["Framework", projectInfo.framework || "unknown"],
9495
+ ["Builder", projectInfo.builderPackage || "unknown"],
9496
+ ["Config Dir", `\`${projectInfo.configDir}\``],
9497
+ ["Language", projectInfo.language === "ts" ? "TypeScript" : "JavaScript"]
9498
+ ];
9499
+ return projectInfo.packageManager && rows.push(["Package Manager", projectInfo.packageManagerName || "unknown"]), rows.push(["Addons", projectInfo.addons.length > 0 ? projectInfo.addons.join(", ") : "none"]), ["## Project Info", "", "| Property | Value |", "|----------|-------|", rows.map(([key, value]) => `| ${key} | ${value} |`).join(`
9500
+ `)].join(
9501
+ `
9502
+ `
9503
+ );
10166
9504
  }
10167
9505
 
10168
9506
  // src/ai/setup-prompts/index.ts
10169
- var CURRENTLY_USED_PROMPT = {
10170
- "pattern-copy-play": instructions
9507
+ var DEFAULT_PROMPT_NAME = "pattern-copy-play", CURRENTLY_USED_PROMPT = {
9508
+ [DEFAULT_PROMPT_NAME]: instructions
10171
9509
  }, FORMERLY_USED_PROMPTS = {
10172
- setup: async () => (await import("./setup-VZ6IVNC4.js")).instructions
9510
+ monorepo: async () => (await import("./monorepo-TVSJOSCW.js")).instructions,
9511
+ "optimized-tests": async () => (await import("./optimized-tests-V6WOQ2XH.js")).instructions,
9512
+ "relaxed-limits": async () => (await import("./relaxed-limits-YQA6Y4DQ.js")).instructions,
9513
+ setup: async () => (await import("./setup-HAYJDL6K.js")).instructions,
9514
+ "pattern-copy-play": async () => (await import("./pattern-copy-play-6YIEGMCW.js")).instructions
10173
9515
  }, PROMPT_NAMES = [
10174
9516
  ...Object.keys(CURRENTLY_USED_PROMPT),
10175
9517
  ...Object.keys(FORMERLY_USED_PROMPTS)
10176
- ], DEFAULT_PROMPT_NAME = "pattern-copy-play", EVAL_SETUP_PROMPT_ENV = "EVAL_SETUP_PROMPT";
9518
+ ], EVAL_SETUP_PROMPT_ENV = "EVAL_SETUP_PROMPT";
10177
9519
  function resolvePromptName() {
10178
9520
  let requested = process.env[EVAL_SETUP_PROMPT_ENV]?.trim();
10179
9521
  return requested && (Object.hasOwn(CURRENTLY_USED_PROMPT, requested) || Object.hasOwn(FORMERLY_USED_PROMPTS, requested)) ? requested : DEFAULT_PROMPT_NAME;
10180
9522
  }
10181
- async function getPrompts(projectInfo) {
10182
- let name = resolvePromptName(), builder = CURRENTLY_USED_PROMPT[name] ?? await FORMERLY_USED_PROMPTS[name]();
10183
- return {
10184
- prompts: [
10185
- {
10186
- name,
10187
- description: "Set up Storybook for success",
10188
- instructions: builder(projectInfo)
10189
- }
10190
- ]
10191
- };
10192
- }
10193
-
10194
- // src/ai/prompt.ts
10195
- function getProjectOverview(projectInfo) {
10196
- return dedent18`
10197
- ## Project Info
10198
-
10199
- | Property | Value |
10200
- |----------|-------|
10201
- | Version | ${projectInfo.storybookVersion || "unknown"} |
10202
- | Renderer | ${projectInfo.rendererPackage || "unknown"} |
10203
- | Framework | ${projectInfo.framework || "unknown"} |
10204
- | Builder | ${projectInfo.builderPackage || "unknown"} |
10205
- | Config Dir | \`${projectInfo.configDir}\` |
10206
- | CSF Format | ${projectInfo.hasCsfFactoryPreview ? "CSF Factory" : "CSF3"} |
10207
- | Addons | ${projectInfo.addons.length > 0 ? projectInfo.addons.join(", ") : "none"} |
10208
- `;
9523
+ async function getAiSetupPrompt(projectInfo) {
9524
+ let name = resolvePromptName();
9525
+ return (CURRENTLY_USED_PROMPT[name] ?? await FORMERLY_USED_PROMPTS[name]())(projectInfo);
10209
9526
  }
10210
- async function generateMarkdownOutput(projectInfo) {
10211
- let { prompts: aiPrompts } = await getPrompts(projectInfo), sections = [];
10212
- sections.push(dedent18`
9527
+ async function getAiSetupMarkdownOutput(projectInfo) {
9528
+ return {
9529
+ markdown: dedent17`
10213
9530
  # Storybook Setup
10214
- `), sections.push(getProjectOverview(projectInfo));
10215
- for (let aiPrompt of aiPrompts)
10216
- sections.push(aiPrompt.instructions);
10217
- return { markdown: sections.join(`
10218
9531
 
10219
- `) };
9532
+ ${getProjectOverview(projectInfo)}
9533
+
9534
+ ${await getAiSetupPrompt(projectInfo)}
9535
+ `
9536
+ };
10220
9537
  }
10221
9538
 
10222
9539
  // src/ai/index.ts
10223
9540
  async function aiSetup(options) {
10224
- let { configDir: userConfigDir, packageManager: packageManagerName, output } = options, projectInfo;
9541
+ let { configDir: userConfigDir, packageManager, output } = options, projectInfo;
10225
9542
  try {
10226
9543
  let data = await getStorybookData({
10227
9544
  configDir: userConfigDir,
10228
- packageManagerName
10229
- }), majorVersion = data.versionInstalled ? parseMajorVersion(data.versionInstalled) : void 0;
9545
+ packageManagerName: packageManager
9546
+ });
10230
9547
  if (!data.frameworkPackage || !data.rendererPackage || !data.builderPackage) {
10231
- logger21.error(
9548
+ logger22.error(
10232
9549
  "Could not detect framework, renderer, or builder from your Storybook config. Make sure you are running this command from your project root, or specify --config-dir."
10233
9550
  );
10234
9551
  return;
10235
9552
  }
10236
- let language = await new ProjectTypeService(data.packageManager).detectLanguage() === SupportedLanguage2.TYPESCRIPT ? "ts" : "js";
9553
+ let majorVersion = data.versionInstalled ? parseMajorVersion(data.versionInstalled) : void 0, language = await new ProjectTypeService(data.packageManager).detectLanguage() === SupportedLanguage2.TYPESCRIPT ? "ts" : "js", needsUserOnboarding = await cache.get("onboarding-pending", !1);
10237
9554
  projectInfo = {
10238
9555
  storybookVersion: data.versionInstalled,
10239
9556
  majorVersion,
@@ -10244,51 +9561,49 @@ async function aiSetup(options) {
10244
9561
  addons: data.addons ?? [],
10245
9562
  configDir: data.configDir,
10246
9563
  storiesPaths: data.storiesPaths,
9564
+ packageManager: data.packageManager,
9565
+ packageManagerName: getPrettyPackageManagerName(data.packageManager.type),
9566
+ language,
10247
9567
  hasCsfFactoryPreview: data.hasCsfFactoryPreview,
10248
- language
9568
+ needsUserOnboarding
10249
9569
  };
10250
9570
  } catch (err) {
10251
- logger21.error(
9571
+ logger22.error(
10252
9572
  `Failed to read Storybook configuration: ${err instanceof Error ? err.message : String(err)}`
10253
- ), logger21.log(
9573
+ ), logger22.log(
10254
9574
  "Make sure you are running this command from your project root, or specify --config-dir."
10255
9575
  );
10256
9576
  return;
10257
9577
  }
10258
9578
  if (projectInfo.rendererPackage !== "@storybook/react" || projectInfo.builderPackage !== "@storybook/builder-vite") {
10259
- logger21.log(
9579
+ logger22.log(
10260
9580
  "AI-assisted setup is currently only available for projects using the React renderer with Vite builder. Detected renderer: " + projectInfo.rendererPackage + ", builder: " + projectInfo.builderPackage
10261
9581
  );
10262
9582
  return;
10263
9583
  }
10264
- let markdownOutput = (await generateMarkdownOutput(projectInfo)).markdown;
10265
- if (await telemetry("ai-setup", {
9584
+ let markdownOutput = (await getAiSetupMarkdownOutput(projectInfo)).markdown;
9585
+ if (await cache.set("ai-setup-ran", {
9586
+ timestamp: Date.now(),
9587
+ configDir: resolve4(projectInfo.configDir)
9588
+ }).catch(() => {
9589
+ }), await telemetry("ai-setup", {
10266
9590
  cliOptions: {
10267
9591
  output: output ? "file" : void 0,
10268
9592
  configDir: projectInfo.configDir,
10269
- packageManager: packageManagerName
9593
+ packageManager: projectInfo.packageManager.type
10270
9594
  },
10271
9595
  project: {
10272
9596
  framework: projectInfo.framework,
10273
9597
  renderer: projectInfo.rendererPackage,
10274
9598
  builder: projectInfo.builderPackage,
10275
- language: projectInfo.language,
10276
- hasCsfFactoryPreview: projectInfo.hasCsfFactoryPreview
9599
+ language: projectInfo.language
10277
9600
  }
10278
- }), isTelemetryModuleEnabled()) {
10279
- let resolvedConfigDir = resolve3(projectInfo.configDir), previewSnapshot = await snapshotPreviewFile(resolvedConfigDir), sessionId = await getSessionId(), pendingRecord = {
10280
- timestamp: Date.now(),
10281
- sessionId,
10282
- configDir: resolvedConfigDir,
10283
- ...previewSnapshot
10284
- };
10285
- await cache.set("ai-setup-pending", pendingRecord);
10286
- }
10287
- if (output) {
10288
- let outputPath = resolve3(output);
10289
- await writeFile9(outputPath, markdownOutput, "utf-8"), logger21.log(`Prompt written to ${outputPath}`);
9601
+ }), output) {
9602
+ let outputPath = resolve4(output);
9603
+ await writeFile9(outputPath, markdownOutput, "utf-8"), logger22.log(`Prompt written to ${outputPath}`);
10290
9604
  } else
10291
- logger21.log(markdownOutput);
9605
+ process.stdout.write(`${markdownOutput}
9606
+ `);
10292
9607
  }
10293
9608
  function parseMajorVersion(version2) {
10294
9609
  let match = version2.match(/^(\d+)/);
@@ -10303,7 +9618,7 @@ import {
10303
9618
  CLI_COLORS as CLI_COLORS4,
10304
9619
  createHyperlink,
10305
9620
  logTracker as logTracker3,
10306
- logger as logger23,
9621
+ logger as logger24,
10307
9622
  prompt as prompt6
10308
9623
  } from "storybook/internal/node-logger";
10309
9624
  import {
@@ -10311,14 +9626,14 @@ import {
10311
9626
  UpgradeStorybookUnknownCurrentVersionError
10312
9627
  } from "storybook/internal/server-errors";
10313
9628
  import { telemetry as telemetry2 } from "storybook/internal/telemetry";
10314
- import { dedent as dedent19 } from "ts-dedent";
9629
+ import { dedent as dedent18 } from "ts-dedent";
10315
9630
 
10316
9631
  // src/automigrate/multi-project.ts
10317
- import { CLI_COLORS as CLI_COLORS3, logger as logger22, prompt as prompt5 } from "storybook/internal/node-logger";
9632
+ import { CLI_COLORS as CLI_COLORS3, logger as logger23, prompt as prompt5 } from "storybook/internal/node-logger";
10318
9633
  import { ErrorCollector, sanitizeError } from "storybook/internal/telemetry";
10319
9634
  async function collectAutomigrationsAcrossProjects(options) {
10320
9635
  let { fixes, projects, taskLog } = options, automigrationMap = /* @__PURE__ */ new Map();
10321
- logger22.debug(
9636
+ logger23.debug(
10322
9637
  `Starting automigration collection across ${projects.length} projects and ${fixes.length} fixes...`
10323
9638
  );
10324
9639
  function collectResult(fix, project, status, result) {
@@ -10340,10 +9655,10 @@ async function collectAutomigrationsAcrossProjects(options) {
10340
9655
  }
10341
9656
  for (let project of projects) {
10342
9657
  let projectName = shortenPath(project.configDir);
10343
- taskLog.message(`Checking automigrations for ${projectName}...`), logger22.debug(`Processing project: ${projectName}`);
9658
+ taskLog.message(`Checking automigrations for ${projectName}...`), logger23.debug(`Processing project: ${projectName}`);
10344
9659
  for (let fix of fixes)
10345
9660
  try {
10346
- logger22.debug(`Checking fix ${fix.id} for project ${projectName}...`);
9661
+ logger23.debug(`Checking fix ${fix.id} for project ${projectName}...`);
10347
9662
  let checkOptions = {
10348
9663
  packageManager: project.packageManager,
10349
9664
  configDir: project.configDir,
@@ -10356,9 +9671,9 @@ async function collectAutomigrationsAcrossProjects(options) {
10356
9671
  }, result = await fix.check(checkOptions);
10357
9672
  result !== null ? collectResult(fix, project, "check_succeeded", result) : collectResult(fix, project, "not_applicable");
10358
9673
  } catch (error) {
10359
- collectResult(fix, project, "check_failed"), logger22.debug(
9674
+ collectResult(fix, project, "check_failed"), logger23.debug(
10360
9675
  `Failed to check fix ${fix.id} for project ${shortenPath(project.configDir)}.`
10361
- ), logger22.debug(`${error instanceof Error ? error.stack : String(error)}`), ErrorCollector.addError(error);
9676
+ ), logger23.debug(`${error instanceof Error ? error.stack : String(error)}`), ErrorCollector.addError(error);
10362
9677
  }
10363
9678
  }
10364
9679
  let allAutomigrations = Array.from(automigrationMap.values()), applicableAutomigrations = allAutomigrations.filter(
@@ -10372,9 +9687,9 @@ async function collectAutomigrationsAcrossProjects(options) {
10372
9687
  );
10373
9688
  return taskLog.message(`
10374
9689
  Automigrations detected:`), successAutomigrations.forEach((fixId) => {
10375
- taskLog.message(`${CLI_COLORS3.success(`${logger22.SYMBOLS.success} ${fixId}`)}`);
9690
+ taskLog.message(`${CLI_COLORS3.success(`${logger23.SYMBOLS.success} ${fixId}`)}`);
10376
9691
  }), failedAutomigrations.forEach((fixId) => {
10377
- taskLog.message(`${CLI_COLORS3.error(`${logger22.SYMBOLS.error} ${fixId}`)}`);
9692
+ taskLog.message(`${CLI_COLORS3.error(`${logger23.SYMBOLS.error} ${fixId}`)}`);
10378
9693
  }), failedAutomigrations.length > 0 ? taskLog.error(
10379
9694
  `${failedAutomigrations.length} automigration ${failedAutomigrations.length > 1 ? "checks" : "check"} failed`
10380
9695
  ) : taskLog.success(
@@ -10392,12 +9707,12 @@ async function promptForAutomigrations(automigrations, options) {
10392
9707
  if (automigrations.length === 0)
10393
9708
  return [];
10394
9709
  if (options.dryRun)
10395
- return logger22.log("Detected automigrations (dry run - no changes will be made):"), automigrations.forEach(({ fix, reports: list }) => {
10396
- logger22.log(` - ${fix.id} (${formatProjectDirs(list)})`);
9710
+ return logger23.log("Detected automigrations (dry run - no changes will be made):"), automigrations.forEach(({ fix, reports: list }) => {
9711
+ logger23.log(` - ${fix.id} (${formatProjectDirs(list)})`);
10397
9712
  }), [];
10398
9713
  if (options.yes)
10399
- return logger22.log("Running all detected automigrations:"), automigrations.forEach(({ fix, reports: list }) => {
10400
- logger22.log(` - ${fix.id} (${formatProjectDirs(list)})`);
9714
+ return logger23.log("Running all detected automigrations:"), automigrations.forEach(({ fix, reports: list }) => {
9715
+ logger23.log(` - ${fix.id} (${formatProjectDirs(list)})`);
10401
9716
  }), automigrations;
10402
9717
  let choices = automigrations.map((am) => {
10403
9718
  let hint = [];
@@ -10446,13 +9761,13 @@ async function runAutomigrationsForProjects(selectedAutomigrations, options) {
10446
9761
  title: `${countPrefix}Running automigrations for ${projectName}`
10447
9762
  }) : {
10448
9763
  message: (message) => {
10449
- logger22.debug(`${message}`);
9764
+ logger23.debug(`${message}`);
10450
9765
  },
10451
9766
  error: (message) => {
10452
- logger22.debug(`${message}`);
9767
+ logger23.debug(`${message}`);
10453
9768
  },
10454
9769
  success: (message) => {
10455
- logger22.debug(`${message}`);
9770
+ logger23.debug(`${message}`);
10456
9771
  }
10457
9772
  }, fixResults = {}, fixFailures = {};
10458
9773
  for (let automigration of projectAutomigration) {
@@ -10486,11 +9801,11 @@ async function runAutomigrationsForProjects(selectedAutomigrations, options) {
10486
9801
  storiesPaths: project2.storiesPaths,
10487
9802
  yes
10488
9803
  };
10489
- await fix.run(runOptions), fixResults[fix.id] = "succeeded" /* SUCCEEDED */, taskLog.message(CLI_COLORS3.success(`${logger22.SYMBOLS.success} ${fix.id}`));
9804
+ await fix.run(runOptions), fixResults[fix.id] = "succeeded" /* SUCCEEDED */, taskLog.message(CLI_COLORS3.success(`${logger23.SYMBOLS.success} ${fix.id}`));
10490
9805
  }
10491
9806
  } catch (error) {
10492
9807
  let errorMessage = (error instanceof Error ? error.stack : String(error)) ?? "Unknown error";
10493
- fixResults[fix.id] = "failed" /* FAILED */, fixFailures[fix.id] = sanitizeError(error), taskLog.message(CLI_COLORS3.error(`${logger22.SYMBOLS.error} ${automigration.fix.id}`)), logger22.debug(errorMessage), ErrorCollector.addError(error);
9808
+ fixResults[fix.id] = "failed" /* FAILED */, fixFailures[fix.id] = sanitizeError(error), taskLog.message(CLI_COLORS3.error(`${logger23.SYMBOLS.error} ${automigration.fix.id}`)), logger23.debug(errorMessage), ErrorCollector.addError(error);
10494
9809
  }
10495
9810
  }
10496
9811
  let automigrationsWithErrors = Object.values(fixResults).filter(
@@ -10600,28 +9915,28 @@ function logUpgradeResults(projectResults, detectedAutomigrations, doctorResults
10600
9915
  doctorResults
10601
9916
  );
10602
9917
  if (failedProjects.length > 0) {
10603
- if (logTracker3.enableLogWriting(), logger23.step(
9918
+ if (logTracker3.enableLogWriting(), logger24.step(
10604
9919
  "The upgrade is complete, but some projects failed to upgrade or migrate completely. Please see the debug logs for more details."
10605
9920
  ), successfulProjects.length > 0) {
10606
9921
  let successfulProjectsList = successfulProjects.map((dir) => ` \u2022 ${shortenPath(dir)}`).join(`
10607
9922
  `);
10608
- logger23.log(`${CLI_COLORS4.success("Successfully upgraded:")}
9923
+ logger24.log(`${CLI_COLORS4.success("Successfully upgraded:")}
10609
9924
  ${successfulProjectsList}`);
10610
9925
  }
10611
9926
  let failedProjectsList = failedProjects.map((dir) => ` \u2022 ${shortenPath(dir)}`).join(`
10612
9927
  `);
10613
- if (logger23.log(
9928
+ if (logger24.log(
10614
9929
  `${CLI_COLORS4.error("Failed to upgrade:")}
10615
9930
  Some automigrations failed, please check the logs in the log file for more details.
10616
9931
  ${failedProjectsList}`
10617
9932
  ), projectsWithNoFixes.length > 0) {
10618
9933
  let projectList = projectsWithNoFixes.map((dir) => ` \u2022 ${shortenPath(dir)}`).join(`
10619
9934
  `);
10620
- logger23.log(`${CLI_COLORS4.info("No applicable migrations:")}
9935
+ logger24.log(`${CLI_COLORS4.info("No applicable migrations:")}
10621
9936
  ${projectList}`);
10622
9937
  }
10623
9938
  } else
10624
- Object.values(doctorResults).every((result) => result.status === "healthy") ? logger23.step(`${CLI_COLORS4.success("Your project(s) have been upgraded successfully! \u{1F389}")}`) : logger23.step(
9939
+ Object.values(doctorResults).every((result) => result.status === "healthy") ? logger24.step(`${CLI_COLORS4.success("Your project(s) have been upgraded successfully! \u{1F389}")}`) : logger24.step(
10625
9940
  `${import_picocolors16.default.yellow("Your project(s) have been upgraded successfully, but some issues were found which need your attention, please check Storybook doctor logs above.")}`
10626
9941
  );
10627
9942
  let automigrationLinks = detectedAutomigrations.filter(
@@ -10635,9 +9950,9 @@ ${projectList}`);
10635
9950
  ...automigrationLinks
10636
9951
  ].join(`
10637
9952
  `);
10638
- logger23.log(automigrationLinksMessage);
9953
+ logger24.log(automigrationLinksMessage);
10639
9954
  }
10640
- logger23.log(
9955
+ logger24.log(
10641
9956
  `For a full list of changes, please check our migration guide: ${CLI_COLORS4.cta("https://storybook.js.org/docs/releases/migration-guide?ref=upgrade")}`
10642
9957
  );
10643
9958
  }
@@ -10669,7 +9984,7 @@ async function sendMultiUpgradeTelemetry(options) {
10669
9984
  hasUserInterrupted
10670
9985
  });
10671
9986
  } catch (error) {
10672
- logger23.debug(`Failed to send multi-upgrade telemetry: ${String(error)}`);
9987
+ logger24.debug(`Failed to send multi-upgrade telemetry: ${String(error)}`);
10673
9988
  }
10674
9989
  }
10675
9990
  async function upgrade(options) {
@@ -10677,13 +9992,13 @@ async function upgrade(options) {
10677
9992
  if (projectsResult === void 0 || projectsResult.selectedProjects.length === 0)
10678
9993
  return;
10679
9994
  let { allProjects, selectedProjects: storybookProjects } = projectsResult;
10680
- storybookProjects.length > 1 ? logger23.info(`Upgrading the following projects:
9995
+ storybookProjects.length > 1 ? logger24.info(`Upgrading the following projects:
10681
9996
  ${storybookProjects.map((p) => `${import_picocolors16.default.cyan(shortenPath(p.configDir))}: ${import_picocolors16.default.bold(p.beforeVersion)} -> ${import_picocolors16.default.bold(p.currentCLIVersion)}`).join(`
10682
- `)}`) : logger23.info(
9997
+ `)}`) : logger24.info(
10683
9998
  `Upgrading from ${import_picocolors16.default.bold(storybookProjects[0].beforeVersion)} to ${import_picocolors16.default.bold(storybookProjects[0].currentCLIVersion)}`
10684
9999
  );
10685
10000
  let automigrationResults = {}, doctorResults = {}, handleInterruption = async () => {
10686
- throw logger23.log(`
10001
+ throw logger24.log(`
10687
10002
 
10688
10003
  Upgrade interrupted by user.`), allProjects.length > 1 && await sendMultiUpgradeTelemetry({
10689
10004
  allProjects,
@@ -10696,7 +10011,7 @@ Upgrade interrupted by user.`), allProjects.length > 1 && await sendMultiUpgrade
10696
10011
  process.on("SIGINT", handleInterruption), process.on("SIGTERM", handleInterruption);
10697
10012
  try {
10698
10013
  if (processAutoblockerResults(storybookProjects, (message) => {
10699
- logger23.error(dedent19`Blockers detected\n\n${message}`);
10014
+ logger24.error(dedent18`Blockers detected\n\n${message}`);
10700
10015
  }))
10701
10016
  throw new HandledError2("Blockers detected");
10702
10017
  if (storybookProjects.some((project) => {
@@ -10715,7 +10030,7 @@ Upgrade interrupted by user.`), allProjects.length > 1 && await sendMultiUpgrade
10715
10030
  try {
10716
10031
  let loggedPaths = [];
10717
10032
  for (let project of storybookProjects) {
10718
- logger23.debug(`Updating dependencies in ${shortenPath(project.configDir)}...`);
10033
+ logger24.debug(`Updating dependencies in ${shortenPath(project.configDir)}...`);
10719
10034
  let newPaths = project.packageManager.packageJsonPaths.map(shortenPath).filter((path4) => !loggedPaths.includes(path4));
10720
10035
  newPaths.length > 0 && (task.message(newPaths.join(`
10721
10036
  `)), loggedPaths.push(...newPaths)), await upgradeStorybookDependencies({
@@ -10733,17 +10048,17 @@ Upgrade interrupted by user.`), allProjects.length > 1 && await sendMultiUpgrade
10733
10048
  }
10734
10049
  }
10735
10050
  let automigrationResults2 = {}, detectedAutomigrations = [];
10736
- options.skipAutomigrations ? logger23.log("Skipping automigrations (--skip-automigrations).") : { automigrationResults: automigrationResults2, detectedAutomigrations } = await runAutomigrations(
10051
+ options.skipAutomigrations ? logger24.log("Skipping automigrations (--skip-automigrations).") : { automigrationResults: automigrationResults2, detectedAutomigrations } = await runAutomigrations(
10737
10052
  storybookProjects,
10738
10053
  options
10739
10054
  );
10740
10055
  let rootPackageManager = storybookProjects.length > 1 ? JsPackageManagerFactory2.getPackageManager({ force: options.packageManager }) : storybookProjects[0].packageManager;
10741
- rootPackageManager.type === "npm" ? await rootPackageManager.installDependencies({ force: !0 }) : await rootPackageManager.installDependencies(), rootPackageManager.type !== PackageManagerName2.YARN1 && rootPackageManager.isStorybookInMonorepo() && (logger23.warn(
10056
+ rootPackageManager.type === "npm" ? await rootPackageManager.installDependencies({ force: !0 }) : await rootPackageManager.installDependencies(), rootPackageManager.type !== PackageManagerName2.YARN1 && rootPackageManager.isStorybookInMonorepo() && (logger24.warn(
10742
10057
  "Since you are in a monorepo, we advise you to deduplicate your dependencies. We can do this for you but it might take some time."
10743
10058
  ), options.yes || await prompt6.confirm({
10744
10059
  message: `Execute ${rootPackageManager.getRunCommand("dedupe")}?`,
10745
10060
  initialValue: !0
10746
- }) ? rootPackageManager.type === "npm" ? await rootPackageManager.dedupeDependencies({ force: !0 }) : await rootPackageManager.dedupeDependencies() : logger23.log(
10061
+ }) ? rootPackageManager.type === "npm" ? await rootPackageManager.dedupeDependencies({ force: !0 }) : await rootPackageManager.dedupeDependencies() : logger24.log(
10747
10062
  `If you find any issues running Storybook, you can run ${rootPackageManager.getRunCommand("dedupe")} manually to deduplicate your dependencies and try again.`
10748
10063
  ));
10749
10064
  let doctorProjects = storybookProjects.map((project) => ({
@@ -10752,7 +10067,7 @@ Upgrade interrupted by user.`), allProjects.length > 1 && await sendMultiUpgrade
10752
10067
  storybookVersion: project.currentCLIVersion,
10753
10068
  mainConfig: project.mainConfig
10754
10069
  }));
10755
- logger23.step("Checking the health of your project(s).."), doctorResults = await runMultiProjectDoctor(doctorProjects), displayDoctorResults(doctorResults) && logTracker3.enableLogWriting(), logUpgradeResults(automigrationResults2, detectedAutomigrations, doctorResults);
10070
+ logger24.step("Checking the health of your project(s).."), doctorResults = await runMultiProjectDoctor(doctorProjects), displayDoctorResults(doctorResults) && logTracker3.enableLogWriting(), logUpgradeResults(automigrationResults2, detectedAutomigrations, doctorResults);
10756
10071
  for (let project of storybookProjects) {
10757
10072
  let resultData = automigrationResults2[project.configDir] || {
10758
10073
  automigrationStatuses: {},
@@ -10788,13 +10103,13 @@ Upgrade interrupted by user.`), allProjects.length > 1 && await sendMultiUpgrade
10788
10103
  // src/bin/run.ts
10789
10104
  addToGlobalContext("cliVersion", versions5.storybook);
10790
10105
  var handleCommandFailure = (logFilePath) => async (error) => {
10791
- error instanceof HandledError3 || logger24.error(String(error));
10106
+ error instanceof HandledError3 || logger25.error(String(error));
10792
10107
  try {
10793
10108
  let logFile = await logTracker4.writeToFile(logFilePath);
10794
- logger24.log(`Debug logs are written to: ${logFile}`);
10109
+ logger25.log(`Debug logs are written to: ${logFile}`);
10795
10110
  } catch {
10796
10111
  }
10797
- logger24.outro(""), process.exit(1);
10112
+ logger25.outro(""), process.exit(1);
10798
10113
  }, command = (name) => program.command(name).option(
10799
10114
  "--disable-telemetry",
10800
10115
  "Disable sending telemetry data",
@@ -10804,21 +10119,21 @@ var handleCommandFailure = (logFilePath) => async (error) => {
10804
10119
  "Write all debug logs to the specified file at the end of the run. Defaults to debug-storybook.log when [path] is not provided"
10805
10120
  ).option("--loglevel <trace | debug | info | warn | error | silent>", "Define log level", "info").hook("preAction", async (self2) => {
10806
10121
  let options = self2.opts();
10807
- options.debug && logger24.setLogLevel("debug"), options.loglevel && logger24.setLogLevel(options.loglevel), options.logfile && logTracker4.enableLogWriting();
10122
+ options.debug && logger25.setLogLevel("debug"), options.loglevel && logger25.setLogLevel(options.loglevel), options.logfile && logTracker4.enableLogWriting();
10808
10123
  try {
10809
10124
  await globalSettings();
10810
10125
  } catch (e) {
10811
- logger24.error(`Error loading global settings:
10126
+ logger25.error(`Error loading global settings:
10812
10127
  ` + String(e));
10813
10128
  }
10814
10129
  }).hook("postAction", async (command2) => {
10815
10130
  if (logTracker4.shouldWriteLogsToFile) {
10816
10131
  try {
10817
10132
  let logFile = await logTracker4.writeToFile(command2.getOptionValue("logfile"));
10818
- logger24.log(`Debug logs are written to: ${logFile}`);
10133
+ logger25.log(`Debug logs are written to: ${logFile}`);
10819
10134
  } catch {
10820
10135
  }
10821
- logger24.outro(CLI_COLORS5.success("Done!"));
10136
+ logger25.outro(CLI_COLORS5.success("Done!"));
10822
10137
  }
10823
10138
  });
10824
10139
  command("init").description("Initialize Storybook into your project").option("-f --force", "Force add Storybook").option("-s --skip-install", "Skip installing deps").addOption(
@@ -10835,7 +10150,7 @@ command("add <addon>").description("Add an addon to your Storybook").addOption(
10835
10150
  )
10836
10151
  ).option("-c, --config-dir <dir-name>", "Directory where to load Storybook configurations from").option("--skip-install", "Skip installing deps").option("-s --skip-postinstall", "Skip package specific postinstall config modifications").option("-y --yes", "Skip prompting the user").option("--skip-doctor", "Skip doctor check").action((addonName, options) => {
10837
10152
  withTelemetry("add", { cliOptions: options }, async () => {
10838
- logger24.intro(`Setting up your project for ${addonName}`), await add(addonName, options), await telemetry3("add", { addon: addonName, source: "cli" }), logger24.outro("Done!");
10153
+ logger25.intro(`Setting up your project for ${addonName}`), await add(addonName, options), await telemetry3("add", { addon: addonName, source: "cli" }), logger25.outro("Done!");
10839
10154
  }).catch(handleCommandFailure);
10840
10155
  });
10841
10156
  command("remove <addon>").description("Remove an addon from your Storybook").addOption(
@@ -10844,7 +10159,7 @@ command("remove <addon>").description("Remove an addon from your Storybook").add
10844
10159
  )
10845
10160
  ).option("-c, --config-dir <dir-name>", "Directory where to load Storybook configurations from").option("-s --skip-install", "Skip installing deps").action(
10846
10161
  (addonName, options) => withTelemetry("remove", { cliOptions: options }, async () => {
10847
- logger24.intro(`Removing ${addonName} from your Storybook`);
10162
+ logger25.intro(`Removing ${addonName} from your Storybook`);
10848
10163
  let packageManager = JsPackageManagerFactory3.getPackageManager({
10849
10164
  configDir: options.configDir,
10850
10165
  force: options.packageManager
@@ -10853,7 +10168,7 @@ command("remove <addon>").description("Remove an addon from your Storybook").add
10853
10168
  configDir: options.configDir,
10854
10169
  packageManager,
10855
10170
  skipInstall: options.skipInstall
10856
- }), await telemetry3("remove", { addon: addonName, source: "cli" }), logger24.outro("Done!");
10171
+ }), await telemetry3("remove", { addon: addonName, source: "cli" }), logger25.outro("Done!");
10857
10172
  }).catch(handleCommandFailure(options.logfile))
10858
10173
  );
10859
10174
  command("upgrade").description(`Upgrade your Storybook packages to v${versions5.storybook}`).addOption(
@@ -10871,12 +10186,12 @@ command("upgrade").description(`Upgrade your Storybook packages to v${versions5.
10871
10186
  "upgrade",
10872
10187
  { cliOptions: { ...options, configDir: options.configDir?.[0] } },
10873
10188
  async () => {
10874
- logger24.intro(`Storybook upgrade - v${versions5.storybook}`), await upgrade(options), logger24.outro("Storybook upgrade completed!");
10189
+ logger25.intro(`Storybook upgrade - v${versions5.storybook}`), await upgrade(options), logger25.outro("Storybook upgrade completed!");
10875
10190
  }
10876
10191
  ).catch(handleCommandFailure(options.logfile));
10877
10192
  });
10878
10193
  command("info").description("Prints debugging information about the local environment").action(async () => {
10879
- logger24.log(import_picocolors17.default.bold(`
10194
+ logger25.log(import_picocolors17.default.bold(`
10880
10195
  Storybook Environment Info:`));
10881
10196
  let activePackageManager = JsPackageManagerFactory3.getPackageManager().type.replace(/\d/, ""), output = await import_envinfo.default.run({
10882
10197
  System: ["OS", "CPU", "Shell"],
@@ -10885,7 +10200,7 @@ Storybook Environment Info:`));
10885
10200
  npmPackages: "{@storybook/*,*storybook*,sb,chromatic}",
10886
10201
  npmGlobalPackages: "{@storybook/*,*storybook*,sb,chromatic}"
10887
10202
  }), activePackageManagerLine = output.match(new RegExp(`${activePackageManager}:.*`, "i"));
10888
- logger24.log(
10203
+ logger25.log(
10889
10204
  output.replace(
10890
10205
  activePackageManagerLine,
10891
10206
  import_picocolors17.default.bold(`${activePackageManagerLine} <----- active`)
@@ -10900,12 +10215,12 @@ command("migrate [migration]").description("Run a Storybook codemod migration on
10900
10215
  'Rename suffix of matching files after codemod has been applied, e.g. ".js:.ts"'
10901
10216
  ).action((migration, options) => {
10902
10217
  withTelemetry("migrate", { cliOptions: options }, async () => {
10903
- logger24.intro(`Running ${migration} migration`), await migrate(migration, options), logger24.outro("Migration completed");
10218
+ logger25.intro(`Running ${migration} migration`), await migrate(migration, options), logger25.outro("Migration completed");
10904
10219
  }).catch(handleCommandFailure(options.logfile));
10905
10220
  });
10906
10221
  command("sandbox [filterValue]").alias("repro").description("Create a sandbox from a set of possible templates").option("-o --output <outDir>", "Define an output directory").option("--no-init", "Whether to download a template without an initialized Storybook", !1).action((filterValue, options) => {
10907
- logger24.intro("Creating a Storybook sandbox..."), sandbox({ filterValue, ...options }).catch(handleCommandFailure).finally(() => {
10908
- logger24.outro("Done!");
10222
+ logger25.intro("Creating a Storybook sandbox..."), sandbox({ filterValue, ...options }).catch(handleCommandFailure).finally(() => {
10223
+ logger25.outro("Done!");
10909
10224
  });
10910
10225
  });
10911
10226
  command("link <repo-url-or-directory>").description("Pull down a repro from a URL (or a local directory), link it, and run storybook").option("--local", "Link a local directory already in your file system").option("--no-start", "Start the storybook", !0).action(
@@ -10920,7 +10235,7 @@ command("automigrate [fixId]").description("Check storybook for incompatibilitie
10920
10235
  "The renderer package for the framework Storybook is using."
10921
10236
  ).option("--skip-doctor", "Skip doctor check").option("--glob <pattern>", "Glob pattern for story files (for csf-factories codemod)").action(async (fixId, options) => {
10922
10237
  withTelemetry("automigrate", { cliOptions: options }, async () => {
10923
- logger24.intro(fixId ? `Running ${fixId} automigration` : "Running automigrations"), await doAutomigrate({ fixId, ...options }), logger24.outro("Done");
10238
+ logger25.intro(fixId ? `Running ${fixId} automigration` : "Running automigrations"), await doAutomigrate({ fixId, ...options }), logger25.outro("Done");
10924
10239
  }).catch(handleCommandFailure(options.logfile));
10925
10240
  });
10926
10241
  command("doctor").description("Check Storybook for known problems and provide suggestions or fixes").addOption(
@@ -10929,7 +10244,7 @@ command("doctor").description("Check Storybook for known problems and provide su
10929
10244
  )
10930
10245
  ).option("-c, --config-dir <dir-name>", "Directory of Storybook configuration").action(async (options) => {
10931
10246
  withTelemetry("doctor", { cliOptions: options }, async () => {
10932
- logger24.intro("Doctoring Storybook"), await doctor(options), logger24.outro("Done");
10247
+ logger25.intro("Doctoring Storybook"), await doctor(options), logger25.outro("Done");
10933
10248
  }).catch(handleCommandFailure(options.logfile));
10934
10249
  });
10935
10250
  var aiCommand = command("ai").description("AI agent helpers for Storybook").option(
@@ -10953,6 +10268,6 @@ program.on("command:*", ([invalidCmd]) => {
10953
10268
  let errorMessage = ` Invalid command: ${import_picocolors17.default.bold(invalidCmd)}.
10954
10269
  See --help for a list of available commands.`, suggestion = program.commands.map((cmd) => cmd.name()).find((cmd) => leven(cmd, invalidCmd) < 3);
10955
10270
  suggestion && (errorMessage += `
10956
- Did you mean ${import_picocolors17.default.yellow(suggestion)}?`), logger24.error(errorMessage), process.exit(1);
10271
+ Did you mean ${import_picocolors17.default.yellow(suggestion)}?`), logger25.error(errorMessage), process.exit(1);
10957
10272
  });
10958
10273
  program.usage("<command> [options]").version(String(version)).parse(process.argv);