react-doctor 0.8.1-dev.0b0b5ac → 0.8.1-dev.1839566

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.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a9af63ed-7b82-56d3-8549-274ab7f23579")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c24708ed-97a3-59cc-81f7-4cf277ab29f2")}catch(e){}}();
3
3
  import { createRequire } from "node:module";
4
4
  import * as NodeChildProcess from "node:child_process";
5
5
  import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
@@ -36571,10 +36571,10 @@ const FALLBACK_TSCONFIG_FILENAMES = ["tsconfig.app.json", "tsconfig.build.json"]
36571
36571
  const FRAMEWORK_PACKAGES = {
36572
36572
  next: "nextjs",
36573
36573
  "@tanstack/react-start": "tanstack-start",
36574
- "@remix-run/react": "remix",
36575
- gatsby: "gatsby",
36576
36574
  vite: "vite",
36577
36575
  "react-scripts": "cra",
36576
+ "@remix-run/react": "remix",
36577
+ gatsby: "gatsby",
36578
36578
  expo: "expo",
36579
36579
  "react-native": "react-native"
36580
36580
  };
@@ -36598,17 +36598,11 @@ const NEXT_CONFIG_FILENAMES = [
36598
36598
  ];
36599
36599
  const BABEL_CONFIG_FILENAMES = [
36600
36600
  ".babelrc",
36601
- ".babelrc.js",
36602
36601
  ".babelrc.json",
36603
- ".babelrc.cjs",
36604
- ".babelrc.mjs",
36605
- ".babelrc.cts",
36606
36602
  "babel.config.js",
36607
36603
  "babel.config.json",
36608
36604
  "babel.config.cjs",
36609
- "babel.config.mjs",
36610
- "babel.config.ts",
36611
- "babel.config.cts"
36605
+ "babel.config.mjs"
36612
36606
  ];
