react-doctor 0.9.4-dev.8b97fdc → 0.9.4-dev.bafef41

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]="cae1c0fa-086e-5609-a7c4-729ec799fb2c")}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]="e74e6a68-20e1-59fe-8db0-62b87e8fe049")}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";
@@ -65501,17 +65501,20 @@ const SUPPLY_CHAIN_IGNORED_PACKAGES = new Set(["next"]);
65501
65501
  const isErrnoException = (error) => error instanceof Error && "code" in error;
65502
65502
  const IGNORABLE_READDIR_ERROR_CODES = new Set([
65503
65503
  "EACCES",
65504
+ "EBUSY",
65504
65505
  "EPERM",
65505
65506
  "ENOENT",
65506
65507
  "ENOTDIR",
65507
65508
  "EINVAL",
65508
65509
  "ELOOP",
65509
- "ENAMETOOLONG"
65510
+ "ENAMETOOLONG",
65511
+ "ETIMEDOUT",
65512
+ "UNKNOWN"
65510
65513
  ]);
65511
65514
  const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
65512
65515
  const readDirectoryEntries = (directoryPath) => {
65513
65516
  try {
65514
- return NFS.readdirSync(directoryPath, { withFileTypes: true });
65517
+ return fs.readdirSync(directoryPath, { withFileTypes: true });
65515
65518
  } catch (error) {
65516
65519
  if (isIgnorableReaddirError(error)) return [];
65517
65520
  throw error;
@@ -65519,14 +65522,14 @@ const readDirectoryEntries = (directoryPath) => {
65519
65522
  };
65520
65523
  const isFile = (filePath) => {
65521
65524
  try {
65522
- return NFS.statSync(filePath).isFile();
65525
+ return fs.statSync(filePath).isFile();
65523
65526
  } catch {
65524
65527
  return false;
65525
65528
  }
65526
65529
  };
65527
65530
  const isDirectory = (directoryPath) => {
65528
65531
  try {
65529
- return NFS.statSync(directoryPath).isDirectory();
65532
+ return fs.statSync(directoryPath).isDirectory();
65530
65533
  } catch {
65531
65534
  return false;
65532
65535
  }
@@ -65950,7 +65953,12 @@ const mergeCompilerOptions = (inherited, current) => {
65950
65953
  };
65951
65954
  };
65952
65955
  const readResolvedCompilerOptions = (tsConfigPath, extendsDepth, visitedPaths) => {
65953
- const realPath = NFS.realpathSync.native(tsConfigPath);
65956
+ let realPath;
65957
+ try {
65958
+ realPath = NFS.realpathSync.native(tsConfigPath);
65959
+ } catch {
65960
+ return null;
65961
+ }
65954
65962
  if (visitedPaths.has(realPath)) return null;
65955
65963
  const tsConfig = readTsConfig(realPath);
65956
65964
  if (!tsConfig) return null;
@@ -66478,27 +66486,30 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
66478
66486
  }
66479
66487
  return null;
66480
66488
  };
66481
- const configExpressionMayDefineProperty = (expression, propertyName, analysis) => {
66489
+ const configExpressionMayDefineProperty = (expression, propertyName, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
66482
66490
  let resolvedExpression = expression;
66483
66491
  while (ts.isParenthesizedExpression(resolvedExpression) || ts.isAsExpression(resolvedExpression) || ts.isTypeAssertionExpression(resolvedExpression) || ts.isSatisfiesExpression(resolvedExpression) || ts.isNonNullExpression(resolvedExpression)) resolvedExpression = resolvedExpression.expression;
66492
+ if (visitedExpressions.has(resolvedExpression)) return true;
66493
+ const nextVisitedExpressions = new Set(visitedExpressions);
66494
+ nextVisitedExpressions.add(resolvedExpression);
66484
66495
  if (ts.isIdentifier(resolvedExpression)) {
66485
66496
  if (analysis.localBindings.has(resolvedExpression.text)) {
66486
66497
  const localReference = analysis.localBindings.get(resolvedExpression.text);
66487
- return localReference?.expression ? configExpressionMayDefineProperty(localReference.expression, propertyName, localReference.analysis) : true;
66498
+ return localReference?.expression ? configExpressionMayDefineProperty(localReference.expression, propertyName, localReference.analysis, nextVisitedExpressions) : true;
66488
66499
  }
66489
66500
  const scopedBinding = getScopedConfigBinding(resolvedExpression);
66490
- if (scopedBinding.wasFound) return scopedBinding.initializer ? configExpressionMayDefineProperty(scopedBinding.initializer, propertyName, analysis) : true;
66501
+ if (scopedBinding.wasFound) return scopedBinding.initializer ? configExpressionMayDefineProperty(scopedBinding.initializer, propertyName, analysis, nextVisitedExpressions) : true;
66491
66502
  const topLevelBinding = getTopLevelBinding(analysis.sourceFile, resolvedExpression.text);
66492
- return topLevelBinding && ts.isExpression(topLevelBinding) ? configExpressionMayDefineProperty(topLevelBinding, propertyName, analysis) : true;
66503
+ return topLevelBinding && ts.isExpression(topLevelBinding) ? configExpressionMayDefineProperty(topLevelBinding, propertyName, analysis, nextVisitedExpressions) : true;
66493
66504
  }
66494
66505
  if (ts.isConditionalExpression(resolvedExpression)) {
66495
- if (isStaticallyTruthyConfigExpression(resolvedExpression.condition, analysis)) return configExpressionMayDefineProperty(resolvedExpression.whenTrue, propertyName, analysis);
66496
- if (isStaticallyDisabledConfigExpression(resolvedExpression.condition, analysis)) return configExpressionMayDefineProperty(resolvedExpression.whenFalse, propertyName, analysis);
66497
- return configExpressionMayDefineProperty(resolvedExpression.whenTrue, propertyName, analysis) || configExpressionMayDefineProperty(resolvedExpression.whenFalse, propertyName, analysis);
66506
+ if (isStaticallyTruthyConfigExpression(resolvedExpression.condition, analysis)) return configExpressionMayDefineProperty(resolvedExpression.whenTrue, propertyName, analysis, nextVisitedExpressions);
66507
+ if (isStaticallyDisabledConfigExpression(resolvedExpression.condition, analysis)) return configExpressionMayDefineProperty(resolvedExpression.whenFalse, propertyName, analysis, nextVisitedExpressions);
66508
+ return configExpressionMayDefineProperty(resolvedExpression.whenTrue, propertyName, analysis, nextVisitedExpressions) || configExpressionMayDefineProperty(resolvedExpression.whenFalse, propertyName, analysis, nextVisitedExpressions);
66498
66509
  }
66499
66510
  if (!ts.isObjectLiteralExpression(resolvedExpression)) return true;
66500
66511
  return resolvedExpression.properties.some((property) => {
66501
- if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
66512
+ if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis, nextVisitedExpressions);
66502
66513
  if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
66503
66514
  const staticPropertyName = getStaticPropertyName$2(property.name);
66504
66515
  return staticPropertyName === null || staticPropertyName === propertyName;
@@ -66574,7 +66585,13 @@ const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform,
66574
66585
  if (visitedModules.has(moduleVisitKey)) return false;
66575
66586
  const nextVisitedModules = new Set(visitedModules);
66576
66587
  nextVisitedModules.add(moduleVisitKey);
66577
- return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList, argumentAnalysis);
66588
+ let sourceText;
66589
+ try {
66590
+ sourceText = NFS.readFileSync(filePath, "utf-8");
66591
+ } catch {
66592
+ return false;
66593
+ }
66594
+ return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, sourceText), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList, argumentAnalysis);
66578
66595
  };
