react-doctor 0.9.11 → 0.9.12-dev.a2b460d

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 (28) hide show
  1. package/dist/{build-section-divider-sLcWe1hO.js → build-section-divider-Vz879zXD.js} +7 -7
  2. package/dist/{ci-DsrrD52i.js → ci-BVYrYekU.js} +11 -11
  3. package/dist/cli.js +22 -22
  4. package/dist/{design-CP25gyyg.js → design-D-TYN_tr.js} +4 -4
  5. package/dist/{exit-gracefully-CVVkBxDS.js → exit-gracefully-Cjv5kC_l.js} +6 -6
  6. package/dist/index.d.ts +17 -19
  7. package/dist/index.js +150 -34
  8. package/dist/{inspect-D6y8oLtg.js → inspect-kkvDHKDE.js} +19 -19
  9. package/dist/{install-afMFGeTB.js → install-ZeYvD9Rw.js} +8 -8
  10. package/dist/{install-doctor-script-Be7Mv3-l.js → install-doctor-script-D58Hr1dM.js} +4 -4
  11. package/dist/{install-github-workflow-Dev2F6Ea.js → install-github-workflow-DkMicv8E.js} +6 -6
  12. package/dist/{install-react-doctor-DIPVunY4.js → install-react-doctor-CjgE52al.js} +8 -8
  13. package/dist/lsp.js +55 -24
  14. package/dist/{print-branded-header-D5jLdo4p.js → print-branded-header-D4QYSu-h.js} +4 -4
  15. package/dist/{read-object-file-CEh1CqnD.js → read-object-file-OFRlvCAL.js} +4 -4
  16. package/dist/{record-metric-CJxSHfJD.js → record-metric-CMe2d1Xv.js} +86 -41
  17. package/dist/{report-error-CAEixMg1.js → report-error-1l7v6_dE.js} +5 -5
  18. package/dist/{report-workflow-result-C0jbKH8p.js → report-workflow-result-EagkH_v9.js} +5 -5
  19. package/dist/{resolve-scope-DS7rcRRz.js → resolve-scope-CMNrOdDf.js} +6 -6
  20. package/dist/{rules-BJynymuU.js → rules-CzR1qUru.js} +6 -6
  21. package/dist/{run-scan-app-BGzlyiIB.js → run-scan-app-Ciq22jzp.js} +69 -36
  22. package/dist/{scan-CgPRG6_z.js → scan-D4m5r4Rs.js} +8 -8
  23. package/dist/{should-fail-scan-gate-4jf7ZRdL.js → should-fail-scan-gate-lMTlhEhE.js} +56 -21
  24. package/dist/{should-skip-prompts-C78r7Ww7.js → should-skip-prompts-mXKZBNCz.js} +4 -4
  25. package/dist/{unref-stdin-Dc8ipkaw.js → unref-stdin-Cxhw67r6.js} +4 -4
  26. package/dist/{version-DDrwsTas.js → version-CnvVY2VD.js} +4 -4
  27. package/dist/{why-BRNrKY1b.js → why-BktDEhhH.js} +4 -4
  28. package/package.json +7 -9