36613
36607
  const VITE_CONFIG_FILENAMES = [
36614
36608
  "vite.config.js",
@@ -36620,28 +36614,12 @@ const VITE_CONFIG_FILENAMES = [
36620
36614
  "vitest.config.ts",
36621
36615
  "vitest.config.js"
36622
36616
  ];
36623
- const RSBUILD_CONFIG_FILENAMES = [
36624
- "rsbuild.config.ts",
36625
- "rsbuild.config.js",
36626
- "rsbuild.config.mts",
36627
- "rsbuild.config.mjs",
36628
- "rsbuild.config.cts",
36629
- "rsbuild.config.cjs"
36630
- ];
36631
- const RSPACK_CONFIG_FILENAMES = [
36632
- "rspack.config.ts",
36633
- "rspack.config.js",
36634
- "rspack.config.mts",
36635
- "rspack.config.mjs",
36636
- "rspack.config.cts",
36637
- "rspack.config.cjs"
36638
- ];
36639
36617
  const EXPO_APP_CONFIG_FILENAMES = [
36640
36618
  "app.json",
36641
36619
  "app.config.js",
36642
36620
  "app.config.ts"
36643
36621
  ];
36644
- const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|reactCompilerPreset\s*\(|["']react-compiler["']/;
36622
+ const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|["']react-compiler["']/;
36645
36623
  const REACT_COMPILER_ENABLED_FLAG_PATTERN = /["']?reactCompiler["']?\s*:\s*(?:true\b|\{)/;
36646
36624
  const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
36647
36625
  const hasCompilerPackage = (packageJson, compilerPackages) => {
@@ -36676,8 +36654,6 @@ const detectReactCompiler = (directory, packageJson) => {
36676
36654
  if (hasCompilerInConfigFiles(directory, NEXT_CONFIG_FILENAMES)) return true;
36677
36655
  if (hasCompilerInConfigFiles(directory, BABEL_CONFIG_FILENAMES)) return true;
36678
36656
  if (hasCompilerInConfigFiles(directory, VITE_CONFIG_FILENAMES)) return true;
36679
- if (hasCompilerInConfigFiles(directory, RSBUILD_CONFIG_FILENAMES)) return true;
36680
- if (hasCompilerInConfigFiles(directory, RSPACK_CONFIG_FILENAMES)) return true;
36681
36657
  if (hasCompilerInConfigFiles(directory, EXPO_APP_CONFIG_FILENAMES)) return true;
36682
36658
  return hasCompilerPackageInAncestors(directory, REACT_COMPILER_TRANSFORM_PACKAGES);
36683
36659
  };
@@ -37125,6 +37101,19 @@ const getPreactVersion = (packageJson) => {
37125
37101
  ...packageJson.devDependencies
37126
37102
  }.preact ?? null;
37127
37103
  };
37104
+ const TANSTACK_QUERY_PACKAGES = new Set([
37105
+ "@tanstack/react-query",
37106
+ "@tanstack/query-core",
37107
+ "react-query"
37108
+ ]);
37109
+ const hasTanStackQuery = (packageJson) => {
37110
+ const allDependencies = {
37111
+ ...packageJson.peerDependencies,
37112
+ ...packageJson.dependencies,
37113
+ ...packageJson.devDependencies
37114
+ };
37115
+ return Object.keys(allDependencies).some((packageName) => TANSTACK_QUERY_PACKAGES.has(packageName));
37116
+ };
37128
37117
  const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
37129
37118
  if (version === null || !isCatalogReference(version)) return version;
37130
37119
  const catalogName = extractCatalogName(version);
@@ -37327,60 +37316,7 @@ const listWorkspacePackages = (rootDirectory) => {
37327
37316
  }
37328
37317
  return packages;
37329
37318
  };
37330
- const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
37331
- const allDependencies = {
37332
- ...packageJson.devDependencies,
37333
- ...packageJson.peerDependencies,
37334
- ...packageJson.dependencies
37335
- };
37336
- for (const packageName of packageNames) {
37337
- const version = allDependencies[packageName];
37338
- if (version !== void 0) return version;
37339
- }
37340
- return null;
37341
- };
37342
- const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
37343
- const getTanStackQueryVersion = (packageJson) => {
37344
- return getPreferredDependencyVersion({
37345
- packageJson,
37346
- packageNames: TANSTACK_REACT_QUERY_PACKAGES
37347
- });
37348
- };
37349
- const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
37350
- const getStyledComponentsVersion = (packageJson) => {
37351
- return getPreferredDependencyVersion({
37352
- packageJson,
37353
- packageNames: STYLED_COMPONENTS_PACKAGES
37354
- });
37355
- };
37356
- const I18N_PACKAGES = [
37357
- "i18next",
37358
- "react-i18next",
37359
- "next-i18next",
37360
- "react-intl",
37361
- "next-intl",
37362
- "use-intl",
37363
- "@formatjs/intl",
37364
- "@lingui/core",
37365
- "@lingui/react",
37366
- "typesafe-i18n",
37367
- "@tolgee/react",
37368
- "react-intl-universal"
37369
- ];
37370
- const hasI18nDependency = (packageJson) => {
37371
- const allDependencies = {
37372
- ...packageJson.peerDependencies,
37373
- ...packageJson.dependencies,
37374
- ...packageJson.devDependencies,
37375
- ...packageJson.optionalDependencies
37376
- };
37377
- return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
37378
- };
37379
37319
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
37380
- const MOBX_REACT_PACKAGE_NAME = "mobx-react";
37381
- const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
37382
- const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
37383
- const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
37384
37320
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
37385
37321
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
37386
37322
  const dependencyDeclaration = getDependencyDeclaration({
@@ -37399,26 +37335,7 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
37399
37335
  if (nextMajor === null) return false;
37400
37336
  return nextMajor < currentMajor;
37401
37337
  };
37402
- const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
37403
- if (currentFact.version === null) return true;
37404
- if (nextFact.version === null) return false;
37405
- const currentMajor = getLowestDependencyMajor(currentFact.version);
37406
- const nextMajor = getLowestDependencyMajor(nextFact.version);
37407
- if (currentMajor === null) return false;
37408
- if (nextMajor === null) return true;
37409
- if (currentMajor > latestSupportedMajor) return false;
37410
- if (nextMajor > latestSupportedMajor) return true;
37411
- return nextMajor < currentMajor;
37412
- };
37413
- const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
37414
- if (!currentVersion) return true;
37415
- const currentMajor = getLowestDependencyMajor(currentVersion);
37416
- const nextMajor = getLowestDependencyMajor(nextVersion);
37417
- if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
37418
- if (nextMajor === null) return currentMajor >= 6;
37419
- return nextMajor < currentMajor;
37420
- };
37421
- const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
37338
+ const evaluateManifestFacts = (facts, packageJson, directory) => {
37422
37339
  if (facts.expo.version === null) {
37423
37340
  const spec = getDependencySpec(packageJson, "expo");
37424
37341
  if (spec !== null) facts.expo = {
@@ -37440,74 +37357,13 @@ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, roo
37440
37357
  sourceDirectory: directory
37441
37358
  };
37442
37359
  }
37443
- const mobxSpec = getDependencySpec(packageJson, "mobx");
37444
- if (mobxSpec !== null) {
37445
- const nextMobxFact = {
37446
- version: resolveCatalogBackedDependencyVersion({
37447
- rootDirectory: directory,
37448
- rootPackageJson: packageJson,
37449
- packageName: "mobx",
37450
- version: mobxSpec
37451
- }),
37452
- sourceDirectory: directory
37453
- };
37454
- if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
37455
- }
37456
- facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
37457
- facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
37458
- facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
37459
- facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
37460
- const zustandSpec = getDependencySpec(packageJson, "zustand");
37461
- if (zustandSpec !== null) {
37462
- const nextZustandFact = {
37463
- version: resolveCatalogBackedDependencyVersion({
37464
- rootDirectory: directory,
37465
- rootPackageJson: packageJson,
37466
- packageName: "zustand",
37467
- version: zustandSpec
37468
- }),
37469
- sourceDirectory: directory
37470
- };
37471
- if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
37472
- }
37473
37360
  if (facts.reanimatedVersion === null) {
37474
37361
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
37475
37362
  if (spec !== null) facts.reanimatedVersion = spec;
37476
37363
  }
37477
- if (facts.valtioVersion === null) {
37478
- const spec = getDependencySpec(packageJson, "valtio");
37479
- if (spec !== null) facts.valtioVersion = spec;
37480
- }
37481
- facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
37482
- const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
37483
- rootDirectory: directory,
37484
- rootPackageJson: packageJson,
37485
- packageName: "styled-components",
37486
- version: getStyledComponentsVersion(packageJson)
37487
- });
37488
- if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
37489
- facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
37490
37364
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
37491
37365
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
37492
37366
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
37493
- const remotionSpec = getDependencySpec(packageJson, "remotion");
37494
- if (remotionSpec !== null) {
37495
- facts.hasRemotionDependency = true;
37496
- const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
37497
- rootDirectory,
37498
- rootPackageJson,
37499
- packageName: "remotion",
37500
- version: remotionSpec
37501
- });
37502
- const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
37503
- if (remotionMajorVersion === null) {
37504
- facts.hasUnknownRemotionVersion = true;
37505
- facts.remotionVersion = null;
37506
- } else if (!facts.hasUnknownRemotionVersion) {
37507
- const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
37508
- if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
37509
- }
37510
- }
37511
37367
  };
37512
37368
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
37513
37369
  const facts = {
@@ -37527,31 +37383,12 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
37527
37383
  version: null,
37528
37384
  sourceDirectory: null
37529
37385
  },
37530
- valtioVersion: null,
37531
- mobx: {
37532
- version: null,
37533
- sourceDirectory: null
37534
- },
37535
- hasMobxReact: false,
37536
- hasMobxReactLite: false,
37537
- hasMobxStateTree: false,
37538
- hasMobxReactObserver: false,
37539
- zustand: {
37540
- version: null,
37541
- sourceDirectory: null
37542
- },
37543
- tanstackQueryVersion: null,
37544
- styledComponentsVersion: null,
37545
- hasI18nLibrary: false,
37546
37386
  hasReactNativeAwarePackage: false,
37547
37387
  hasReanimatedAwarePackage: false,
37548
37388
  hasSsrDependency: false,
37549
- hasRemotionDependency: false,
37550
- hasUnknownRemotionVersion: false,
37551
- remotionVersion: null,
37552
37389
  reanimatedVersion: null
37553
37390
  };
37554
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
37391
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
37555
37392
  let isReactGroupSettled = !collectReactGroup;
37556
37393
  const visitedDirectories = /* @__PURE__ */ new Set();
37557
37394
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -37560,7 +37397,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
37560
37397
  if (visitedDirectories.has(workspaceDirectory)) continue;
37561
37398
  visitedDirectories.add(workspaceDirectory);
37562
37399
  const workspacePackageJson = readPackageJson$1(Path.join(workspaceDirectory, "package.json"));
37563
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
37400
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
37564
37401
  const info = extractDependencyInfo(workspacePackageJson);