66579
66596
  const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
66580
66597
  const analysis = {
@@ -70077,6 +70094,43 @@ const validateStringArrayField = (fieldName, value) => {
70077
70094
  return false;
70078
70095
  });
70079
70096
  };
70097
+ const validateIgnoreOverride = (rawOverride, index) => {
70098
+ const fieldName = `ignore.overrides[${index}]`;
70099
+ if (!isRecord$1(rawOverride)) {
70100
+ warnConfigIssue(`config field "${fieldName}" must be an object (got ${typeof rawOverride}); ignoring this override.`);
70101
+ return;
70102
+ }
70103
+ const files = validateStringArrayField(`${fieldName}.files`, rawOverride.files);
70104
+ if (files === void 0) return void 0;
70105
+ const validatedOverride = { files };
70106
+ if (rawOverride.rules !== void 0) {
70107
+ const rules = validateStringArrayField(`${fieldName}.rules`, rawOverride.rules);
70108
+ if (rules !== void 0) validatedOverride.rules = rules;
70109
+ }
70110
+ return validatedOverride;
70111
+ };
70112
+ const validateIgnoreField = (rawIgnore) => {
70113
+ if (!isRecord$1(rawIgnore)) {
70114
+ warnConfigIssue(`config field "ignore" must be an object (got ${typeof rawIgnore}); ignoring this field.`);
70115
+ return;
70116
+ }
70117
+ const validatedIgnore = {};
70118
+ for (const fieldName of [
70119
+ "rules",
70120
+ "files",
70121
+ "tags"
70122
+ ]) {
70123
+ if (rawIgnore[fieldName] === void 0) continue;
70124
+ const validatedValues = validateStringArrayField(`ignore.${fieldName}`, rawIgnore[fieldName]);
70125
+ if (validatedValues !== void 0) validatedIgnore[fieldName] = validatedValues;
70126
+ }
70127
+ if (rawIgnore.overrides !== void 0) if (!Array.isArray(rawIgnore.overrides)) warnConfigIssue(`config field "ignore.overrides" must be an array (got ${typeof rawIgnore.overrides}); ignoring this field.`);
70128
+ else validatedIgnore.overrides = rawIgnore.overrides.flatMap((rawOverride, index) => {
70129
+ const validatedOverride = validateIgnoreOverride(rawOverride, index);
70130
+ return validatedOverride ? [validatedOverride] : [];
70131
+ });
70132
+ return validatedIgnore;
70133
+ };
70080
70134
  const validateSurfaceControls = (surface, rawControls) => {
70081
70135
  if (!isRecord$1(rawControls)) {
70082
70136
  warnConfigIssue(`config field "surfaces.${surface}" must be an object (got ${typeof rawControls}); ignoring this surface.`);
@@ -70152,6 +70206,7 @@ const validateConfigTypes = (config) => {
70152
70206
  for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
70153
70207
  for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
70154
70208
  for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
70209
+ applyFieldValidator(config, validated, "ignore", validateIgnoreField);
70155
70210
  applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
70156
70211
  for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
70157
70212
  applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
@@ -71844,7 +71899,7 @@ const collectScriptMotionEvidence = (sourceFile, typeChecker, program) => {
71844
71899
  if (calleeEvidence.isReducedMotionHook && isExpressionValueConsumed(node)) evidence.hasReducedMotionHandling = true;
71845
71900
  }
71846
71901
  if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
71847
- const tagEvidence = ts.isJsxNamespacedName(node.tagName) ? EMPTY_MOTION_EXPRESSION_EVIDENCE : resolveMotionExpressionEvidence(node.tagName, typeChecker, program);
71902
+ const tagEvidence = ts.isIdentifier(node.tagName) || ts.isPropertyAccessExpression(node.tagName) ? resolveMotionExpressionEvidence(node.tagName, typeChecker, program) : EMPTY_MOTION_EXPRESSION_EVIDENCE;
71848
71903
  if (tagEvidence.isMotionComponent || tagEvidence.isMotionComponentFactory) evidence.hasMotionUse = true;
71849
71904
  if (tagEvidence.isMotionConfig && jsxElementHasReducedMotionConfiguration(node.attributes, typeChecker)) evidence.hasReducedMotionHandling = true;
71850
71905
  }
@@ -73844,7 +73899,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
73844
73899
  changedFiles: yield* mergeUntracked(directory, splitNullSeparated(diff.stdout), includeUntracked),
73845
73900
  isCurrentChanges: false
73846
73901
  };
73847
- }).pipe(withSpan("Git.diffSelection")),
73902
+ }).pipe(catchReasons("ReactDoctorError", { GitInvocationFailed: () => succeed$2(null) }, (_reason, error) => fail$4(error)), withSpan("Git.diffSelection")),
73848
73903
  stagedFilePaths: (directory) => runGit(directory, [
73849
73904
  "diff",
73850
73905
  "--no-ext-diff",
@@ -74060,6 +74115,33 @@ const detectUserLintConfigPaths = (rootDirectory) => {
74060
74115
  return [];
74061
74116
  };
74062
74117
  const DISABLE_DIRECTIVE_PATTERN = /(eslint|oxlint)-disable/;
74118
+ const neutralizedFileLeases = /* @__PURE__ */ new Map();
74119
+ const activeNeutralizationInitializations = /* @__PURE__ */ new Set();
74120
+ const directoriesOverlap = (left, right) => {
74121
+ const isWithin = (parent, candidate) => {
74122
+ const relativePath = Path.relative(parent, candidate);
74123
+ return relativePath.length === 0 || !relativePath.startsWith(`..${Path.sep}`) && relativePath !== ".." && !Path.isAbsolute(relativePath);
74124
+ };
74125
+ return isWithin(left, right) || isWithin(right, left);
74126
+ };
74127
+ const withOverlappingInitializationLock = async (rootDirectory, operation) => {
74128
+ const blockers = [...activeNeutralizationInitializations].filter((initialization) => directoriesOverlap(initialization.rootDirectory, rootDirectory)).map((initialization) => initialization.done);
74129
+ let release;
74130
+ const initialization = {
74131
+ rootDirectory,
74132
+ done: new Promise((resolve) => {
74133
+ release = resolve;
74134
+ })
74135
+ };
74136
+ activeNeutralizationInitializations.add(initialization);
74137
+ await Promise.all(blockers);
74138
+ try {
74139
+ return await operation();
74140
+ } finally {
74141
+ activeNeutralizationInitializations.delete(initialization);
74142
+ release();
74143
+ }
74144
+ };
74063
74145
  const findFilesWithDisableDirectivesViaGit = async (rootDirectory, includePaths) => {
74064
74146
  const program = gen(function* () {
74065
74147
  return yield* (yield* Git).grep({
@@ -74102,34 +74184,84 @@ const findFilesWithDisableDirectivesViaFilesystem = (rootDirectory, includePaths
74102
74184
  };
74103
74185
  const findFilesWithDisableDirectives = async (rootDirectory, includePaths) => await findFilesWithDisableDirectivesViaGit(rootDirectory, includePaths) ?? findFilesWithDisableDirectivesViaFilesystem(rootDirectory, includePaths);
74104
74186
  const neutralizeContent = (content) => content.replaceAll("eslint-disable", "eslint_disable").replaceAll("oxlint-disable", "oxlint_disable");
74105
- const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
74106
- const filePaths = await findFilesWithDisableDirectives(rootDirectory, includePaths);
74107
- const originalContents = /* @__PURE__ */ new Map();
74187
+ const collectNeutralizationCandidatePaths = (rootDirectory, discoveredRelativePaths, includePaths) => {
74188
+ const resolvedRootDirectory = NFS.realpathSync(rootDirectory);
74189
+ const requestedPaths = includePaths && includePaths.length > 0 ? new Set(includePaths.flatMap((includePath) => {
74190
+ try {
74191
+ return [NFS.realpathSync(Path.resolve(resolvedRootDirectory, includePath))];
74192
+ } catch {
74193
+ return [];
74194
+ }
74195
+ })) : null;
74196
+ const candidatePaths = /* @__PURE__ */ new Set();
74197
+ for (const relativePath of discoveredRelativePaths) try {
74198
+ candidatePaths.add(NFS.realpathSync(Path.resolve(resolvedRootDirectory, relativePath)));
74199
+ } catch {
74200
+ continue;
74201
+ }
74202
+ for (const leasedPath of neutralizedFileLeases.keys()) {
74203
+ const relativePath = Path.relative(resolvedRootDirectory, leasedPath);
74204
+ if (!(relativePath.length === 0 || !relativePath.startsWith(`..${Path.sep}`) && relativePath !== ".." && !Path.isAbsolute(relativePath)) || requestedPaths && !requestedPaths.has(leasedPath)) continue;
74205
+ candidatePaths.add(leasedPath);
74206
+ }
74207
+ return candidatePaths;
74208
+ };
74209
+ const neutralizeDisableDirectives = async (rootDirectory, includePaths, options = {}) => {
74210
+ const resolvedRootDirectory = NFS.realpathSync(rootDirectory);
74211
+ const leasedPaths = /* @__PURE__ */ new Set();
74108
74212
  let isRestored = false;
74109
74213
  const restore = () => {
74110
74214
  if (isRestored) return;
74111
74215
  isRestored = true;
74112
- for (const [absolutePath, originalContent] of originalContents) try {
74113
- NFS.writeFileSync(absolutePath, originalContent);
74114
- } catch (error) {
74115
- process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${messageFromUnknown(error)}\n[react-doctor] Run: git checkout -- ${absolutePath}\n`);
74216
+ for (const absolutePath of leasedPaths) {
74217
+ const lease = neutralizedFileLeases.get(absolutePath);
74218
+ if (!lease) continue;
74219
+ lease.referenceCount -= 1;
74220
+ if (lease.referenceCount > 0) continue;
74221
+ neutralizedFileLeases.delete(absolutePath);
74222
+ try {
74223
+ NFS.writeFileSync(absolutePath, lease.originalContent);
74224
+ } catch (error) {
74225
+ process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${messageFromUnknown(error)}\n[react-doctor] Run: git checkout -- ${absolutePath}\n`);
74226
+ }
74116
74227
  }
74117
74228
  };
74118
74229
  const onExit = () => restore();
74119
74230
  process.once("exit", onExit);
74120
- for (const relativePath of filePaths) {
74121
- const absolutePath = Path.join(rootDirectory, relativePath);
74231
+ const leaseCandidatePath = (absolutePath) => {
74232
+ if (leasedPaths.has(absolutePath)) return;
74233
+ const existingLease = neutralizedFileLeases.get(absolutePath);
74234
+ if (existingLease) {
74235
+ existingLease.referenceCount += 1;
74236
+ leasedPaths.add(absolutePath);
74237
+ return;
74238
+ }
74122
74239
  let originalContent;
74123
74240
  try {
74124
74241
  originalContent = NFS.readFileSync(absolutePath, "utf-8");
74125
74242
  } catch {
74126
- continue;
74243
+ return;
74127
74244
  }
74128
74245
  const neutralizedContent = neutralizeContent(originalContent);
74129
74246
  if (neutralizedContent !== originalContent) {
74130
- originalContents.set(absolutePath, originalContent);
74131
74247
  NFS.writeFileSync(absolutePath, neutralizedContent);
74248
+ neutralizedFileLeases.set(absolutePath, {
74249
+ originalContent,
74250
+ referenceCount: 1
74251
+ });
74252
+ leasedPaths.add(absolutePath);
74132
74253
  }
74254
+ };
74255
+ try {
74256
+ await withOverlappingInitializationLock(resolvedRootDirectory, async () => {
74257
+ for (const absolutePath of collectNeutralizationCandidatePaths(resolvedRootDirectory, [], includePaths)) if (neutralizedFileLeases.has(absolutePath)) leaseCandidatePath(absolutePath);
74258
+ const discoveredRelativePaths = await (options.findFiles ?? findFilesWithDisableDirectives)(resolvedRootDirectory, includePaths);
74259
+ for (const absolutePath of collectNeutralizationCandidatePaths(resolvedRootDirectory, discoveredRelativePaths, includePaths)) leaseCandidatePath(absolutePath);
74260
+ });
74261
+ } catch (error) {
74262
+ restore();
74263
+ process.removeListener("exit", onExit);
74264
+ throw error;
74133
74265
  }
74134
74266
  return () => {
74135
74267
  restore();
@@ -78475,7 +78607,7 @@ const materializeSourceTree = (input) => gen(function* () {
78475
78607
  const sourcePath = path.join(input.directory, subdirectory, configFilename);
78476
78608
  const targetPath = path.resolve(resolvedTempDirectory, subdirectory, configFilename);
78477
78609
  if (!isPathInsideDirectory(targetPath, resolvedTempDirectory)) continue;
78478
- if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) {
78610
+ if (isFile(sourcePath) && !fs.existsSync(targetPath)) {
78479
78611
  fs.mkdirSync(path.dirname(targetPath), { recursive: true });
78480
78612
  fs.cpSync(sourcePath, targetPath);
78481
78613
  }
@@ -78993,16 +79125,17 @@ const groupBy = (items, keyFn) => {
78993
79125
  * a 404. Gate the directive on this predicate.
78994
79126
  */
78995
79127
  const hasPublishedFixRecipe = (diagnostic) => diagnostic.plugin === "react-doctor" && Object.hasOwn(REACT_DOCTOR_RULE_REGISTRY, diagnostic.rule);
78996
- const unionValues = (baseValues, overrideValues) => [...new Set([...baseValues, ...overrideValues])];
79128
+ const stringValues = (values) => Array.isArray(values) ? values.filter((value) => typeof value === "string") : [];
79129
+ const unionValues = (baseValues, overrideValues) => [...new Set([...stringValues(baseValues), ...stringValues(overrideValues)])];
78997
79130
  const mergeIgnores = (baseIgnore, overrideIgnore) => {
78998
79131
  const mergedIgnore = {
78999
79132
  ...baseIgnore,
79000
79133
  ...overrideIgnore
79001
79134
  };
79002
- if (baseIgnore.rules && overrideIgnore.rules) mergedIgnore.rules = unionValues(baseIgnore.rules, overrideIgnore.rules);
79003
- if (baseIgnore.files && overrideIgnore.files) mergedIgnore.files = unionValues(baseIgnore.files, overrideIgnore.files);
79004
- if (baseIgnore.tags && overrideIgnore.tags) mergedIgnore.tags = unionValues(baseIgnore.tags, overrideIgnore.tags);
79005
- if (baseIgnore.overrides && overrideIgnore.overrides) mergedIgnore.overrides = [...baseIgnore.overrides, ...overrideIgnore.overrides];
79135
+ if (baseIgnore.rules !== void 0 || overrideIgnore.rules !== void 0) mergedIgnore.rules = unionValues(baseIgnore.rules, overrideIgnore.rules);
79136
+ if (baseIgnore.files !== void 0 || overrideIgnore.files !== void 0) mergedIgnore.files = unionValues(baseIgnore.files, overrideIgnore.files);
79137
+ if (baseIgnore.tags !== void 0 || overrideIgnore.tags !== void 0) mergedIgnore.tags = unionValues(baseIgnore.tags, overrideIgnore.tags);
79138
+ if (baseIgnore.overrides !== void 0 || overrideIgnore.overrides !== void 0) mergedIgnore.overrides = [...Array.isArray(baseIgnore.overrides) ? baseIgnore.overrides : [], ...Array.isArray(overrideIgnore.overrides) ? overrideIgnore.overrides : []];
79006
79139
  return mergedIgnore;
79007
79140
  };
79008
79141
  /**
@@ -79197,6 +79330,21 @@ const NON_INTERACTIVE_ENVIRONMENT_VARIABLES = [
79197
79330
  ];
79198
79331
  const isNonInteractiveEnvironment = () => NON_INTERACTIVE_ENVIRONMENT_VARIABLES.some((envVariable) => Boolean(process.env[envVariable])) || isCodingAgentEnvironment();
79199
79332
  //#endregion
79333
+ //#region src/cli/utils/cli-input-error.ts
79334
+ /**
79335
+ * A mistake in *how the CLI was invoked* — a malformed `<file>:<line>`
79336
+ * argument, mutually exclusive flags, or an unknown `--project` name. This is
79337
+ * user input, not a react-doctor bug, so `isExpectedUserError` routes it
79338
+ * through `handleUserError`: a clean, single-line message with no Sentry
79339
+ * report and no "Something went wrong, open a prefilled issue" block.
79340
+ *
79341
+ * The `message` is rendered verbatim, so it must read as a complete,
79342
+ * human-readable sentence that tells the user how to fix their invocation.
79343
+ */
79344
+ var CliInputError = class extends Error {
79345
+ name = "CliInputError";
79346
+ };
79347
+ //#endregion
79200
79348
  //#region src/cli/utils/constants.ts
79201
79349
  const REACT_DOCTOR_CONFIG_PROJECT_NAME = "react-doctor";
79202
79350
  const STAGED_FILES_TEMP_DIR_PREFIX = "react-doctor-staged-";
@@ -79348,7 +79496,7 @@ const makeNoopConsole = () => ({
79348
79496
  });
79349
79497
  //#endregion
79350
79498
  //#region src/cli/utils/version.ts
79351
- const VERSION = "0.9.4-dev.8b97fdc";
79499
+ const VERSION = "0.9.4-dev.bafef41";
79352
79500
  //#endregion
79353
79501
  //#region src/cli/utils/json-mode.ts
79354
79502
  let context = null;
@@ -79392,9 +79540,14 @@ const enableJsonMode = ({ compact, directory, outputFile }) => {
79392
79540
  directory,
79393
79541
  startTime: performance$1.now(),
79394
79542
  mode: "full",
79395
- outputFile: outputFile ?? null
79543
+ outputFile: null
79396
79544
  };
79397
79545
  installSilentConsole();
79546
+ if (outputFile) {
79547
+ const resolvedOutputFile = Path.resolve(outputFile);
79548
+ if (NFS.existsSync(resolvedOutputFile) && !NFS.statSync(resolvedOutputFile).isFile()) throw new CliInputError(`--json-out must point to a file, not ${resolvedOutputFile}.`);
79549
+ context.outputFile = outputFile;
79550
+ }
79398
79551
  };
79399
79552
  const isJsonModeActive = () => context !== null;
79400
79553
  const setJsonReportDirectory = (directory) => {
@@ -79588,6 +79741,101 @@ const buildSentryScope = (runContext = buildRunContext()) => {
79588
79741
  //#region src/cli/utils/is-env-flag-enabled.ts
79589
79742
  const isEnvFlagEnabled = (value) => value === "1" || value?.toLowerCase() === "true";
79590
79743
  //#endregion
79744
+ //#region src/cli/utils/is-environment-error.ts
79745
+ const ENVIRONMENT_ERROR_CODES = new Set([
79746
+ "EACCES",
79747
+ "EIO",
79748
+ "ENOSPC",
79749
+ "ENOTDIR",
79750
+ "EPERM",
79751
+ "EROFS"
79752
+ ]);
79753
+ const ENVIRONMENT_FILESYSTEM_SYSCALLS = new Set([
79754
+ "lstat",
79755
+ "open",
79756
+ "read",
79757
+ "readdir",
79758
+ "readlink",
79759
+ "realpath",
79760
+ "scandir",
79761
+ "stat"
79762
+ ]);
79763
+ const TRANSIENT_FILESYSTEM_ERROR_CODES = new Set([
79764
+ "EBUSY",
79765
+ "ETIMEDOUT",
79766
+ "UNKNOWN"
79767
+ ]);
79768
+ const findEnvironmentError = (error) => {
79769
+ const pendingErrors = [error];
79770
+ const visitedErrors = /* @__PURE__ */ new Set();
79771
+ while (pendingErrors.length > 0) {
79772
+ const currentError = pendingErrors.pop();
79773
+ if (typeof currentError !== "object" || currentError === null) continue;
79774
+ if (visitedErrors.has(currentError)) continue;
79775
+ visitedErrors.add(currentError);
79776
+ if (isErrnoException(currentError) && typeof currentError.code === "string") {
79777
+ const syscall = currentError.syscall ?? "";
79778
+ if (ENVIRONMENT_ERROR_CODES.has(currentError.code) || currentError.code === "ENOENT" && syscall.startsWith("spawn") || TRANSIENT_FILESYSTEM_ERROR_CODES.has(currentError.code) && ENVIRONMENT_FILESYSTEM_SYSCALLS.has(syscall)) return currentError;
79779
+ }
79780
+ if (currentError instanceof Error && currentError.cause !== void 0) pendingErrors.push(currentError.cause);
79781
+ if (isReactDoctorError(currentError) && "cause" in currentError.reason) pendingErrors.push(currentError.reason.cause);
79782
+ }
79783
+ return null;
79784
+ };
79785
+ const isEnvironmentError = (error) => findEnvironmentError(error) !== null;
79786
+ const formatEnvironmentError = (error) => {
79787
+ const environmentError = findEnvironmentError(error);
79788
+ if (!environmentError) return messageFromUnknown(error);
79789
+ switch (environmentError.code) {
79790
+ case "EBUSY": return environmentError.path ? `Resource busy or locked at ${environmentError.path}. Close the process using it and try again.` : "Resource busy or locked. Close the process using it and try again.";
79791
+ case "ENOSPC": return "No space left on device. Free up disk space and try again.";
79792
+ case "EIO": return "I/O error: the filesystem or disk may be failing. Check your system logs.";
79793
+ case "EROFS": return "Read-only filesystem: cannot write to this location.";
79794
+ case "EACCES":
79795
+ case "EPERM": return environmentError.path ? `Permission denied accessing ${environmentError.path}. Check file permissions and try again.` : "Permission denied. Check file permissions and try again.";
79796
+ case "ENOTDIR": return environmentError.path ? `A file exists at ${environmentError.path} or one of its parent paths where a directory was expected.` : "A file exists where a directory was expected.";
79797
+ case "ENOENT": return "Required command not found. Ensure the tool (e.g. git) is installed and on your PATH.";
79798
+ case "ETIMEDOUT": return environmentError.path ? `Timed out accessing ${environmentError.path}. Check the network or cloud drive and try again.` : "Filesystem access timed out. Check the network or cloud drive and try again.";
79799
+ case "UNKNOWN": return environmentError.path ? `The operating system could not access ${environmentError.path}. Check the filesystem and try again.` : "The operating system could not access the filesystem. Check it and try again.";
79800
+ default: return environmentError.message;
79801
+ }
79802
+ };
79803
+ //#endregion
79804
+ //#region src/cli/utils/is-expected-user-error.ts
79805
+ /**
79806
+ * Whether `error` is an expected, user-actionable failure — the user's project
79807
+ * or input, not a react-doctor bug. Such failures must be kept out of crash
79808
+ * reporting (Sentry + the alertable error-rate metric) and rendered via
79809
+ * `handleUserError` (a plain message — no "Something went wrong", prefilled
79810
+ * issue, Discord link, or Sentry reference), since there is no bug to report.
79811
+ *
79812
+ * Four distinct shapes reach the CLI's catch blocks:
79813
+ *
79814
+ * - **Project-discovery failures** (`NoReactDependencyError`,
79815
+ * `ProjectNotFoundError`, `PackageJsonNotFoundError`, `NotADirectoryError`,
79816
+ * `AmbiguousProjectError`) arrive as their plain legacy classes (so
79817
+ * `isReactDoctorError` is `false` for them) — narrow with
79818
+ * `isProjectDiscoveryError`. Running react-doctor against a directory that
79819
+ * has no React, or a path that doesn't exist, is the canonical example.
79820
+ * - **CLI invocation mistakes** (`CliInputError`): a malformed
79821
+ * `<file>:<line>` argument, mutually exclusive flags, or an unknown
79822
+ * `--project` name.
79823
+ * - **Bad `--diff` input** (`GitBaseBranchInvalid` / `GitBaseBranchMissing`)
79824
+ * stays the tagged `ReactDoctorError`, so dispatch on the reason `_tag`.
79825
+ * - **Environment failures** (`ENOSPC`, `EIO`, `EROFS`, `EACCES`, `EPERM`,
79826
+ * `ENOTDIR`, plus a `spawn`-scoped `ENOENT` for a missing binary) — disk
79827
+ * full / failing / read-only, permission denied, or a path blocked by a
79828
+ * file. React Doctor cannot fix the user's environment; exit cleanly with an
79829
+ * actionable message instead of crashing. See `is-environment-error.ts` for
79830
+ * why the set stays narrow (codes that usually mean our bug keep reaching
79831
+ * Sentry).
79832
+ *
79833
+ * This composes the existing core narrowers rather than introducing a new
79834
+ * error-shape helper (AGENTS.md): it encodes CLI-layer reporting policy, not
79835
+ * knowledge of the `ReactDoctorError` shape.
79836
+ */
79837
+ const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isEnvironmentError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
79838
+ //#endregion
79591
79839
  //#region src/cli/utils/anonymize-text.ts
79592
79840
  /**
79593
79841
  * Free-text fields can carry both a home-directory path (the OS username) and a
@@ -79709,13 +79957,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
79709
79957
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
79710
79958
  * standard `SENTRY_RELEASE` override.
79711
79959
  */
79712
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.4-dev.8b97fdc`;
79960
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.4-dev.bafef41`;
79713
79961
  /**
79714
79962
  * Deployment environment shown in Sentry's environment filter. Defaults to
79715
79963
  * `production` for tagged releases and `development` for dev/unbuilt versions,
79716
79964
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
79717
79965
  */
79718
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.4-dev.8b97fdc") ? "development" : "production");
79966
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.4-dev.bafef41") ? "development" : "production");
79719
79967
  /**
79720
79968
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
79721
79969
  * (set to `0` to disable tracing) and falls back to
@@ -79780,21 +80028,25 @@ const initializeSentry = () => {
79780
80028
  isInitialized = true;
79781
80029
  resolvedTracesSampleRate = isDebugFlagEnabled() ? 1 : resolveTracesSampleRate();
79782
80030
  const { tags, contexts } = buildSentryScope();
79783
- Sentry.init({
79784
- dsn: process.env.SENTRY_DSN || "https://f253d570240a59b8dbd77b7a548ef133@o4510226365743104.ingest.us.sentry.io/4511487817809920",
79785
- release: resolveSentryRelease(),
79786
- environment: resolveSentryEnvironment(),
79787
- sendDefaultPii: false,
79788
- tracesSampleRate: resolvedTracesSampleRate,
79789
- debug: isEnvFlagEnabled(process.env.SENTRY_DEBUG),
79790
- initialScope: {
79791
- tags,
79792
- contexts
79793
- },
79794
- beforeSend: (event) => scrubSentryEvent(event),
79795
- beforeSendTransaction: (event) => scrubSentryEvent(event),
79796
- beforeSendMetric: (metric) => scrubSentryMetric(metric)
79797
- });
80031
+ try {
80032
+ Sentry.init({
80033
+ dsn: process.env.SENTRY_DSN || "https://f253d570240a59b8dbd77b7a548ef133@o4510226365743104.ingest.us.sentry.io/4511487817809920",
80034
+ release: resolveSentryRelease(),
80035
+ environment: resolveSentryEnvironment(),
80036
+ sendDefaultPii: false,
80037
+ tracesSampleRate: resolvedTracesSampleRate,
80038
+ debug: isEnvFlagEnabled(process.env.SENTRY_DEBUG),
80039
+ initialScope: {
80040
+ tags,
80041
+ contexts
80042
+ },
80043
+ beforeSend: (event, hint) => isExpectedUserError(hint.originalException) ? null : scrubSentryEvent(event),
80044
+ beforeSendTransaction: (event) => scrubSentryEvent(event),
80045
+ beforeSendMetric: (metric) => scrubSentryMetric(metric)
80046
+ });
80047
+ } catch {
80048
+ resolvedTracesSampleRate = 0;
80049
+ }
79798
80050
  };
79799
80051
  //#endregion
79800
80052
  //#region src/cli/utils/cli-logger.ts
@@ -91109,34 +91361,6 @@ const runCiConfig = async (options = {}) => {
91109
91361
  });
91110
91362
  };
91111
91363
  //#endregion
91112
- //#region src/cli/utils/is-environment-error.ts
91113
- const ENVIRONMENT_ERROR_CODES = new Set([
91114
- "ENOSPC",
91115
- "EIO",
91116
- "EROFS",
91117
- "EACCES",
91118
- "EPERM",
91119
- "ENOTDIR"
91120
- ]);
91121
- const isEnvironmentError = (error) => {
91122
- if (!isErrnoException(error) || typeof error.code !== "string") return false;
91123
- if (error.code === "ENOENT") return error.syscall?.startsWith("spawn") ?? false;
91124
- return ENVIRONMENT_ERROR_CODES.has(error.code);
91125
- };
91126
- const formatEnvironmentError = (error) => {
91127
- if (!isErrnoException(error)) return messageFromUnknown(error);
91128
- switch (error.code) {
91129
- case "ENOSPC": return "No space left on device. Free up disk space and try again.";
91130
- case "EIO": return "I/O error: the filesystem or disk may be failing. Check your system logs.";
91131
- case "EROFS": return "Read-only filesystem: cannot write to this location.";
91132
- case "EACCES":
91133
- case "EPERM": return error.path ? `Permission denied accessing ${error.path}. Check file permissions and try again.` : "Permission denied. Check file permissions and try again.";
91134
- case "ENOTDIR": return error.path ? `A file exists at ${error.path} or one of its parent paths where a directory was expected.` : "A file exists where a directory was expected.";
91135
- case "ENOENT": return "Required command not found. Ensure the tool (e.g. git) is installed and on your PATH.";
91136
- default: return error.message;
91137
- }
91138
- };
91139
- //#endregion
91140
91364
  //#region src/cli/utils/handle-error.ts
91141
91365
  const OTLP_ENDPOINT_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_ENDPOINT";
91142
91366
  const OTLP_AUTH_HEADER_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_AUTH_HEADER";
@@ -91238,56 +91462,6 @@ const handleUserError = (error, options = {}) => {
91238
91462
  process.exitCode = 1;
91239
91463
  };
91240
91464
  //#endregion
91241
- //#region src/cli/utils/cli-input-error.ts
91242
- /**
91243
- * A mistake in *how the CLI was invoked* — a malformed `<file>:<line>`
91244
- * argument, mutually exclusive flags, or an unknown `--project` name. This is
91245
- * user input, not a react-doctor bug, so `isExpectedUserError` routes it
91246
- * through `handleUserError`: a clean, single-line message with no Sentry
91247
- * report and no "Something went wrong, open a prefilled issue" block.
91248
- *
91249
- * The `message` is rendered verbatim, so it must read as a complete,
91250
- * human-readable sentence that tells the user how to fix their invocation.
91251
- */
91252
- var CliInputError = class extends Error {
91253
- name = "CliInputError";
91254
- };
91255
- //#endregion
91256
- //#region src/cli/utils/is-expected-user-error.ts
91257
- /**
91258
- * Whether `error` is an expected, user-actionable failure — the user's project
91259
- * or input, not a react-doctor bug. Such failures must be kept out of crash
91260
- * reporting (Sentry + the alertable error-rate metric) and rendered via
91261
- * `handleUserError` (a plain message — no "Something went wrong", prefilled
91262
- * issue, Discord link, or Sentry reference), since there is no bug to report.
91263
- *
91264
- * Four distinct shapes reach the CLI's catch blocks:
91265
- *
91266
- * - **Project-discovery failures** (`NoReactDependencyError`,
91267
- * `ProjectNotFoundError`, `PackageJsonNotFoundError`, `NotADirectoryError`,
91268
- * `AmbiguousProjectError`) arrive as their plain legacy classes (so
91269
- * `isReactDoctorError` is `false` for them) — narrow with
91270
- * `isProjectDiscoveryError`. Running react-doctor against a directory that
91271
- * has no React, or a path that doesn't exist, is the canonical example.
91272
- * - **CLI invocation mistakes** (`CliInputError`): a malformed
91273
- * `<file>:<line>` argument, mutually exclusive flags, or an unknown
91274
- * `--project` name.
91275
- * - **Bad `--diff` input** (`GitBaseBranchInvalid` / `GitBaseBranchMissing`)
91276
- * stays the tagged `ReactDoctorError`, so dispatch on the reason `_tag`.
91277
- * - **Environment failures** (`ENOSPC`, `EIO`, `EROFS`, `EACCES`, `EPERM`,
91278
- * `ENOTDIR`, plus a `spawn`-scoped `ENOENT` for a missing binary) — disk
91279
- * full / failing / read-only, permission denied, or a path blocked by a
91280
- * file. React Doctor cannot fix the user's environment; exit cleanly with an
91281
- * actionable message instead of crashing. See `is-environment-error.ts` for
91282
- * why the set stays narrow (codes that usually mean our bug keep reaching
91283
- * Sentry).
91284
- *
91285
- * This composes the existing core narrowers rather than introducing a new
91286
- * error-shape helper (AGENTS.md): it encodes CLI-layer reporting policy, not
91287
- * knowledge of the `ReactDoctorError` shape.
91288
- */
91289
- const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isEnvironmentError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
91290
- //#endregion
91291
91465
  //#region src/cli/utils/print-branded-header.ts
91292
91466
  /**
91293
91467
  * Single branded line every command prints first when not in JSON
@@ -97260,16 +97434,16 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
97260
97434
  const requestedDirectory = Path.resolve(directory);
97261
97435
  const startTime = performance$1.now();
97262
97436
  let scanStartupSpinner = null;
97263
- if (isJsonMode) {
97264
- enableJsonMode({
97265
- compact: Boolean(flags.jsonCompact),
97266
- directory: requestedDirectory,
97267
- outputFile: flags.jsonOut
97268
- });
97269
- if (flags.jsonOut) recordCount(METRIC.jsonOutUsed, 1);
97270
- }
97271
- recordCount(METRIC.cliInvoked, 1, { command: invocationCommand });
97272
97437
  try {
97438
+ if (isJsonMode) {
97439
+ enableJsonMode({
97440
+ compact: Boolean(flags.jsonCompact),
97441
+ directory: requestedDirectory,
97442
+ outputFile: flags.jsonOut
97443
+ });
97444
+ if (flags.jsonOut) recordCount(METRIC.jsonOutUsed, 1);
97445
+ }
97446
+ recordCount(METRIC.cliInvoked, 1, { command: invocationCommand });
97273
97447
  validateModeFlags(flags);
97274
97448
  if (flags.staged) setJsonReportMode("staged");
97275
97449
  await maybeMigrateLegacyConfig(requestedDirectory, {
@@ -97823,7 +97997,7 @@ const runScanCommand = async (input) => {
97823
97997
  return;
97824
97998
  }
97825
97999
  recordCount(METRIC.cliInvoked, 1, { command: input.invocationCommand });
97826
- const { runScanApp } = await import("./run-scan-app-QbtG43NL.js");
98000
+ const { runScanApp } = await import("./run-scan-app-C8iWVgvR.js");
97827
98001
  const { shouldFail } = await runScanApp({
97828
98002
  directory: input.directory,
97829
98003
  scanTarget,
@@ -98956,6 +99130,9 @@ program.command("experimental-tui [directory]", { hidden: true }).description("[
98956
99130
  process.stdout.on("error", (error) => {
98957
99131
  if (error.code === "EPIPE") process.exit(0);
98958
99132
  });
99133
+ process.stderr.on("error", (error) => {
99134
+ if (error.code === "EPIPE") process.exit(0);
99135
+ });
98959
99136
  const knownCommands = program.commands.flatMap((command) => [command.name(), ...command.aliases()]);
98960
99137
  const strippedArgv = stripUnknownCliFlags(process.argv);
98961
99138
  if (process.argv.includes("-V") && !strippedArgv.includes("-V")) {
@@ -98982,4 +99159,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
98982
99159
  export { TUI_REPORT_DETAIL_WIDTH_FRACTION as $, shouldRecordOnboarding as A, buildSortedRuleGroups as B, createInvocationInspect as C, markOnboardingComplete as D, doctorFace as E, buildEmptyReportMessage as F, recordCount as G, formatLearnMoreLine as H, hasIncompleteScoreAnalysis as I, findNearestPackageDirectory as J, recordDistribution as K, buildNoScoreMessage as L, computeProjectedScore as M, formatElapsedTime as N, canAnimateOnboarding as O, buildCodeFrame as P, TUI_REPORT_COMPACT_MAX_ROWS as Q, hasLintHardFailure as R, deduplicateProjectScans as S, easeOutCubic as T, resolveBlockingLevel as U, formatFixRecipeLine as V, isReactDoctorWorkflowInstalled as W, CI_TRUST_COMPANIES as X, isUnicodeSupported as Y, METRIC as Z, launchCliAgent as _, succeed$3 as _t, selectProjects as a, buildRuleDocsUrl as at, formatSkippedProjectsMessage as b, resolveWorkspaceDeadCodeOwner as c, highlighter as ct, countUniqueScannedFiles as d, remainingDeadlineBudgetMs as dt, isCiEnvironment as et, setUpGitHubActions as f, resolveScanTarget as ft, copyToClipboard as g, void_ as gt, CLI_AGENT_BINARIES as h, sync as ht, discoverWorkspacePackages as i, Reporter as it, filterDiagnosticsByCategories as j, isOnboardingForced as k, resolveCliInspectOptions as l, isPathInsideDirectory as lt, detectLaunchableAgents as m, runPromise as mt, registerActiveTuiRenderer as n, GITHUB_ACTIONS_SETUP_URL as nt, resolveProjectScan as o, getCategoryImpact as ot, openUrl as p, yieldToEventLoop as pt, toForwardSlashes as q, shouldFailScanGate as r, Progress as rt, retryMissingProjectScores as s, hasPublishedFixRecipe as st, exitGracefully as t, DIAGNOSTIC_CATEGORY_BUCKETS as tt, filterScansForSurface as u, mapWithConcurrency as ut, buildHandoffPayload as v, printFooter as w, collectProjectSourceFileCounts as x, isShareOptedOut as y, buildRulePriorityMap as z };
98983
99160
 
98984
99161
  //# sourceMappingURL=cli.js.map
98985
- //# debugId=cae1c0fa-086e-5609-a7c4-729ec799fb2c
99162
+ //# debugId=e74e6a68-20e1-59fe-8db0-62b87e8fe049