package/dist/lsp.js CHANGED
@@ -21257,11 +21257,11 @@ var JsonReportV1 = class extends Class("JsonReportV1")({
21257
21257
  */
21258
21258
  baselineDegraded: optional(Boolean$1),
21259
21259
  /**
21260
- * Whether any scanned project resolved a React-compatible runtime (React
21261
- * or Preact). `false` means every React-runtime rule family was gated off,
21262
- * so an empty `diagnostics` array is vacuous — NOT the same as a clean
21263
- * React scan. Consumers gating on the report (CI, verifiers, hooks) should
21264
- * treat `reactDetected === false` as "wrong scan target", not "all clear".
21260
+ * Whether any scanned project resolved a React-compatible runtime directly
21261
+ * or through a React-backed framework. `false` means every React-runtime
21262
+ * rule family was gated off, not that the scan target was unsupported:
21263
+ * other detected framework and library rule families still run, as do
21264
+ * framework-neutral rules on any analyzable project.
21265
21265
  * Absent when nothing was scanned (`projects` is empty), on error reports,
21266
21266
  * and on reports from older CLI versions.
21267
21267
  */
@@ -65113,7 +65113,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
65113
65113
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
65114
65114
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
65115
65115
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
65116
- const CORE_PACKAGE_VERSION = "0.9.11";
65116
+ const CORE_PACKAGE_VERSION = "0.9.12";
65117
65117
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
65118
65118
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
65119
65119
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -65458,7 +65458,8 @@ const listSourceFilesViaFilesystemCooperative = async (rootDirectory, signal) =>
65458
65458
  const listSourceFilePaths = (rootDirectory) => (listSourceFilesViaGit(rootDirectory) ?? listSourceFilesViaFilesystem(rootDirectory)).sort();
65459
65459
  const listSourceFilePathsCooperative = async (rootDirectory, signal) => (await listSourceFilesViaGitCooperative(rootDirectory, signal) ?? await listSourceFilesViaFilesystemCooperative(rootDirectory, signal)).sort();
65460
65460
  const listSourceFilesWithSize = (rootDirectory) => collectSizedSourceFiles(rootDirectory, listSourceFilePaths(rootDirectory));
65461
- const listSourceFilesCooperative = async (rootDirectory, signal) => (await collectSizedSourceFilesCooperative(rootDirectory, await listSourceFilePathsCooperative(rootDirectory, signal), signal)).map((entry) => entry.path);
65461
+ const listSourceFilesWithSizeCooperative = async (rootDirectory, signal) => collectSizedSourceFilesCooperative(rootDirectory, await listSourceFilePathsCooperative(rootDirectory, signal), signal);
65462
+ const listSourceFilesCooperative = async (rootDirectory, signal) => (await listSourceFilesWithSizeCooperative(rootDirectory, signal)).map((entry) => entry.path);
65462
65463
  const listSourceFiles = (rootDirectory) => listSourceFilesWithSize(rootDirectory).map((entry) => entry.path);
65463
65464
  const countSourceFiles = (rootDirectory) => listSourceFilesWithSize(rootDirectory).length;
65464
65465
  const NEXT_CONFIG_FILENAMES = [
@@ -72093,6 +72094,21 @@ function* collectSecurityScanFiles(rootDirectory, excludedDirectories = /* @__PU
72093
72094
  }
72094
72095
  }
72095
72096
  }
72097
+ const REACT_COMPATIBLE_FRAMEWORKS = new Set([
72098
+ "nextjs",
72099
+ "tanstack-start",
72100
+ "cra",
72101
+ "remix",
72102
+ "gatsby",
72103
+ "expo",
72104
+ "react-native",
72105
+ "preact"
72106
+ ]);
72107
+ /**
72108
+ * Whether project discovery resolved a React-compatible runtime directly or
72109
+ * through a framework whose runtime is necessarily React-compatible.
72110
+ */
72111
+ const hasReactRuntime = (project) => project.reactVersion !== null || project.preactVersion !== null || REACT_COMPATIBLE_FRAMEWORKS.has(project.framework);
72096
72112
  const CLIENT_ONLY_FRAMEWORKS = new Set([
72097
72113
  "vite",
72098
72114
  "cra",
@@ -72114,7 +72130,7 @@ const addVersionCapabilityLadder = (capabilities, name, detectedVersion, earlies
72114
72130
  const buildCapabilities = (project) => {
72115
72131
  const capabilities = /* @__PURE__ */ new Set();
72116
72132
  capabilities.add(project.framework);
72117
- if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
72133
+ if (hasReactRuntime(project)) capabilities.add("react");
72118
72134
  if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
72119
72135
  if (project.expoVersion !== null) {
72120
72136
  capabilities.add("expo");
@@ -74401,6 +74417,9 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
74401
74417
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
74402
74418
  const capabilities = getCapabilities(project);
74403
74419
  const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
74420
+ const noMultiCompOverride = resolveRuleSeverityOverride({ ruleKey: "react-doctor/no-multi-comp" }, severityControls);
74421
+ const multiComponentFileOverride = resolveRuleSeverityOverride({ ruleKey: "react-doctor/no-multi-component-file" }, severityControls);
74422
+ const shouldUseExplicitNoMultiCompPolicy = noMultiCompOverride !== void 0 && multiComponentFileOverride === void 0;
74404
74423
  const enabledReactDoctorRules = {};
74405
74424
  for (const registryEntry of REACT_DOCTOR_RULES) {
74406
74425
  const rule = REACT_DOCTOR_RULE_REGISTRY[registryEntry.id];
@@ -74409,6 +74428,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
74409
74428
  if (ruleSelection === "sidecar" && !CROSS_FILE_RULE_IDS.has(registryEntry.id)) continue;
74410
74429
  if (ruleSelection === "sidecar" && sidecarRuleIdFilter !== void 0 && !sidecarRuleIdFilter.has(registryEntry.id)) continue;
74411
74430
  if (rule.isScanRule) continue;
74431
+ if (registryEntry.id === "no-multi-component-file" && shouldUseExplicitNoMultiCompPolicy) continue;
74412
74432
  if (customRulesOnly && registryEntry.originallyExternal) continue;
74413
74433
  if (rule.framework !== "global" && !rule.requires) continue;
74414
74434
  if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
@@ -74445,6 +74465,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
74445
74465
  plugins: [],
74446
74466
  jsPlugins: [...jsPlugins, pluginPath],
74447
74467
  settings: { "react-doctor": {
74468
+ portedRuleMode: "curated",
74448
74469
  framework: project.framework,
74449
74470
  rootDirectory: settingsRootDirectory,
74450
74471
  capabilities: [...capabilities].sort(),
@@ -75626,6 +75647,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
75626
75647
  };
75627
75648
  };
75628
75649
  const parseRuleCode = (code) => {
75650
+ if (typeof code !== "string" || code.length === 0) return {
75651
+ plugin: "unknown",
75652
+ rule: "unknown"
75653
+ };
75629
75654
  const match = code.match(/^(.+)\((.+)\)$/);
75630
75655
  if (!match) return {
75631
75656
  plugin: "unknown",
@@ -76709,7 +76734,7 @@ const runOxlint = async (options) => {
76709
76734
  const pluginPath = resolvePluginPath();
76710
76735
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
76711
76736
  const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
76712
- const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
76737
+ const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths ?? options.precomputedSourceFiles?.map((sourceFile) => sourceFile.path));
76713
76738
  const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
76714
76739
  const configPath = Path.join(configDirectory, "oxlintrc.json");
76715
76740
  try {
@@ -76742,8 +76767,8 @@ const runOxlint = async (options) => {
76742
76767
  ...sharedArgs
76743
76768
  ];
76744
76769
  await yieldToEventLoop();
76745
- const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
76746
- const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
76770
+ const sizedScanFiles = options.precomputedSourceFiles ?? (includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null);
76771
+ const candidateFiles = sizedScanFiles === null ? includePaths ?? [] : sizedScanFiles.map((entry) => entry.path);
76747
76772
  const projectIndexModuleSources = includePaths === void 0 && options.deadlineEpochMs === void 0 ? await collectProjectIndexModuleSources(rootDirectory, candidateFiles) : void 0;
76748
76773
  unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
76749
76774
  rootDirectory,
@@ -77123,6 +77148,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
77123
77148
  rootDirectory: input.rootDirectory,
77124
77149
  project: input.project,
77125
77150
  includePaths: input.includePaths ? [...input.includePaths] : void 0,
77151
+ precomputedSourceFiles: input.precomputedSourceFiles,
77126
77152
  nodeBinaryPath: input.nodeBinaryPath,
77127
77153
  customRulesOnly: input.customRulesOnly,
77128
77154
  respectInlineDisables: input.respectInlineDisables,
@@ -77920,22 +77946,23 @@ const runInspect = (input, hooks = {}) => gen(function* () {
77920
77946
  const relativeFilePath = toNormalizedRelativePath(diagnostic.filePath, scanDirectory);
77921
77947
  return excludedProjectRelativePaths.some((excludedRelativePath) => relativeFilePath === excludedRelativePath || relativeFilePath.startsWith(`${excludedRelativePath}/`));
77922
77948
  };
77923
- const precomputedSourceFiles = input.suppressScanSummary === true || excludedProjectDirectories.length > 0 ? yield* filesService.listSourceFilesCooperative({
77949
+ const shouldListSourceFiles = input.precomputedSourceFiles === void 0 && (input.suppressScanSummary === true || excludedProjectDirectories.length > 0);
77950
+ const precomputedSourceFilePaths = input.precomputedSourceFiles?.map((sourceFile) => sourceFile.path) ?? (shouldListSourceFiles ? yield* filesService.listSourceFilesCooperative({
77924
77951
  rootDirectory: scanDirectory,
77925
77952
  signal: input.signal
77926
- }) : null;
77927
- const includedPrecomputedSourceFiles = precomputedSourceFiles !== null && excludedProjectDirectories.length > 0 ? filterPathsOutsideDirectories({
77953
+ }) : null);
77954
+ const includedPrecomputedSourceFilePaths = precomputedSourceFilePaths !== null && excludedProjectDirectories.length > 0 ? filterPathsOutsideDirectories({
77928
77955
  rootDirectory: scanDirectory,
77929
- relativePaths: precomputedSourceFiles,
77956
+ relativePaths: precomputedSourceFilePaths,
77930
77957
  excludedDirectories: excludedProjectDirectories
77931
- }) : precomputedSourceFiles;
77932
- const sourceFileCount = excludedProjectDirectories.length > 0 ? includedPrecomputedSourceFiles?.length : input.precomputedSourceFileCount ?? includedPrecomputedSourceFiles?.length;
77958
+ }) : precomputedSourceFilePaths;
77959
+ const sourceFileCount = excludedProjectDirectories.length > 0 ? includedPrecomputedSourceFilePaths?.length : input.precomputedSourceFiles?.length ?? input.precomputedSourceFileCount ?? includedPrecomputedSourceFilePaths?.length;
77933
77960
  const project = yield* projectService.discover({
77934
77961
  directory: scanDirectory,
77935
77962
  sourceFileCount
77936
77963
  });
77937
77964
  if (!isAnalyzableProject(project)) return yield* new ReactDoctorError({ reason: new NoReactDependency({ directory: scanDirectory }) });
77938
- const deadCodeSourceFileCount = input.retainExcludedProjectDeadCodeDiagnostics === true && precomputedSourceFiles !== null ? precomputedSourceFiles.length : project.sourceFileCount;
77965
+ const deadCodeSourceFileCount = input.retainExcludedProjectDeadCodeDiagnostics === true && precomputedSourceFilePaths !== null ? precomputedSourceFilePaths.length : project.sourceFileCount;
77939
77966
  const [repo, sha, defaultBranch] = yield* all([
77940
77967
  gitService.githubRepo(scanDirectory).pipe(orElseSucceed(() => null)),
77941
77968
  gitService.headSha(scanDirectory).pipe(orElseSucceed(() => null)),
@@ -77946,13 +77973,16 @@ const runInspect = (input, hooks = {}) => gen(function* () {
77946
77973
  directory: scanDirectory,
77947
77974
  repo
77948
77975
  }).pipe(orElseSucceed(() => null)) : succeed$2(null));
77949
- let lintIncludePaths = (input.skipExplicitIncludePathFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths])) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, includedPrecomputedSourceFiles ?? void 0);
77976
+ let lintIncludePaths = (input.skipExplicitIncludePathFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths])) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, includedPrecomputedSourceFilePaths ?? void 0);
77950
77977
  if (excludedProjectDirectories.length > 0) lintIncludePaths = filterPathsOutsideDirectories({
77951
77978
  rootDirectory: scanDirectory,
77952
- relativePaths: lintIncludePaths ?? includedPrecomputedSourceFiles ?? (yield* filesService.listSourceFiles(scanDirectory)),
77979
+ relativePaths: lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? (yield* filesService.listSourceFiles(scanDirectory)),
77953
77980
  excludedDirectories: excludedProjectDirectories
77954
77981
  });
77955
- const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? includedPrecomputedSourceFiles ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
77982
+ const suppliedSourceFiles = input.precomputedSourceFiles;
77983
+ const includedPrecomputedSourceFilePathSet = suppliedSourceFiles === void 0 || input.includePaths.length > 0 ? null : new Set(lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? []);
77984
+ const precomputedLintSourceFiles = includedPrecomputedSourceFilePathSet === null || suppliedSourceFiles === void 0 ? void 0 : suppliedSourceFiles.filter((sourceFile) => includedPrecomputedSourceFilePathSet.has(sourceFile.path));
77985
+ const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
77956
77986
  const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
77957
77987
  const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
77958
77988
  yield* beforeLint(project);
@@ -78085,6 +78115,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
78085
78115
  rootDirectory: scanDirectory,
78086
78116
  project,
78087
78117
  includePaths: lintIncludePaths ?? void 0,
78118
+ precomputedSourceFiles: precomputedLintSourceFiles,
78088
78119
  nodeBinaryPath: input.nodeBinaryPath,
78089
78120
  customRulesOnly: input.customRulesOnly,
78090
78121
  respectInlineDisables: input.respectInlineDisables,
@@ -78577,7 +78608,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
78577
78608
  /** Display name used in client-facing messages and progress titles. */
78578
78609
  const SERVER_DISPLAY_NAME = "React Doctor";
78579
78610
  /** Server version reported in `serverInfo`; injected at build, `dev` from source. */
78580
- const SERVER_VERSION = "0.9.11";
78611
+ const SERVER_VERSION = "0.9.12";
78581
78612
  /** `Diagnostic.source` shown next to every published diagnostic. */
78582
78613
  const DIAGNOSTIC_SOURCE = "react-doctor";
78583
78614
  /**
@@ -81110,5 +81141,5 @@ const startLanguageServer = () => {
81110
81141
  };
81111
81142
  //#endregion
81112
81143
  export { startLanguageServer };
81113
- !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]="828bb7ee-aeca-51f3-9dcb-647387281900")}catch(e){}}();
81114
- //# debugId=828bb7ee-aeca-51f3-9dcb-647387281900
81144
+ !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]="d47cadfc-699f-5bd2-926e-fa241e8cb6b9")}catch(e){}}();
81145
+ //# debugId=d47cadfc-699f-5bd2-926e-fa241e8cb6b9
@@ -1,6 +1,6 @@
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]="dcc6062b-9d93-5742-be37-a12564a4b38a")}catch(e){}}();
3
- import { Gn as log, Xn as gen, cn as highlighter, g as VERSION } from "./record-metric-CJxSHfJD.js";
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]="fdc80814-5e35-5aef-8c7d-2f5adadf9064")}catch(e){}}();
3
+ import { Gn as log, Xn as gen, cn as highlighter, g as VERSION } from "./record-metric-CMe2d1Xv.js";
4
4
  //#region src/cli/utils/print-branded-header.ts
5
5
  /**
6
6
  * Single branded line every command prints first when not in JSON
@@ -18,5 +18,5 @@ const printBrandedHeader = gen(function* () {
18
18
  //#endregion
19
19
  export { printBrandedHeader as t };
20
20
 
21
- //# sourceMappingURL=print-branded-header-D5jLdo4p.js.map
22
- //# debugId=dcc6062b-9d93-5742-be37-a12564a4b38a
21
+ //# sourceMappingURL=print-branded-header-D4QYSu-h.js.map
22
+ //# debugId=fdc80814-5e35-5aef-8c7d-2f5adadf9064
@@ -1,6 +1,6 @@
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]="4c2dc830-6387-5ba4-a659-4e9bb413d5f5")}catch(e){}}();
3
- import { mn as isPlainObject } from "./record-metric-CJxSHfJD.js";
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]="72b640cf-4fca-5f0f-8473-13a6e1fdbf5a")}catch(e){}}();
3
+ import { mn as isPlainObject } from "./record-metric-CMe2d1Xv.js";
4
4
  import * as fs$1 from "node:fs";
5
5
  import { parseJSON5 } from "confbox";
6
6
  //#region src/cli/utils/read-object-file.ts
@@ -20,5 +20,5 @@ const readObjectFile = (filePath) => {
20
20
  //#endregion
21
21
  export { readObjectFile as t };
22
22
 
23
- //# sourceMappingURL=read-object-file-CEh1CqnD.js.map
24
- //# debugId=4c2dc830-6387-5ba4-a659-4e9bb413d5f5
23
+ //# sourceMappingURL=read-object-file-OFRlvCAL.js.map
24
+ //# debugId=72b640cf-4fca-5f0f-8473-13a6e1fdbf5a
@@ -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]="23657ac7-3a23-5dc3-a8b9-100f22c56678")}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]="7be6c41a-aed3-5157-8122-572c03c4bc93")}catch(e){}}();
3
3
  import { n as __require, r as __toESM$1, t as __commonJSMin$1 } from "./chunk-q7NCDQ7-.js";
4
4
  import { createRequire } from "node:module";
5
5
  import * as NodeChildProcess from "node:child_process";
@@ -21259,11 +21259,11 @@ var JsonReportV1 = class extends Class("JsonReportV1")({
21259
21259
  */
21260
21260
  baselineDegraded: optional(Boolean$1),
21261
21261
  /**
21262
- * Whether any scanned project resolved a React-compatible runtime (React
21263
- * or Preact). `false` means every React-runtime rule family was gated off,
21264
- * so an empty `diagnostics` array is vacuous — NOT the same as a clean
21265
- * React scan. Consumers gating on the report (CI, verifiers, hooks) should
21266
- * treat `reactDetected === false` as "wrong scan target", not "all clear".
21262
+ * Whether any scanned project resolved a React-compatible runtime directly
21263
+ * or through a React-backed framework. `false` means every React-runtime
21264
+ * rule family was gated off, not that the scan target was unsupported:
21265
+ * other detected framework and library rule families still run, as do
21266
+ * framework-neutral rules on any analyzable project.
21267
21267
  * Absent when nothing was scanned (`projects` is empty), on error reports,
21268
21268
  * and on reports from older CLI versions.
21269
21269
  */
@@ -65198,7 +65198,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
65198
65198
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
65199
65199
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
65200
65200
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
65201
- const CORE_PACKAGE_VERSION = "0.9.11";
65201
+ const CORE_PACKAGE_VERSION = "0.9.12";
65202
65202
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
65203
65203
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
65204
65204
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -65540,7 +65540,8 @@ const listSourceFilesViaFilesystemCooperative = async (rootDirectory, signal) =>
65540
65540
  const listSourceFilePaths = (rootDirectory) => (listSourceFilesViaGit(rootDirectory) ?? listSourceFilesViaFilesystem(rootDirectory)).sort();
65541
65541
  const listSourceFilePathsCooperative = async (rootDirectory, signal) => (await listSourceFilesViaGitCooperative(rootDirectory, signal) ?? await listSourceFilesViaFilesystemCooperative(rootDirectory, signal)).sort();
65542
65542
  const listSourceFilesWithSize = (rootDirectory) => collectSizedSourceFiles(rootDirectory, listSourceFilePaths(rootDirectory));
65543
- const listSourceFilesCooperative = async (rootDirectory, signal) => (await collectSizedSourceFilesCooperative(rootDirectory, await listSourceFilePathsCooperative(rootDirectory, signal), signal)).map((entry) => entry.path);
65543
+ const listSourceFilesWithSizeCooperative = async (rootDirectory, signal) => collectSizedSourceFilesCooperative(rootDirectory, await listSourceFilePathsCooperative(rootDirectory, signal), signal);
65544
+ const listSourceFilesCooperative = async (rootDirectory, signal) => (await listSourceFilesWithSizeCooperative(rootDirectory, signal)).map((entry) => entry.path);
65544
65545
  const listSourceFiles = (rootDirectory) => listSourceFilesWithSize(rootDirectory).map((entry) => entry.path);
65545
65546
  const countSourceFiles = (rootDirectory) => listSourceFilesWithSize(rootDirectory).length;
65546
65547
  const NEXT_CONFIG_FILENAMES = [
@@ -72270,6 +72271,21 @@ function* collectSecurityScanFiles(rootDirectory, excludedDirectories = /* @__PU
72270
72271
  }
72271
72272
  }
72272
72273
  }
72274
+ const REACT_COMPATIBLE_FRAMEWORKS = new Set([
72275
+ "nextjs",
72276
+ "tanstack-start",
72277
+ "cra",
72278
+ "remix",
72279
+ "gatsby",
72280
+ "expo",
72281
+ "react-native",
72282
+ "preact"
72283
+ ]);
72284
+ /**
72285
+ * Whether project discovery resolved a React-compatible runtime directly or
72286
+ * through a framework whose runtime is necessarily React-compatible.
72287
+ */
72288
+ const hasReactRuntime = (project) => project.reactVersion !== null || project.preactVersion !== null || REACT_COMPATIBLE_FRAMEWORKS.has(project.framework);
72273
72289
  const CLIENT_ONLY_FRAMEWORKS = new Set([
72274
72290
  "vite",
72275
72291
  "cra",
@@ -72291,7 +72307,7 @@ const addVersionCapabilityLadder = (capabilities, name, detectedVersion, earlies
72291
72307
  const buildCapabilities = (project) => {
72292
72308
  const capabilities = /* @__PURE__ */ new Set();
72293
72309
  capabilities.add(project.framework);
72294
- if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
72310
+ if (hasReactRuntime(project)) capabilities.add("react");
72295
72311
  if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
72296
72312
  if (project.expoVersion !== null) {
72297
72313
  capabilities.add("expo");
@@ -74594,6 +74610,9 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
74594
74610
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
74595
74611
  const capabilities = getCapabilities(project);
74596
74612
  const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
74613
+ const noMultiCompOverride = resolveRuleSeverityOverride({ ruleKey: "react-doctor/no-multi-comp" }, severityControls);
74614
+ const multiComponentFileOverride = resolveRuleSeverityOverride({ ruleKey: "react-doctor/no-multi-component-file" }, severityControls);
74615
+ const shouldUseExplicitNoMultiCompPolicy = noMultiCompOverride !== void 0 && multiComponentFileOverride === void 0;
74597
74616
  const enabledReactDoctorRules = {};
74598
74617
  for (const registryEntry of REACT_DOCTOR_RULES) {
74599
74618
  const rule = REACT_DOCTOR_RULE_REGISTRY[registryEntry.id];
@@ -74602,6 +74621,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
74602
74621
  if (ruleSelection === "sidecar" && !CROSS_FILE_RULE_IDS.has(registryEntry.id)) continue;
74603
74622
  if (ruleSelection === "sidecar" && sidecarRuleIdFilter !== void 0 && !sidecarRuleIdFilter.has(registryEntry.id)) continue;
74604
74623
  if (rule.isScanRule) continue;
74624
+ if (registryEntry.id === "no-multi-component-file" && shouldUseExplicitNoMultiCompPolicy) continue;
74605
74625
  if (customRulesOnly && registryEntry.originallyExternal) continue;
74606
74626
  if (rule.framework !== "global" && !rule.requires) continue;
74607
74627
  if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
@@ -74638,6 +74658,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
74638
74658
  plugins: [],
74639
74659
  jsPlugins: [...jsPlugins, pluginPath],
74640
74660
  settings: { "react-doctor": {
74661
+ portedRuleMode: "curated",
74641
74662
  framework: project.framework,
74642
74663
  rootDirectory: settingsRootDirectory,
74643
74664
  capabilities: [...capabilities].sort(),
@@ -75819,6 +75840,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
75819
75840
  };
75820
75841
  };
75821
75842
  const parseRuleCode = (code) => {
75843
+ if (typeof code !== "string" || code.length === 0) return {
75844
+ plugin: "unknown",
75845
+ rule: "unknown"
75846
+ };
75822
75847
  const match = code.match(/^(.+)\((.+)\)$/);
75823
75848
  if (!match) return {
75824
75849
  plugin: "unknown",
@@ -76902,7 +76927,7 @@ const runOxlint = async (options) => {
76902
76927
  const pluginPath = resolvePluginPath();
76903
76928
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
76904
76929
  const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
76905
- const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
76930
+ const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths ?? options.precomputedSourceFiles?.map((sourceFile) => sourceFile.path));
76906
76931
  const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
76907
76932
  const configPath = Path.join(configDirectory, "oxlintrc.json");
76908
76933
  try {
@@ -76935,8 +76960,8 @@ const runOxlint = async (options) => {
76935
76960
  ...sharedArgs
76936
76961
  ];
76937
76962
  await yieldToEventLoop();
76938
- const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
76939
- const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
76963
+ const sizedScanFiles = options.precomputedSourceFiles ?? (includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null);
76964
+ const candidateFiles = sizedScanFiles === null ? includePaths ?? [] : sizedScanFiles.map((entry) => entry.path);
76940
76965
  const projectIndexModuleSources = includePaths === void 0 && options.deadlineEpochMs === void 0 ? await collectProjectIndexModuleSources(rootDirectory, candidateFiles) : void 0;
76941
76966
  unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
76942
76967
  rootDirectory,
@@ -77316,6 +77341,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
77316
77341
  rootDirectory: input.rootDirectory,
77317
77342
  project: input.project,
77318
77343
  includePaths: input.includePaths ? [...input.includePaths] : void 0,
77344
+ precomputedSourceFiles: input.precomputedSourceFiles,
77319
77345
  nodeBinaryPath: input.nodeBinaryPath,
77320
77346
  customRulesOnly: input.customRulesOnly,
77321
77347
  respectInlineDisables: input.respectInlineDisables,
@@ -78113,22 +78139,23 @@ const runInspect = (input, hooks = {}) => gen(function* () {
78113
78139
  const relativeFilePath = toNormalizedRelativePath(diagnostic.filePath, scanDirectory);
78114
78140
  return excludedProjectRelativePaths.some((excludedRelativePath) => relativeFilePath === excludedRelativePath || relativeFilePath.startsWith(`${excludedRelativePath}/`));
78115
78141
  };
78116
- const precomputedSourceFiles = input.suppressScanSummary === true || excludedProjectDirectories.length > 0 ? yield* filesService.listSourceFilesCooperative({
78142
+ const shouldListSourceFiles = input.precomputedSourceFiles === void 0 && (input.suppressScanSummary === true || excludedProjectDirectories.length > 0);
78143
+ const precomputedSourceFilePaths = input.precomputedSourceFiles?.map((sourceFile) => sourceFile.path) ?? (shouldListSourceFiles ? yield* filesService.listSourceFilesCooperative({
78117
78144
  rootDirectory: scanDirectory,
78118
78145
  signal: input.signal
78119
- }) : null;
78120
- const includedPrecomputedSourceFiles = precomputedSourceFiles !== null && excludedProjectDirectories.length > 0 ? filterPathsOutsideDirectories({
78146
+ }) : null);
78147
+ const includedPrecomputedSourceFilePaths = precomputedSourceFilePaths !== null && excludedProjectDirectories.length > 0 ? filterPathsOutsideDirectories({
78121
78148
  rootDirectory: scanDirectory,
78122
- relativePaths: precomputedSourceFiles,
78149
+ relativePaths: precomputedSourceFilePaths,
78123
78150
  excludedDirectories: excludedProjectDirectories
78124
- }) : precomputedSourceFiles;
78125
- const sourceFileCount = excludedProjectDirectories.length > 0 ? includedPrecomputedSourceFiles?.length : input.precomputedSourceFileCount ?? includedPrecomputedSourceFiles?.length;
78151
+ }) : precomputedSourceFilePaths;
78152
+ const sourceFileCount = excludedProjectDirectories.length > 0 ? includedPrecomputedSourceFilePaths?.length : input.precomputedSourceFiles?.length ?? input.precomputedSourceFileCount ?? includedPrecomputedSourceFilePaths?.length;
78126
78153
  const project = yield* projectService.discover({
78127
78154
  directory: scanDirectory,
78128
78155
  sourceFileCount
78129
78156
  });
78130
78157
  if (!isAnalyzableProject(project)) return yield* new ReactDoctorError({ reason: new NoReactDependency({ directory: scanDirectory }) });
78131
- const deadCodeSourceFileCount = input.retainExcludedProjectDeadCodeDiagnostics === true && precomputedSourceFiles !== null ? precomputedSourceFiles.length : project.sourceFileCount;
78158
+ const deadCodeSourceFileCount = input.retainExcludedProjectDeadCodeDiagnostics === true && precomputedSourceFilePaths !== null ? precomputedSourceFilePaths.length : project.sourceFileCount;
78132
78159
  const [repo, sha, defaultBranch] = yield* all([
78133
78160
  gitService.githubRepo(scanDirectory).pipe(orElseSucceed(() => null)),
78134
78161
  gitService.headSha(scanDirectory).pipe(orElseSucceed(() => null)),
@@ -78139,13 +78166,16 @@ const runInspect = (input, hooks = {}) => gen(function* () {
78139
78166
  directory: scanDirectory,
78140
78167
  repo
78141
78168
  }).pipe(orElseSucceed(() => null)) : succeed$2(null));
78142
- let lintIncludePaths = (input.skipExplicitIncludePathFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths])) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, includedPrecomputedSourceFiles ?? void 0);
78169
+ let lintIncludePaths = (input.skipExplicitIncludePathFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths])) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, includedPrecomputedSourceFilePaths ?? void 0);
78143
78170
  if (excludedProjectDirectories.length > 0) lintIncludePaths = filterPathsOutsideDirectories({
78144
78171
  rootDirectory: scanDirectory,
78145
- relativePaths: lintIncludePaths ?? includedPrecomputedSourceFiles ?? (yield* filesService.listSourceFiles(scanDirectory)),
78172
+ relativePaths: lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? (yield* filesService.listSourceFiles(scanDirectory)),
78146
78173
  excludedDirectories: excludedProjectDirectories
78147
78174
  });
78148
- const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? includedPrecomputedSourceFiles ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
78175
+ const suppliedSourceFiles = input.precomputedSourceFiles;
78176
+ const includedPrecomputedSourceFilePathSet = suppliedSourceFiles === void 0 || input.includePaths.length > 0 ? null : new Set(lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? []);
78177
+ const precomputedLintSourceFiles = includedPrecomputedSourceFilePathSet === null || suppliedSourceFiles === void 0 ? void 0 : suppliedSourceFiles.filter((sourceFile) => includedPrecomputedSourceFilePathSet.has(sourceFile.path));
78178
+ const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
78149
78179
  const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
78150
78180
  const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
78151
78181
  yield* beforeLint(project);
@@ -78278,6 +78308,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
78278
78308
  rootDirectory: scanDirectory,
78279
78309
  project,
78280
78310
  includePaths: lintIncludePaths ?? void 0,
78311
+ precomputedSourceFiles: precomputedLintSourceFiles,
78281
78312
  nodeBinaryPath: input.nodeBinaryPath,
78282
78313
  customRulesOnly: input.customRulesOnly,
78283
78314
  respectInlineDisables: input.respectInlineDisables,
@@ -78738,13 +78769,6 @@ const summarizeDiagnostics = (diagnostics, worstScore = null, worstScoreLabel =
78738
78769
  scoreLabel: worstScoreLabel
78739
78770
  };
78740
78771
  };
78741
- /**
78742
- * Whether project discovery resolved a React-compatible runtime (React or
78743
- * Preact, which ships the same hooks + JSX model). This is the same
78744
- * predicate that grants the `react` capability, so `false` means every
78745
- * React-runtime rule family was gated off for the project.
78746
- */
78747
- const hasReactRuntime = (project) => project.reactVersion !== null || project.preactVersion !== null;
78748
78772
  const isScanComplete = (input) => input.analyzedFileCount !== void 0 && input.scannedFileCount !== void 0 && input.skippedCheckCount === 0 && input.skippedCheckReasonCount === 0 && input.analyzedFileCount === input.scannedFileCount;
78749
78773
  const toJsonDiff = (diff) => {
78750
78774
  if (!diff) return null;
@@ -79006,31 +79030,43 @@ const getChangedLineRanges = (input) => runPromise(gen(function* () {
79006
79030
  * instead of being improvised per diagnostic.
79007
79031
  */
79008
79032
  const buildRuleDocsUrl = (plugin, rule) => `${DOCS_RULES_BASE_URL}/${plugin}/${rule}`;
79009
- const collectSourceFileCountsByDirectory = async (rootDirectory, projectDirectories, signal) => {
79033
+ const collectSourceFilesByDirectory = async (rootDirectory, projectDirectories, signal) => {
79010
79034
  const resolvedRootDirectory = Path.resolve(rootDirectory);
79011
- const sourceFileCounts = /* @__PURE__ */ new Map();
79035
+ const sourceFilesByDirectory = /* @__PURE__ */ new Map();
79012
79036
  const projectDirectoryByRelativePath = /* @__PURE__ */ new Map();
79013
79037
  for (const projectDirectory of projectDirectories) {
79014
79038
  const resolvedProjectDirectory = Path.resolve(projectDirectory);
79015
79039
  const relativeDirectory = Path.relative(resolvedRootDirectory, resolvedProjectDirectory);
79016
- if (Path.isAbsolute(relativeDirectory) || relativeDirectory.startsWith("..")) continue;
79017
- sourceFileCounts.set(resolvedProjectDirectory, 0);
79040
+ if (Path.isAbsolute(relativeDirectory) || relativeDirectory === ".." || relativeDirectory.startsWith(`..${Path.sep}`)) continue;
79041
+ sourceFilesByDirectory.set(resolvedProjectDirectory, []);
79018
79042
  projectDirectoryByRelativePath.set(relativeDirectory.replaceAll(Path.sep, "/"), resolvedProjectDirectory);
79019
79043
  }
79020
- const sourceFilePaths = await listSourceFilesCooperative(resolvedRootDirectory, signal);
79021
- for (const sourceFilePath of sourceFilePaths) {
79022
- let relativeDirectory = Path.posix.dirname(sourceFilePath);
79044
+ const sourceFiles = await listSourceFilesWithSizeCooperative(resolvedRootDirectory, signal);
79045
+ for (const sourceFile of sourceFiles) {
79046
+ let relativeDirectory = Path.posix.dirname(sourceFile.path);
79023
79047
  while (true) {
79024
79048
  const normalizedRelativeDirectory = relativeDirectory === "." ? "" : relativeDirectory;
79025
79049
  const projectDirectory = projectDirectoryByRelativePath.get(normalizedRelativeDirectory);
79026
79050
  if (projectDirectory !== void 0) {
79027
- sourceFileCounts.set(projectDirectory, (sourceFileCounts.get(projectDirectory) ?? 0) + 1);
79051
+ const projectRelativePath = Path.posix.relative(normalizedRelativeDirectory, sourceFile.path);
79052
+ const projectSourceFiles = sourceFilesByDirectory.get(projectDirectory);
79053
+ if (projectSourceFiles === void 0) break;
79054
+ projectSourceFiles.push({
79055
+ path: projectRelativePath,
79056
+ sizeBytes: sourceFile.sizeBytes
79057
+ });
79028
79058
  break;
79029
79059
  }
79030
79060
  if (relativeDirectory === ".") break;
79031
79061
  relativeDirectory = Path.posix.dirname(relativeDirectory);
79032
79062
  }
79033
79063
  }
79064
+ return sourceFilesByDirectory;
79065
+ };
79066
+ const collectSourceFileCountsByDirectory = async (rootDirectory, projectDirectories, signal) => {
79067
+ const sourceFilesByDirectory = await collectSourceFilesByDirectory(rootDirectory, projectDirectories, signal);
79068
+ const sourceFileCounts = /* @__PURE__ */ new Map();
79069
+ for (const [projectDirectory, sourceFiles] of sourceFilesByDirectory) sourceFileCounts.set(projectDirectory, sourceFiles.length);
79034
79070
  return sourceFileCounts;
79035
79071
  };
79036
79072
  const computeConfigFingerprint = (projectDirectory, version) => {
@@ -79107,6 +79143,15 @@ const groupBy = (items, keyFn) => {
79107
79143
  * a 404. Gate the directive on this predicate.
79108
79144
  */
79109
79145
  const hasPublishedFixRecipe = (diagnostic) => diagnostic.plugin === "react-doctor" && Object.hasOwn(REACT_DOCTOR_RULE_REGISTRY, diagnostic.rule);
79146
+ const AMBIENT_PROJECT_CAPABILITIES = new Set([
79147
+ "unknown",
79148
+ "typescript",
79149
+ "pre-es2023"
79150
+ ]);
79151
+ const hasSupportedFrameworkOrLibrary = (project) => {
79152
+ for (const capability of buildCapabilities(project)) if (!AMBIENT_PROJECT_CAPABILITIES.has(capability)) return true;
79153
+ return false;
79154
+ };
79110
79155
  const stringValues = (values) => Array.isArray(values) ? values.filter((value) => typeof value === "string") : [];
79111
79156
  const unionValues = (baseValues, overrideValues) => [...new Set([...stringValues(baseValues), ...stringValues(overrideValues)])];
79112
79157
  const mergeIgnores = (baseIgnore, overrideIgnore) => {
@@ -79503,7 +79548,7 @@ const makeNoopConsole = () => ({
79503
79548
  });
79504
79549
  //#endregion
79505
79550
  //#region src/cli/utils/version.ts
79506
- const VERSION = "0.9.11";
79551
+ const VERSION = "0.9.12-dev.a2b460d";
79507
79552
  //#endregion
79508
79553
  //#region src/cli/utils/json-mode.ts
79509
79554
  let context = null;
@@ -79828,7 +79873,7 @@ const recordDistribution = (name, value, options = {}) => {
79828
79873
  } catch {}
79829
79874
  };
79830
79875
  //#endregion
79831
- export { CONFIG_SCHEMA_URL as $, orElseSucceed as $n, getCategoryImpact as $t, SCAN_RESULT_CACHE_MAX_HASHED_FILE_SIZE_BYTES as A, resolveReactDoctorCacheDir as An, anonymizeInPlace as At, isGitHookEnvironment as B, validateConfigTypes as Bn, computeConfigFingerprint as Bt, GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS as C, mapWithConcurrency as Cn, SHARE_BASE_URL as Ct, REACT_DOCTOR_CONFIG_PROJECT_NAME as D, remainingDeadlineBudgetMs as Dn, SidecarLintCacheEnabled as Dt, NANOSECONDS_PER_MILLISECOND as E, messageFromUnknown as En, Score as Et, STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES as F, scrubSensitivePaths as Fn, buildSkippedChecks as Ft, isCiOrCodingAgentEnvironment as G, log as Gn, discoverReactSubprojects as Gt, ACTION_INPUT_ENVIRONMENT_VARIABLES as H, Console as Hn, createNodeReadFileLinesSync as Ht, TUI_REPORT_COMPACT_MAX_ROWS as I, setColorEnabled as In, calculateScore as It, CANONICAL_DISCORD_URL as J, decodeUnknownSync as Jn, filterSourceFiles as Jt, isCodingAgentEnvironment as K, warn$1 as Kn, filterDiagnosticsForSurface as Kt, TUI_REPORT_DETAIL_WIDTH_FRACTION as L, summarizeDiagnostics as Ln, canonicalizeUserRuleKey as Lt, SENTRY_FLUSH_TIMEOUT_MS as M, resolveScanTarget as Mn, atomicWriteJson as Mt, SENTRY_RELEASE_PREFIX as N, restoreLegacyThrow as Nn, buildJsonReport as Nt, RUN_GIT_MAX_BUFFER_BYTES as O, resolveGithubActionsScoreMetadata as On, StagedFiles as Ot, STAGED_FILES_TEMP_DIR_PREFIX as P, runInspect as Pn, buildRuleDocsUrl as Pt, COMPILER_CLEANUP_RULE_KEYS as Q, map$3 as Qn, getBaselineDiffPlan as Qt, CliInputError as R, toCanonicalPath as Rn, clearConfigCache as Rt, CI_TRUST_COMPANIES as S, loadConfigWithSource as Sn, Reporter as St, MINIMUM_VTE_VERSION_FOR_HYPERLINKS as T, mergeReactDoctorConfigs as Tn, STAGED_FILES_PROJECT_CONFIG_FILENAMES as Tt, detectRunnerOs as U, error as Un, createOxlintSpawnSlots as Ut, isDebugFlagEnabled as V, yieldToEventLoop as Vn, computeDiagnosticDelta as Vt, isCiEnvironment as W, info as Wn, detectAiTrainingEnvironment as Wt, CI_URL as X, gen as Xn, formatErrorChain as Xt, CANONICAL_GITHUB_URL as Y, make$30 as Yn, findLegacyConfig as Yt, COMPILER_CLEANUP_BUCKET as Z, makeSpan$1 as Zn, formatReactDoctorError as Zt, makeNoopConsole as _, isSameRuleKey as _n, ParentSpan as _r, OxlintConcurrency as _t, isEnvFlagEnabled as a, hasPublishedFixRecipe as an, runSync as ar, Files as at, AXIOM_TRACES_DATASET as b, listSourceFiles as bn, Progress as bt, setSentryProjectInfo as c, highlighter as cn, void_ as cr, Git as ct, isJsonModeActive as d, isFile as dn, provide$2 as dr, LEGACY_CONFIG_FILENAME as dt, getChangedLineRanges as en, promise as er, Config as et, setJsonReportDirectory as f, isMonorepoRoot as fn, succeed$3 as fr, LintPartialFailures as ft, VERSION as g, isReactDoctorError as gn, void_$1 as gr, OXLINT_NODE_REQUIREMENT as gt, writeJsonReport as h, isProjectDiscoveryError as hn, fail$5 as hr, NodeResolver as ht, isTelemetryEnabled as i, groupBy as in, runPromise as ir, ENTERPRISE_CONTACT_URL as it, SENTRY_DSN as j, resolveScanConcurrency as jn, anonymizeText as jt, SCAN_RESULT_CACHE_FILENAME as k, resolveLintBatchOrdering as kn, SupplyChain as kt, getRunId as l, isDirectory as ln, buildWithScope as lr, HTML_FILE_PATTERN as lt, writeJsonErrorReport as m, isPlainObject as mn, makeUnsafe$5 as mr, MILLISECONDS_PER_SECOND as mt, recordDistribution as n, getDiffInfo as nn, provideContext as nr, DOCS_URL as nt, buildSentryScope as o, hasReactRuntime as on, sync as or, GITHUB_ACTIONS_SETUP_URL as ot, setJsonReportMode as p, isPathInsideDirectory as pn, close as pr, Linter as pt, AXIOM_DEFAULT_DOMAIN as q, Diagnostic as qn, filterPathsOutsideDirectories as qt, toSpanAttributes as r, getEquivalentRuleKeys as rn, provideService$2 as rr, DeadCode as rt, buildSentryProjectContext as s, hashFileContents as sn, try_ as sr, GIT_SHOW_MAX_BUFFER_BYTES as st, recordCount as t, getDiagnosticRuleIdentity as tn, provide as tr, DIAGNOSTIC_CATEGORY_BUCKETS as tt, enableJsonMode as u, isErrnoException as un, mergeAll$1 as ur, JSX_FILE_PATTERN as ut, AXIOM_INGEST_TOKEN as v, isScanComplete as vn, OxlintSpawnSlots as vt, METRIC as w, materializeSourceTree as wn, SKILL_NAME as wt, BASELINE_FILES_TEMP_DIR_PREFIX as x, listWorkspacePackages as xn, Project as xt, AXIOM_METRICS_DATASET as y, layerObservability as yn, PerFileLintCacheEnabled as yt, isNonInteractiveEnvironment as z, toRelativePath as zn, collectSourceFileCountsByDirectory as zt };
79876
+ export { CONFIG_SCHEMA_URL as $, orElseSucceed as $n, getCategoryImpact as $t, SCAN_RESULT_CACHE_MAX_HASHED_FILE_SIZE_BYTES as A, resolveReactDoctorCacheDir as An, anonymizeInPlace as At, isGitHookEnvironment as B, validateConfigTypes as Bn, computeConfigFingerprint as Bt, GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS as C, mapWithConcurrency as Cn, SHARE_BASE_URL as Ct, REACT_DOCTOR_CONFIG_PROJECT_NAME as D, remainingDeadlineBudgetMs as Dn, SidecarLintCacheEnabled as Dt, NANOSECONDS_PER_MILLISECOND as E, messageFromUnknown as En, Score as Et, STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES as F, scrubSensitivePaths as Fn, buildSkippedChecks as Ft, isCiOrCodingAgentEnvironment as G, log as Gn, discoverReactSubprojects as Gt, ACTION_INPUT_ENVIRONMENT_VARIABLES as H, Console as Hn, createNodeReadFileLinesSync as Ht, TUI_REPORT_COMPACT_MAX_ROWS as I, setColorEnabled as In, calculateScore as It, CANONICAL_DISCORD_URL as J, decodeUnknownSync as Jn, filterSourceFiles as Jt, isCodingAgentEnvironment as K, warn$1 as Kn, filterDiagnosticsForSurface as Kt, TUI_REPORT_DETAIL_WIDTH_FRACTION as L, summarizeDiagnostics as Ln, canonicalizeUserRuleKey as Lt, SENTRY_FLUSH_TIMEOUT_MS as M, resolveScanTarget as Mn, atomicWriteJson as Mt, SENTRY_RELEASE_PREFIX as N, restoreLegacyThrow as Nn, buildJsonReport as Nt, RUN_GIT_MAX_BUFFER_BYTES as O, resolveGithubActionsScoreMetadata as On, StagedFiles as Ot, STAGED_FILES_TEMP_DIR_PREFIX as P, runInspect as Pn, buildRuleDocsUrl as Pt, COMPILER_CLEANUP_RULE_KEYS as Q, map$3 as Qn, getBaselineDiffPlan as Qt, CliInputError as R, toCanonicalPath as Rn, clearConfigCache as Rt, CI_TRUST_COMPANIES as S, loadConfigWithSource as Sn, Reporter as St, MINIMUM_VTE_VERSION_FOR_HYPERLINKS as T, mergeReactDoctorConfigs as Tn, STAGED_FILES_PROJECT_CONFIG_FILENAMES as Tt, detectRunnerOs as U, error as Un, createOxlintSpawnSlots as Ut, isDebugFlagEnabled as V, yieldToEventLoop as Vn, computeDiagnosticDelta as Vt, isCiEnvironment as W, info as Wn, detectAiTrainingEnvironment as Wt, CI_URL as X, gen as Xn, formatErrorChain as Xt, CANONICAL_GITHUB_URL as Y, make$30 as Yn, findLegacyConfig as Yt, COMPILER_CLEANUP_BUCKET as Z, makeSpan$1 as Zn, formatReactDoctorError as Zt, makeNoopConsole as _, isSameRuleKey as _n, ParentSpan as _r, OxlintConcurrency as _t, isEnvFlagEnabled as a, hasPublishedFixRecipe as an, runSync as ar, Files as at, AXIOM_TRACES_DATASET as b, listSourceFiles as bn, Progress as bt, setSentryProjectInfo as c, highlighter as cn, void_ as cr, Git as ct, isJsonModeActive as d, isFile as dn, provide$2 as dr, LEGACY_CONFIG_FILENAME as dt, getChangedLineRanges as en, promise as er, Config as et, setJsonReportDirectory as f, isMonorepoRoot as fn, succeed$3 as fr, LintPartialFailures as ft, VERSION as g, isReactDoctorError as gn, void_$1 as gr, OXLINT_NODE_REQUIREMENT as gt, writeJsonReport as h, isProjectDiscoveryError as hn, fail$5 as hr, NodeResolver as ht, isTelemetryEnabled as i, groupBy as in, runPromise as ir, ENTERPRISE_CONTACT_URL as it, SENTRY_DSN as j, resolveScanConcurrency as jn, anonymizeText as jt, SCAN_RESULT_CACHE_FILENAME as k, resolveLintBatchOrdering as kn, SupplyChain as kt, getRunId as l, isDirectory as ln, buildWithScope as lr, HTML_FILE_PATTERN as lt, writeJsonErrorReport as m, isPlainObject as mn, makeUnsafe$5 as mr, MILLISECONDS_PER_SECOND as mt, recordDistribution as n, getDiffInfo as nn, provideContext as nr, DOCS_URL as nt, buildSentryScope as o, hasSupportedFrameworkOrLibrary as on, sync as or, GITHUB_ACTIONS_SETUP_URL as ot, setJsonReportMode as p, isPathInsideDirectory as pn, close as pr, Linter as pt, AXIOM_DEFAULT_DOMAIN as q, Diagnostic as qn, filterPathsOutsideDirectories as qt, toSpanAttributes as r, getEquivalentRuleKeys as rn, provideService$2 as rr, DeadCode as rt, buildSentryProjectContext as s, hashFileContents as sn, try_ as sr, GIT_SHOW_MAX_BUFFER_BYTES as st, recordCount as t, getDiagnosticRuleIdentity as tn, provide as tr, DIAGNOSTIC_CATEGORY_BUCKETS as tt, enableJsonMode as u, isErrnoException as un, mergeAll$1 as ur, JSX_FILE_PATTERN as ut, AXIOM_INGEST_TOKEN as v, isScanComplete as vn, OxlintSpawnSlots as vt, METRIC as w, materializeSourceTree as wn, SKILL_NAME as wt, BASELINE_FILES_TEMP_DIR_PREFIX as x, listWorkspacePackages as xn, Project as xt, AXIOM_METRICS_DATASET as y, layerObservability as yn, PerFileLintCacheEnabled as yt, isNonInteractiveEnvironment as z, toRelativePath as zn, collectSourceFileCountsByDirectory as zt };
79832
79877
 
79833
- //# sourceMappingURL=record-metric-CJxSHfJD.js.map
79834
- //# debugId=23657ac7-3a23-5dc3-a8b9-100f22c56678
79878
+ //# sourceMappingURL=record-metric-CMe2d1Xv.js.map
79879
+ //# debugId=7be6c41a-aed3-5157-8122-572c03c4bc93
@@ -1,7 +1,7 @@
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]="93f4cf84-e729-55d2-87fc-383af0704e34")}catch(e){}}();
3
- import { J as CANONICAL_DISCORD_URL, M as SENTRY_FLUSH_TIMEOUT_MS, Un as error, Xn as gen, Xt as formatErrorChain, Y as CANONICAL_GITHUB_URL, Zt as formatReactDoctorError, ar as runSync, cn as highlighter, g as VERSION, gn as isReactDoctorError, l as getRunId, o as buildSentryScope, t as recordCount, un as isErrnoException, w as METRIC } from "./record-metric-CJxSHfJD.js";
4
- import { c as isExpectedUserError, i as recordRunTraceId, l as formatEnvironmentError, n as getActiveRunTrace, s as shutdownTelemetry, u as isEnvironmentError } from "./unref-stdin-Dc8ipkaw.js";
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]="50420dc6-650c-5930-ad21-75a2e964489e")}catch(e){}}();
3
+ import { J as CANONICAL_DISCORD_URL, M as SENTRY_FLUSH_TIMEOUT_MS, Un as error, Xn as gen, Xt as formatErrorChain, Y as CANONICAL_GITHUB_URL, Zt as formatReactDoctorError, ar as runSync, cn as highlighter, g as VERSION, gn as isReactDoctorError, l as getRunId, o as buildSentryScope, t as recordCount, un as isErrnoException, w as METRIC } from "./record-metric-CMe2d1Xv.js";
4
+ import { c as isExpectedUserError, i as recordRunTraceId, l as formatEnvironmentError, n as getActiveRunTrace, s as shutdownTelemetry, u as isEnvironmentError } from "./unref-stdin-Cxhw67r6.js";
5
5
  import * as Sentry from "@sentry/node";
6
6
  //#region src/cli/utils/handle-error.ts
7
7
  const OTLP_ENDPOINT_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_ENDPOINT";
@@ -160,5 +160,5 @@ const reportErrorToSentry = async (error) => {
160
160
  //#endregion
161
161
  export { handleError as n, handleUserError as r, reportErrorToSentry as t };
162
162
 
163
- //# sourceMappingURL=report-error-CAEixMg1.js.map
164
- //# debugId=93f4cf84-e729-55d2-87fc-383af0704e34
163
+ //# sourceMappingURL=report-error-1l7v6_dE.js.map
164
+ //# debugId=50420dc6-650c-5930-ad21-75a2e964489e
@@ -1,7 +1,7 @@
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]="86663d48-cdc4-5e67-ad00-8a375db615d2")}catch(e){}}();
3
- import { D as REACT_DOCTOR_CONFIG_PROJECT_NAME, t as recordCount, w as METRIC } from "./record-metric-CJxSHfJD.js";
4
- import { u as isCommandAvailable } from "./install-github-workflow-Dev2F6Ea.js";
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]="58b948e5-fd1e-5347-af35-6bb38cf4316b")}catch(e){}}();
3
+ import { D as REACT_DOCTOR_CONFIG_PROJECT_NAME, t as recordCount, w as METRIC } from "./record-metric-CMe2d1Xv.js";
4
+ import { u as isCommandAvailable } from "./install-github-workflow-DkMicv8E.js";
5
5
  import { spawn } from "node:child_process";
6
6
  import * as path$1 from "node:path";
7
7
  import process$1 from "node:process";
@@ -275,5 +275,5 @@ const reportWorkflowResult = (workflowSpinner, result, projectRoot) => {
275
275
  //#endregion
276
276
  export { recordGate as a, ACTION_UPGRADE_EVENT as c, INSTALL_AGENTS_PREFERENCE_ID as d, ONBOARDING_EVENT as f, detectAvailableAgents as h, readPreference as i, CI_PITCH_EVENT as l, computeDefaultSelectedAgents as m, openUrl as n, runMigrations as o, SETUP_HINT_EVENT as p, isGatePending as r, writePreference as s, reportWorkflowResult as t, HANDOFF_TARGET_PREFERENCE_ID as u };
277
277
 
278
- //# sourceMappingURL=report-workflow-result-C0jbKH8p.js.map
279
- //# debugId=86663d48-cdc4-5e67-ad00-8a375db615d2
278
+ //# sourceMappingURL=report-workflow-result-EagkH_v9.js.map
279
+ //# debugId=58b948e5-fd1e-5347-af35-6bb38cf4316b