37565
37402
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
37566
37403
  if (isReactGroupSettled) continue;
@@ -37781,27 +37618,11 @@ const discoverProjectWithoutPackageJson = (directory) => {
37781
37618
  tailwindVersion: null,
37782
37619
  zodVersion: null,
37783
37620
  zodMajorVersion: null,
37784
- mobxVersion: null,
37785
- mobxMajorVersion: null,
37786
- hasMobxReact: false,
37787
- hasMobxReactLite: false,
37788
- hasMobxStateTree: false,
37789
- hasMobxReactObserver: false,
37790
- zustandVersion: null,
37791
- zustandMajorVersion: null,
37792
37621
  framework: "unknown",
37793
37622
  hasTypeScript: hasOwnTsConfig,
37794
37623
  hasReactCompiler: false,
37795
37624
  hasReactCompilerLintPlugin: false,
37796
37625
  hasTanStackQuery: false,
37797
- valtioVersion: null,
37798
- valtioMajorVersion: null,
37799
- hasRemotion: false,
37800
- remotionVersion: null,
37801
- remotionMajorVersion: null,
37802
- hasI18nLibrary: false,
37803
- tanstackQueryVersion: null,
37804
- styledComponentsVersion: null,
37805
37626
  hasSsrDependency: false,
37806
37627
  preactVersion: null,
37807
37628
  preactMajorVersion: null,
@@ -37900,12 +37721,6 @@ const discoverProject = (directory) => {
37900
37721
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
37901
37722
  version: workspaceFacts.shopifyFlashList.version
37902
37723
  }) : null;
37903
- const zustandVersion = resolveCatalogBackedDependencyVersion({
37904
- rootDirectory: directory,
37905
- rootPackageJson: packageJson,
37906
- packageName: "zustand",
37907
- version: workspaceFacts.zustand.version
37908
- });
37909
37724
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
37910
37725
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
37911
37726
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -37914,21 +37729,7 @@ const discoverProject = (directory) => {
37914
37729
  packageName: "next",
37915
37730
  version: workspaceFacts.next.version
37916
37731
  }) : null;
37917
- const valtioVersion = resolveCatalogBackedDependencyVersion({
37918
- rootDirectory: directory,
37919
- rootPackageJson: packageJson,
37920
- packageName: "valtio",
37921
- version: workspaceFacts.valtioVersion
37922
- });
37923
- const mobxVersion = resolveCatalogBackedDependencyVersion({
37924
- rootDirectory: directory,
37925
- rootPackageJson: packageJson,
37926
- packageName: "mobx",
37927
- version: workspaceFacts.mobx.version
37928
- });
37929
37732
  const preactVersion = getPreactVersion(packageJson);
37930
- const remotionVersion = workspaceFacts.remotionVersion;
37931
- const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
37932
37733
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
37933
37734
  const projectInfo = {
37934
37735
  rootDirectory: directory,
@@ -37938,27 +37739,11 @@ const discoverProject = (directory) => {
37938
37739
  tailwindVersion,
37939
37740
  zodVersion,
37940
37741
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
37941
- mobxVersion,
37942
- mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
37943
- hasMobxReact: workspaceFacts.hasMobxReact,
37944
- hasMobxReactLite: workspaceFacts.hasMobxReactLite,
37945
- hasMobxStateTree: workspaceFacts.hasMobxStateTree,
37946
- hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
37947
- zustandVersion,
37948
- zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
37949
37742
  framework,
37950
37743
  hasTypeScript,
37951
37744
  hasReactCompiler: detectReactCompiler(directory, packageJson),
37952
37745
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
37953
- hasTanStackQuery: tanstackQueryVersion !== null,
37954
- hasI18nLibrary: workspaceFacts.hasI18nLibrary,
37955
- tanstackQueryVersion,
37956
- styledComponentsVersion: workspaceFacts.styledComponentsVersion,
37957
- valtioVersion,
37958
- valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
37959
- hasRemotion: workspaceFacts.hasRemotionDependency,
37960
- remotionVersion,
37961
- remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
37746
+ hasTanStackQuery: hasTanStackQuery(packageJson),
37962
37747
  hasSsrDependency: workspaceFacts.hasSsrDependency,
37963
37748
  preactVersion,
37964
37749
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -38192,6 +37977,7 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
38192
37977
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
38193
37978
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
38194
37979
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
37980
+ "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
38195
37981
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
38196
37982
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
38197
37983
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -40513,25 +40299,9 @@ const BABEL_CONFIG_FILE_NAMES = [
40513
40299
  ".babelrc.json"
40514
40300
  ];
40515
40301
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
40516
- const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
40517
- const REACT_NATIVE_PACKAGE = "react-native";
40518
- const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
40519
- const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
40520
40302
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
40521
40303
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
40522
- const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
40523
- const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
40524
- const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson$1(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
40525
- if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
40526
- const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
40527
- if (normalizedVersionRange === null) return false;
40528
- const minimumVersion = import_semver.minVersion(normalizedVersionRange);
40529
- return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
40530
- };
40531
- const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
40532
40304
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
40533
- const packageJson = readPackageJson$1(Path.join(rootDirectory, "package.json"));
40534
- const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
40535
40305
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
40536
40306
  const filePath = Path.join(rootDirectory, fileName);
40537
40307
  if (!isFile(filePath)) continue;
@@ -40541,7 +40311,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
40541
40311
  } catch {
40542
40312
  continue;
40543
40313
  }
40544
- if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
40314
+ if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
40545
40315
  filePath: fileName,
40546
40316
  rule: "rn-no-metro-babel-preset",
40547
40317
  severity: "error",
@@ -40564,6 +40334,12 @@ const checkReactNativeProject = (rootDirectory, project) => {
40564
40334
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
40565
40335
  };
40566
40336
  const RULE_KEY = "no-vulnerable-react-server-components";
40337
+ const DEPENDENCY_SECTIONS = [
40338
+ "dependencies",
40339
+ "devDependencies",
40340
+ "peerDependencies",
40341
+ "optionalDependencies"
40342
+ ];
40567
40343
  const REACT_RSC_ADVISORIES_BY_MINOR = {
40568
40344
  "19.0": {
40569
40345
  rceFixedVersion: "19.0.1",
@@ -40610,13 +40386,20 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
40610
40386
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
40611
40387
  return [...directories];
40612
40388
  };
40389
+ const readDeclaredSpec = (packageJson, packageName) => {
40390
+ for (const section of DEPENDENCY_SECTIONS) {
40391
+ const spec = packageJson[section]?.[packageName];
40392
+ if (typeof spec === "string") return spec;
40393
+ }
40394
+ return null;
40395
+ };
40613
40396
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
40614
40397
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
40615
40398
  if (isFile(manifestPath)) {
40616
40399
  const installedVersion = import_semver.valid(readPackageJson$1(manifestPath).version ?? null);
40617
40400
  if (installedVersion !== null) return installedVersion;
40618
40401
  }
40619
- const candidateSpecs = [getDependencySpec(readPackageJson$1(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
40402
+ const candidateSpecs = [readDeclaredSpec(readPackageJson$1(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
40620
40403
  for (const spec of candidateSpecs) {
40621
40404
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
40622
40405
  if (pinnedVersion !== null) return pinnedVersion;
@@ -41284,50 +41067,21 @@ const buildCapabilities = (project) => {
41284
41067
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
41285
41068
  if (project.isStaticExport) capabilities.add("nextjs:static-export");
41286
41069
  if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
41287
- if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
41288
41070
  addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
41289
41071
  if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
41290
41072
  major: 19,
41291
41073
  minor: 2
41292
41074
  })) capabilities.add("react:19.2");
41293
- if (project.tailwindVersion !== null) {
41294
- capabilities.add("tailwind");
41295
- const tailwindVersion = parseTailwindMajorMinor(project.tailwindVersion);
41296
- if (isMajorMinorAtLeast(tailwindVersion, {
41297
- major: 3,
41298
- minor: 4
41299
- })) capabilities.add("tailwind:3.4");
41300
- if (tailwindVersion !== null && isMajorMinorAtLeast(tailwindVersion, {
41301
- major: 4,
41302
- minor: 0
41303
- })) capabilities.add("tailwind:4");
41304
- }
41075
+ if (project.tailwindVersion !== null) capabilities.add("tailwind");
41076
+ if (project.tailwindVersion !== null && isMajorMinorAtLeast(parseTailwindMajorMinor(project.tailwindVersion), {
41077
+ major: 3,
41078
+ minor: 4
41079
+ })) capabilities.add("tailwind:3.4");
41305
41080
  if (project.zodVersion !== null) capabilities.add("zod");
41306
41081
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
41307
- if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
41308
- if (project.hasMobxReact === true) capabilities.add("mobx-react");
41309
- if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
41310
- if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
41311
- if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
41312
- if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
41313
- if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
41314
- if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
41315
- if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
41316
41082
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
41317
41083
  if (project.hasReactCompiler) capabilities.add("react-compiler");
41318
- if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
41319
- if (project.styledComponentsVersion) {
41320
- capabilities.add("styled-components");
41321
- const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
41322
- if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
41323
- }
41324
- if (project.hasI18nLibrary) capabilities.add("i18n");
41325
- if (project.valtioVersion !== null) capabilities.add("valtio");
41326
- addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
41327
- if (project.hasRemotion) {
41328
- capabilities.add("remotion");
41329
- addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
41330
- }
41084
+ if (project.hasTanStackQuery) capabilities.add("tanstack-query");
41331
41085
  if (project.hasTypeScript) capabilities.add("typescript");
41332
41086
  if (project.preactVersion !== null) capabilities.add("preact");
41333
41087
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -41342,7 +41096,7 @@ const getCapabilities = (project) => {
41342
41096
  capabilitiesByProject.set(project, capabilities);
41343
41097
  return capabilities;
41344
41098
  };
41345
- const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen, includedTags) => {
41099
+ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen) => {
41346
41100
  if (requires) {
41347
41101
  for (const capability of requires) if (!capabilities.has(capability)) return false;
41348
41102
  }
@@ -41353,29 +41107,20 @@ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhe
41353
41107
  if (tags) {
41354
41108
  for (const tag of tags) if (ignoredTags.has(tag)) return false;
41355
41109
  }
41356
- if (includedTags && includedTags.size > 0) {
41357
- if (!tags?.some((tag) => includedTags.has(tag))) return false;
41358
- }
41359
41110
  return true;
41360
41111
  };
41361
- const shouldEnableRuleByDefaultStatus = (options) => options.defaultEnabled !== false || options.hasExplicitOverride === true || options.includeTagDefaults && options.hasIncludedTags;
41362
41112
  const yieldToEventLoop = () => new Promise((resolve) => {
41363
41113
  setImmediate(resolve);
41364
41114
  });
41365
41115
  const createSecurityScanSession = (rootDirectory, options) => {
41366
41116
  const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
41367
41117
  const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
41368
- const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
41369
41118
  const enabledScanRules = REACT_DOCTOR_RULES.flatMap((entry) => {
41370
41119
  const rule = entry.rule;
41371
41120
  const scan = rule.scan;
41372
41121
  if (typeof scan !== "function") return [];
41373
- if (!shouldEnableRuleByDefaultStatus({
41374
- defaultEnabled: rule.defaultEnabled,
41375
- includeTagDefaults: options.includeTagDefaults === true,
41376
- hasIncludedTags: includedTags.size > 0
41377
- })) return [];
41378
- if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) return [];
41122
+ if (rule.defaultEnabled === false) return [];
41123
+ if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) return [];
41379
41124
  return [{
41380
41125
  entry,
41381
41126
  scan,
@@ -43377,9 +43122,8 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
43377
43122
  }
43378
43123
  return enabled;
43379
43124
  };
43380
- const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
43381
- const hasIncludedTags = includedTags.size > 0;
43382
- const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
43125
+ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
43126
+ const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
43383
43127
  const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
43384
43128
  const jsPlugins = [];
43385
43129
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
@@ -43394,14 +43138,9 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
43394
43138
  if (rule.scan !== void 0) continue;
43395
43139
  if (customRulesOnly && registryEntry.originallyExternal) continue;
43396
43140
  if (rule.framework !== "global" && !rule.requires) continue;
43397
- if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
43141
+ if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) continue;
43398
43142
  const explicitRuleOverride = resolveRuleSeverityOverride({ ruleKey: registryEntry.key }, severityControls);
43399
- if (!shouldEnableRuleByDefaultStatus({
43400
- defaultEnabled: rule.defaultEnabled,
43401
- includeTagDefaults,
43402
- hasIncludedTags,
43403
- hasExplicitOverride: explicitRuleOverride !== void 0
43404
- })) continue;
43143
+ if (rule.defaultEnabled === false && explicitRuleOverride === void 0) continue;
43405
43144
  const severity = resolveRuleSeverityOverride({
43406
43145
  ruleKey: registryEntry.key,
43407
43146
  category: rule.category
@@ -43410,7 +43149,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
43410
43149
  enabledReactDoctorRules[registryEntry.key] = severity;
43411
43150
  }
43412
43151
  const userPluginRules = {};
43413
- if (ruleSelection !== "sidecar" && !hasIncludedTags) for (const userPlugin of userPlugins) {
43152
+ if (ruleSelection !== "sidecar") for (const userPlugin of userPlugins) {
43414
43153
  Object.assign(userPluginRules, buildUserPluginRules(userPlugin, severityControls));
43415
43154
  jsPlugins.push(userPlugin.entry);
43416
43155
  }
@@ -43627,19 +43366,6 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
43627
43366
  }
43628
43367
  };
43629
43368
  };
43630
- const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
43631
- const fingerprintFileContents = (filePath, fingerprintLength) => {
43632
- const fileStats = NFS.statSync(filePath, { bigint: true });
43633
- const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
43634
- if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
43635
- const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
43636
- fingerprintCacheByFilePath.set(filePath, {
43637
- fingerprint,
43638
- modifiedTimeNanoseconds: fileStats.mtimeNs,
43639
- sizeBytes: fileStats.size
43640
- });
43641
- return fingerprint;
43642
- };
43643
43369
  const bundledRequire$3 = createRequire(import.meta.url);
43644
43370
  const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
43645
43371
  const resolveChildNodeVersion = (nodeBinaryPath) => {
@@ -43663,13 +43389,6 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS$1 = [
43663
43389
  "oxlint-plugin-react-doctor/package.json",
43664
43390
  "eslint-plugin-react-hooks/package.json"
43665
43391
  ];
43666
- const resolvePluginFingerprint = () => {
43667
- try {
43668
- return fingerprintFileContents(bundledRequire$3.resolve("oxlint-plugin-react-doctor"), 16);
43669
- } catch {
43670
- return "unresolved";
43671
- }
43672
- };
43673
43392
  const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
43674
43393
  const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
43675
43394
  for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS$1) try {
@@ -43679,7 +43398,6 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
43679
43398
  } catch {
43680
43399
  versions.push(`${specifier}=missing`);
43681
43400
  }
43682
- versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
43683
43401
  return versions;
43684
43402
  };
43685
43403
  const esmRequire = createRequire(import.meta.url);
@@ -44373,17 +44091,12 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
44373
44091
  const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
44374
44092
  const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
44375
44093
  const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
44376
- const SET_STATE_IN_EFFECT_ACTION = "Prefer deriving or initializing the value before render. If the effect must read a browser API after mount, treat this as advisory or suppress it with `// react-doctor-disable-next-line react-hooks-js/set-state-in-effect`.";
44377
44094
  const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
44378
44095
  const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
44379
44096
  const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
44380
44097
  if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
44381
44098
  return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
44382
44099
  };
44383
- const buildSetStateInEffectMessage = (reasonSummary) => {
44384
- const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
44385
- return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
44386
- };
44387
44100
  const PLUGIN_CATEGORY_MAP = {
44388
44101
  react: "Bugs",
44389
44102
  "react-hooks": "Bugs",
@@ -44441,10 +44154,6 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
44441
44154
  message: REACT_ERROR_BOUNDARY_MESSAGE,
44442
44155
  help: reasonDetail || help
44443
44156
  };
44444
- if (rule === "set-state-in-effect") return {
44445
- message: buildSetStateInEffectMessage(reasonSummary.trim()),
44446
- help: reasonDetail || help
44447
- };
44448
44157
  return {
44449
44158
  message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
44450
44159
  help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
@@ -45155,7 +44864,7 @@ const reactHooksJsPluginDropNote = (error) => {
45155
44864
  * 6. always restore disable directives + clean up the temp dir
45156
44865
  */
45157
44866
  const runOxlint = async (options) => {
45158
- const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
44867
+ const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
45159
44868
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
45160
44869
  const severityControls = buildRuleSeverityControls(userConfig);
45161
44870
  validateRuleRegistration();
@@ -45169,15 +44878,13 @@ const runOxlint = async (options) => {
45169
44878
  }
45170
44879
  const pluginPath = resolvePluginPath();
45171
44880
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
45172
- const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
44881
+ const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
45173
44882
  const buildConfig = (overrides) => createOxlintConfig({
45174
44883
  pluginPath,
45175
44884
  project,
45176
44885
  customRulesOnly,
45177
44886
  extendsPaths: overrides.extendsPaths,
45178
44887
  ignoredTags,
45179
- includedTags,
45180
- includeTagDefaults,
45181
44888
  serverAuthFunctionNames,
45182
44889
  severityControls,
45183
44890
  userPlugins,
@@ -45566,8 +45273,6 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
45566
45273
  respectInlineDisables: input.respectInlineDisables,
45567
45274
  adoptExistingLintConfig: input.adoptExistingLintConfig,
45568
45275
  ignoredTags: input.ignoredTags,
45569
- includedTags: input.includedTags,
45570
- includeTagDefaults: input.includeTagDefaults,
45571
45276
  userConfig: input.userConfig ?? null,
45572
45277
  configSourceDirectory: input.configSourceDirectory,
45573
45278
  onPartialFailure: (reason) => {
@@ -46416,9 +46121,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
46416
46121
  const securityScanFailedRef = yield* make$13(false);
46417
46122
  const securityScanFiber = yield* forkChild(runCollect(applyPerElementPipeline(isDiffMode ? empty$4 : unwrap(tryPromise(() => checkSecurityScanCooperative(scanDirectory, {
46418
46123
  project,
46419
- ignoredTags: input.ignoredTags,
46420
- includedTags: input.includedTags,
46421
- includeTagDefaults: input.includeTagDefaults
46124
+ ignoredTags: input.ignoredTags
46422
46125
  })).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)), catch_$1(() => set(securityScanFailedRef, true).pipe(as(empty$4))))))).pipe(withSpan("SecurityScan.run")));
46423
46126
  const shouldRunSupplyChain = !isDiffMode || (input.supplyChainManifestChanged ?? false);
46424
46127
  const supplyChainOverlapTimeout = yield* SupplyChainOverlapTimeoutMs;
@@ -46509,8 +46212,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
46509
46212
  respectInlineDisables: input.respectInlineDisables,
46510
46213
  adoptExistingLintConfig: input.adoptExistingLintConfig,
46511
46214
  ignoredTags: input.ignoredTags,
46512
- includedTags: input.includedTags,
46513
- includeTagDefaults: input.includeTagDefaults,
46514
46215
  userConfig: resolvedConfig.config ?? void 0,
46515
46216
  configSourceDirectory: resolvedConfig.configSourceDirectory ?? void 0,
46516
46217
  onFileProgress: (scannedFileCount, totalFileCount) => {
@@ -47655,7 +47356,7 @@ const makeNoopConsole = () => ({
47655
47356
  });
47656
47357
  //#endregion
47657
47358
  //#region src/cli/utils/version.ts
47658
- const VERSION = "0.8.1-dev.0b0b5ac";
47359
+ const VERSION = "0.8.1-dev.1839566";
47659
47360
  //#endregion
47660
47361
  //#region src/cli/utils/json-mode.ts
47661
47362
  let context = null;
@@ -47742,11 +47443,7 @@ const getRunId = () => {
47742
47443
  };
47743
47444
  //#endregion
47744
47445
  //#region src/cli/utils/build-run-context.ts
47745
- const ROOT_SUBCOMMANDS = new Set([
47746
- "design",
47747
- "install",
47748
- "setup"
47749
- ]);
47446
+ const ROOT_SUBCOMMANDS = new Set(["install", "setup"]);
47750
47447
  const detectInvokedVia = () => {
47751
47448
  const userAgent = process.env.npm_config_user_agent;
47752
47449
  if (!userAgent) return "unknown";
@@ -47830,9 +47527,7 @@ const buildSentryProjectContext = (projectInfo) => ({
47830
47527
  reactMajorVersion: projectInfo.reactMajorVersion,
47831
47528
  hasTypeScript: projectInfo.hasTypeScript,
47832
47529
  hasReactCompiler: projectInfo.hasReactCompiler,
47833
- tanstackQueryVersion: projectInfo.tanstackQueryVersion,
47834
- mobxVersion: projectInfo.mobxVersion,
47835
- styledComponentsVersion: projectInfo.styledComponentsVersion,
47530
+ hasTanStackQuery: projectInfo.hasTanStackQuery,
47836
47531
  tailwindVersion: projectInfo.tailwindVersion,
47837
47532
  zodVersion: projectInfo.zodVersion,
47838
47533
  preactVersion: projectInfo.preactVersion,
@@ -48013,13 +47708,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
48013
47708
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
48014
47709
  * standard `SENTRY_RELEASE` override.
48015
47710
  */
48016
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.1-dev.0b0b5ac`;
47711
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.1-dev.1839566`;
48017
47712
  /**
48018
47713
  * Deployment environment shown in Sentry's environment filter. Defaults to
48019
47714
  * `production` for tagged releases and `development` for dev/unbuilt versions,
48020
47715
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
48021
47716
  */
48022
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.1-dev.0b0b5ac") ? "development" : "production");
47717
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.1-dev.1839566") ? "development" : "production");
48023
47718
  /**
48024
47719
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
48025
47720
  * (set to `0` to disable tracing) and falls back to
@@ -60345,8 +60040,6 @@ const buildScanResultCacheKey = (input) => {
60345
60040
  warnings: input.options.warnings,
60346
60041
  adoptExistingLintConfig: input.options.adoptExistingLintConfig,
60347
60042
  ignoredTags: [...input.options.ignoredTags].sort(),
60348
- includedTags: [...input.options.includedTags].sort(),
60349
- includeTagDefaults: input.options.includeTagDefaults,
60350
60043
  concurrency: input.options.concurrency,
60351
60044
  lintBatchOrdering: resolveLintBatchOrdering(),
60352
60045
  baselineRef: input.options.baseline?.ref,
@@ -61173,8 +60866,8 @@ const createDiagnosticEvidenceReader = (rootDirectory, options = {}) => {
61173
60866
  //#endregion
61174
60867
  //#region src/cli/utils/build-no-score-message.ts
61175
60868
  const ENTERPRISE_CONTACT_HINT = `Want something custom to your company? Contact us at ${ENTERPRISE_CONTACT_URL}.`;
61176
- const buildNoScoreMessage = (isScoreDisabled, disabledMessage) => {
61177
- return `${isScoreDisabled ? disabledMessage ?? "Score disabled by --no-score." : "Score unavailable (could not reach the score API)."} ${ENTERPRISE_CONTACT_HINT}`;
60869
+ const buildNoScoreMessage = (isScoreDisabled) => {
60870
+ return `${isScoreDisabled ? "Score disabled by --no-score." : "Score unavailable (could not reach the score API)."} ${ENTERPRISE_CONTACT_HINT}`;
61178
60871
  };
61179
60872
  //#endregion
61180
60873
  //#region src/cli/utils/render-agent-guidance.ts
@@ -62299,47 +61992,40 @@ const buildChangedLineMatcher = (directory, changedLineRanges) => {
62299
61992
  return diagnosticIntersectsLineRanges(diagnostic, ranges);
62300
61993
  };
62301
61994
  };
62302
- const buildIgnoredTags = (userConfig, includedTags) => {
61995
+ const buildIgnoredTags = (userConfig) => {
62303
61996
  const tags = /* @__PURE__ */ new Set();
62304
61997
  if (userConfig?.ignore?.tags) for (const tag of userConfig.ignore.tags) tags.add(tag);
62305
- for (const tag of includedTags) tags.delete(tag);
62306
61998
  return tags;
62307
61999
  };
62308
- const mergeInspectOptions = (inputOptions, userConfig) => {
62309
- const includedTags = inputOptions.includedTags ?? /* @__PURE__ */ new Set();
62310
- return {
62311
- lint: inputOptions.lint ?? userConfig?.lint ?? true,
62312
- deadCode: inputOptions.deadCode ?? userConfig?.deadCode ?? true,
62313
- supplyChain: inputOptions.supplyChain ?? userConfig?.supplyChain?.enabled ?? true,
62314
- verbose: inputOptions.verbose ?? userConfig?.verbose ?? false,
62315
- outputDirectory: inputOptions.outputDirectory || null,
62316
- scoreOnly: inputOptions.scoreOnly ?? false,
62317
- noScore: inputOptions.noScore ?? userConfig?.noScore ?? false,
62318
- isCi: inputOptions.isCi ?? false,
62319
- isCiOrCodingAgentEnvironment: isCiOrCodingAgentEnvironment(),
62320
- isNonInteractiveEnvironment: isNonInteractiveEnvironment(),
62321
- silent: inputOptions.silent ?? false,
62322
- includePaths: inputOptions.includePaths ?? [],
62323
- customRulesOnly: includedTags.size > 0 ? false : userConfig?.customRulesOnly ?? false,
62324
- share: userConfig?.share ?? true,
62325
- respectInlineDisables: inputOptions.respectInlineDisables ?? userConfig?.respectInlineDisables ?? true,
62326
- warnings: inputOptions.warnings ?? userConfig?.warnings ?? true,
62327
- categoryFilters: new Set(resolveCliCategories(inputOptions.categoryFilters) ?? []),
62328
- adoptExistingLintConfig: includedTags.size > 0 ? false : userConfig?.adoptExistingLintConfig ?? true,
62329
- ignoredTags: buildIgnoredTags(userConfig, includedTags),
62330
- includedTags,
62331
- includeTagDefaults: inputOptions.includeTagDefaults ?? false,
62332
- scoreDisabledMessage: inputOptions.scoreDisabledMessage,
62333
- outputSurface: inputOptions.outputSurface ?? "cli",
62334
- suppressRendering: inputOptions.suppressRendering ?? false,
62335
- concurrentScan: inputOptions.concurrentScan ?? false,
62336
- concurrency: inputOptions.concurrency,
62337
- maxDurationMs: inputOptions.maxDurationMs ?? null,
62338
- baseline: inputOptions.baseline ?? null,
62339
- changedLineRanges: inputOptions.changedLineRanges ?? null,
62340
- supplyChainManifestChanged: inputOptions.supplyChainManifestChanged ?? false
62341
- };
62342
- };
62000
+ const mergeInspectOptions = (inputOptions, userConfig) => ({
62001
+ lint: inputOptions.lint ?? userConfig?.lint ?? true,
62002
+ deadCode: inputOptions.deadCode ?? userConfig?.deadCode ?? true,
62003
+ supplyChain: inputOptions.supplyChain ?? userConfig?.supplyChain?.enabled ?? true,
62004
+ verbose: inputOptions.verbose ?? userConfig?.verbose ?? false,
62005
+ outputDirectory: inputOptions.outputDirectory || null,
62006
+ scoreOnly: inputOptions.scoreOnly ?? false,
62007
+ noScore: inputOptions.noScore ?? userConfig?.noScore ?? false,
62008
+ isCi: inputOptions.isCi ?? false,
62009
+ isCiOrCodingAgentEnvironment: isCiOrCodingAgentEnvironment(),
62010
+ isNonInteractiveEnvironment: isNonInteractiveEnvironment(),
62011
+ silent: inputOptions.silent ?? false,
62012
+ includePaths: inputOptions.includePaths ?? [],
62013
+ customRulesOnly: userConfig?.customRulesOnly ?? false,
62014
+ share: userConfig?.share ?? true,
62015
+ respectInlineDisables: inputOptions.respectInlineDisables ?? userConfig?.respectInlineDisables ?? true,
62016
+ warnings: inputOptions.warnings ?? userConfig?.warnings ?? true,
62017
+ categoryFilters: new Set(resolveCliCategories(inputOptions.categoryFilters) ?? []),
62018
+ adoptExistingLintConfig: userConfig?.adoptExistingLintConfig ?? true,
62019
+ ignoredTags: buildIgnoredTags(userConfig),
62020
+ outputSurface: inputOptions.outputSurface ?? "cli",
62021
+ suppressRendering: inputOptions.suppressRendering ?? false,
62022
+ concurrentScan: inputOptions.concurrentScan ?? false,
62023
+ concurrency: inputOptions.concurrency,
62024
+ maxDurationMs: inputOptions.maxDurationMs ?? null,
62025
+ baseline: inputOptions.baseline ?? null,
62026
+ changedLineRanges: inputOptions.changedLineRanges ?? null,
62027
+ supplyChainManifestChanged: inputOptions.supplyChainManifestChanged ?? false
62028
+ });
62343
62029
  const deriveScope = (options) => {
62344
62030
  if (options.baseline) return "changed";
62345
62031
  if (options.changedLineRanges !== null) return "lines";
@@ -62470,8 +62156,6 @@ const runBaselineComparison = async (params) => {
62470
62156
  warnings: params.options.warnings,
62471
62157
  adoptExistingLintConfig: params.options.adoptExistingLintConfig,
62472
62158
  ignoredTags: params.options.ignoredTags,
62473
- includedTags: params.options.includedTags,
62474
- includeTagDefaults: params.options.includeTagDefaults,
62475
62159
  nodeBinaryPath: params.resolvedNodeBinaryPath ?? void 0,
62476
62160
  runDeadCode: false,
62477
62161
  isCi: params.options.isCi,
@@ -62565,8 +62249,6 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
62565
62249
  warnings: options.warnings,
62566
62250
  adoptExistingLintConfig: options.adoptExistingLintConfig,
62567
62251
  ignoredTags: options.ignoredTags,
62568
- includedTags: options.includedTags,
62569
- includeTagDefaults: options.includeTagDefaults,
62570
62252
  nodeBinaryPath: resolvedNodeBinaryPath ?? void 0,
62571
62253
  runDeadCode: options.deadCode,
62572
62254
  isCi: options.isCi,
@@ -62755,7 +62437,7 @@ const finalizeAndRender = (input) => gen(function* () {
62755
62437
  securityScanFailed
62756
62438
  });
62757
62439
  const hasSkippedChecks = skippedChecks.length > 0;
62758
- const noScoreMessage = buildNoScoreMessage(options.noScore, options.scoreDisabledMessage);
62440
+ const noScoreMessage = buildNoScoreMessage(options.noScore);
62759
62441
  const buildResult = () => ({
62760
62442
  diagnostics: [...diagnostics],
62761
62443
  score,
@@ -64860,25 +64542,21 @@ const resolveParallelFlag = (parallel) => parallel === false ? 1 : void 0;
64860
64542
  */
64861
64543
  const resolveCliInspectOptions = (flags, userConfig) => {
64862
64544
  const wantsWarningGate = pickBlockingLevel(flags, userConfig) === "warning";
64863
- const isDesignScan = flags.design === true;
64864
64545
  return {
64865
64546
  lint: flags.lint,
64866
- deadCode: isDesignScan ? false : flags.deadCode,
64867
- supplyChain: isDesignScan ? false : flags.supplyChain,
64547
+ deadCode: flags.deadCode,
64548
+ supplyChain: flags.supplyChain,
64868
64549
  verbose: flags.verbose,
64869
64550
  outputDirectory: flags.outputDir,
64870
64551
  respectInlineDisables: flags.respectInlineDisables === false ? false : void 0,
64871
64552
  warnings: wantsWarningGate ? true : flags.warnings,
64872
64553
  scoreOnly: flags.score === true,
64873
- noScore: isDesignScan || flags.score === false || flags.telemetry === false ? true : void 0,
64554
+ noScore: flags.score === false || flags.telemetry === false ? true : void 0,
64874
64555
  isCi: isCiEnvironment(),
64875
64556
  silent: Boolean(flags.json),
64876
64557
  concurrency: resolveParallelFlag(flags.parallel),
64877
64558
  maxDurationMs: resolveMaxDurationFlag(flags.maxDuration),
64878
- categoryFilters: resolveCliCategories(flags.category),
64879
- includedTags: isDesignScan ? new Set(["design"]) : void 0,
64880
- includeTagDefaults: isDesignScan ? true : void 0,
64881
- scoreDisabledMessage: isDesignScan ? "Design scans do not affect the React health score." : void 0
64559
+ categoryFilters: resolveCliCategories(flags.category)
64882
64560
  };
64883
64561
  };
64884
64562
  //#endregion
@@ -65296,7 +64974,7 @@ const maybeMigrateLegacyConfig = async (requestedDirectory, { isQuiet, isStaged
65296
64974
  if (!(!isQuiet && !isStaged && process.stdout.isTTY === true && !isCiOrCodingAgentEnvironment())) return;
65297
64975
  await runProjectMigrations(requestedDirectory);
65298
64976
  };
65299
- const inspectAction = async (directory, flags, invocationCommand = "inspect") => {
64977
+ const inspectAction = async (directory, flags) => {
65300
64978
  const isScoreOnly = Boolean(flags.score);
65301
64979
  const isJsonMode = Boolean(flags.json);
65302
64980
  const isQuiet = isScoreOnly || isJsonMode;
@@ -65310,7 +64988,7 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
65310
64988
  });
65311
64989
  if (flags.jsonOut) recordCount(METRIC.jsonOutUsed, 1);
65312
64990
  }
65313
- recordCount(METRIC.cliInvoked, 1, { command: invocationCommand });
64991
+ recordCount(METRIC.cliInvoked, 1, { command: "inspect" });
65314
64992
  try {
65315
64993
  validateModeFlags(flags);
65316
64994
  if (flags.staged) setJsonReportMode("staged");
@@ -65622,13 +65300,6 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
65622
65300
  }
65623
65301
  };
65624
65302
  //#endregion
65625
- //#region src/cli/commands/design.ts
65626
- const designAction = async (directory, flags) => inspectAction(directory, {
65627
- ...flags,
65628
- design: true,
65629
- lint: flags.lint ?? true
65630
- }, "design");
65631
- //#endregion
65632
65303
  //#region src/cli/commands/install.ts
65633
65304
  const installAction = async (options, command) => {
65634
65305
  recordCount(METRIC.cliInvoked, 1, { command: "install" });
@@ -66465,7 +66136,6 @@ const INSTALL_FLAG_SPEC = {
66465
66136
  shortOptionsWithRequiredValues: new Set(["-c"])
66466
66137
  };
66467
66138
  const COMMAND_FLAG_SPECS = new Map([
66468
- ["design", ROOT_FLAG_SPEC],
66469
66139
  ["install", INSTALL_FLAG_SPEC],
66470
66140
  ["setup", INSTALL_FLAG_SPEC],
66471
66141
  ["version", {
@@ -66622,7 +66292,6 @@ ${formatExampleLines([
66622
66292
  ["react-doctor --scope changed --base main", "scan only new issues vs. main"],
66623
66293
  ["react-doctor --project modules/a,modules/b", "score each module separately (names or paths)"],
66624
66294
  ["react-doctor --staged", "scan staged files (pre-commit hook)"],
66625
- ["react-doctor design", "run the focused UI design audit"],
66626
66295
  ["react-doctor --category Security", "show only one diagnostic category"],
66627
66296
  ["react-doctor --blocking warning", "fail CI on warnings too (default: error)"],
66628
66297
  ["react-doctor --json > report.json", "write a machine-readable report"],
@@ -66656,20 +66325,6 @@ ${highlighter.dim("Managing CI:")}
66656
66325
  ${highlighter.dim("Learn more:")}
66657
66326
  ${highlighter.info(CANONICAL_GITHUB_URL)}
66658
66327
  `;
66659
- const renderDesignHelpEpilog = () => `
66660
- ${highlighter.dim("Examples:")}
66661
- ${formatExampleLines([
66662
- ["react-doctor design", "audit UI design in the current project"],
66663
- ["react-doctor design ./apps/web", "audit one application"],
66664
- ["react-doctor design --verbose", "show every design finding"],
66665
- ["react-doctor design --json", "write a design-only JSON report"]
66666
- ])}
66667
-
66668
- ${highlighter.dim("Scope:")}
66669
- Runs only rules tagged ${highlighter.info("design")}, including focused rules that stay opt-in during a general health scan.
66670
- Dead-code, supply-chain, external lint-config, custom-plugin, and health-score passes are skipped.
66671
- Standard scan flags such as ${highlighter.info("--scope")}, ${highlighter.info("--project")}, ${highlighter.info("--verbose")}, and ${highlighter.info("--json")} still work.
66672
- `;
66673
66328
  const renderCiHelpEpilog = () => `
66674
66329
  ${highlighter.dim("Examples:")}
66675
66330
  ${formatExampleLines([
@@ -66691,7 +66346,6 @@ ${highlighter.dim("Learn more:")}
66691
66346
  const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
66692
66347
  const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
66693
66348
  program.action(inspectAction);
66694
- program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
66695
66349
  program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action((location, options) => whyAction(location, options));
66696
66350
  program.command("install").alias("setup").description("Install the react-doctor skill into your coding agents and optional git hook").option("-y, --yes", "skip prompts, install for all detected agents").option("--dry-run", "show what would be installed without writing files").option("--agent-hooks", "install native non-blocking agent hooks for Claude Code and Cursor").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderInstallHelpEpilog).action(installAction);
66697
66351
  const providerOption = ["--provider <name>", "ci provider: github-actions or gitlab-ci (auto-detected by default)"];
@@ -66740,4 +66394,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
66740
66394
  export {};
66741
66395
 
66742
66396
  //# sourceMappingURL=cli.js.map
66743
- //# debugId=a9af63ed-7b82-56d3-8549-274ab7f23579
66397
+ //# debugId=c24708ed-97a3-59cc-81f7-4cf277ab29f2