react-doctor 0.7.4-dev.99ac4ff → 0.7.4-dev.b47d053

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]="ef42af6f-0ecf-599f-a6cb-63bf1f1bd562")}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]="09731967-e6b8-5d9e-84b7-cb46a451b11a")}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";
@@ -8,8 +8,8 @@ import path from "node:path";
8
8
  import * as NFS from "node:fs";
9
9
  import fs, { mkdtempSync, rmSync } from "node:fs";
10
10
  import process$1 from "node:process";
11
+ import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
11
12
  import ts from "typescript";
12
- import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
13
13
  import * as OS from "node:os";
14
14
  import os, { tmpdir } from "node:os";
15
15
  import { parseJSON5 } from "confbox";
@@ -22411,12 +22411,45 @@ var Diagnostic = class extends Class("Diagnostic")({
22411
22411
  relatedLocations: optional(ArraySchema(DiagnosticRelatedLocation)),
22412
22412
  fixGroupId: optional(String$1)
22413
22413
  }) {};
22414
+ var JsonReportDiagnosticV3 = class extends Class("JsonReportDiagnosticV3")({
22415
+ id: String$1,
22416
+ normalizedFilePath: String$1,
22417
+ filePath: String$1,
22418
+ plugin: String$1,
22419
+ rule: String$1,
22420
+ severity: Severity,
22421
+ tags: ArraySchema(String$1),
22422
+ title: optional(String$1),
22423
+ message: String$1,
22424
+ help: String$1,
22425
+ url: optional(String$1),
22426
+ line: Number$1,
22427
+ column: Number$1,
22428
+ offset: optional(Number$1),
22429
+ length: optional(Number$1),
22430
+ endLine: optional(Number$1),
22431
+ endColumn: optional(Number$1),
22432
+ category: String$1,
22433
+ matchByOccurrence: optional(Boolean$1),
22434
+ fileContext: optional(Literals(["test", "story"])),
22435
+ suppressionHint: optional(String$1),
22436
+ relatedLocations: optional(ArraySchema(DiagnosticRelatedLocation)),
22437
+ fixGroupId: optional(String$1)
22438
+ }) {};
22439
+ /**
22440
+ * Deterministic identity string for a diagnostic. Same diagnostic
22441
+ * across two scans yields the same identity; lets baselines,
22442
+ * suppression files, content-hash caches, and IDE "ignore this"
22443
+ * actions all key off one shared shape.
22444
+ */
22445
+ const buildDiagnosticIdentity = (input) => `${input.filePath}::${input.line}:${input.column}::${input.plugin}/${input.rule}`;
22414
22446
  const JsonReportMode = Literals([
22415
22447
  "full",
22416
22448
  "diff",
22417
22449
  "staged",
22418
22450
  "baseline"
22419
22451
  ]);
22452
+ const Framework = Literals(FRAMEWORK_TOKENS);
22420
22453
  var JsonReportSummary = class extends Class("JsonReportSummary")({
22421
22454
  errorCount: Number$1,
22422
22455
  warningCount: Number$1,
@@ -22454,13 +22487,22 @@ var JsonReportProjectEntry = class extends Class("JsonReportProjectEntry")({
22454
22487
  scannedFileCount: optional(Number$1),
22455
22488
  elapsedMilliseconds: Number$1
22456
22489
  }) {};
22457
- /**
22458
- * Versioned JsonReport schema. `JsonReport` is a `Schema.Union` so we
22459
- * can add `schemaVersion: 2` later as one new union member without
22460
- * breaking existing v1 consumers (the GitHub Action keys off the
22461
- * version literal). Today's union is single-arm; the shape is
22462
- * intentional.
22463
- */
22490
+ var JsonReportProjectEntryV3 = class extends Class("JsonReportProjectEntryV3")({
22491
+ directory: String$1,
22492
+ packageRoot: String$1,
22493
+ framework: Framework,
22494
+ project: Unknown,
22495
+ diagnostics: ArraySchema(JsonReportDiagnosticV3),
22496
+ score: Unknown,
22497
+ skippedChecks: ArraySchema(String$1),
22498
+ skippedCheckReasons: optional(Record$1(String$1, String$1)),
22499
+ analyzedFiles: ArraySchema(String$1),
22500
+ analyzedFileCount: Number$1,
22501
+ complete: Boolean$1,
22502
+ scannedFileCount: optional(Number$1),
22503
+ elapsedMilliseconds: Number$1
22504
+ }) {};
22505
+ /** Original full, diff, and staged report contract. */
22464
22506
  var JsonReportV1 = class extends Class("JsonReportV1")({
22465
22507
  schemaVersion: Literal(1),
22466
22508
  version: String$1,
@@ -22521,7 +22563,27 @@ var JsonReportV2 = class extends Class("JsonReportV2")({
22521
22563
  elapsedMilliseconds: Number$1,
22522
22564
  error: NullOr(JsonReportError)
22523
22565
  }) {};
22524
- Union([JsonReportV1, JsonReportV2]);
22566
+ var JsonReportV3 = class extends Class("JsonReportV3")({
22567
+ schemaVersion: Literal(3),
22568
+ version: String$1,
22569
+ ok: Boolean$1,
22570
+ directory: String$1,
22571
+ mode: JsonReportMode,
22572
+ baselineDegraded: optional(Boolean$1),
22573
+ reactDetected: optional(Boolean$1),
22574
+ diff: NullOr(JsonReportDiffInfo),
22575
+ baseline: optional(JsonReportBaseline),
22576
+ projects: ArraySchema(JsonReportProjectEntryV3),
22577
+ diagnostics: ArraySchema(JsonReportDiagnosticV3),
22578
+ summary: JsonReportSummary,
22579
+ elapsedMilliseconds: Number$1,
22580
+ error: NullOr(JsonReportError)
22581
+ }) {};
22582
+ Union([
22583
+ JsonReportV1,
22584
+ JsonReportV2,
22585
+ JsonReportV3
22586
+ ]);
22525
22587
  //#endregion
22526
22588
  //#region ../../node_modules/.pnpm/semver@7.7.4/node_modules/semver/internal/constants.js
22527
22589
  var require_constants$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
@@ -37085,6 +37147,22 @@ const isPackageJsonReanimatedAware = (packageJson) => {
37085
37147
  };
37086
37148
  return Object.hasOwn(allDependencies, REANIMATED_DEPENDENCY_NAME$1);
37087
37149
  };
37150
+ const SSR_DEPENDENCY_NAMES = new Set([
37151
+ "@react-router/cloudflare",
37152
+ "@react-router/node",
37153
+ "@react-router/serve",
37154
+ "vike",
37155
+ "vite-plugin-ssr"
37156
+ ]);
37157
+ const isPackageJsonSsrAware = (packageJson) => {
37158
+ const allDependencies = {
37159
+ ...packageJson.peerDependencies,
37160
+ ...packageJson.dependencies,
37161
+ ...packageJson.devDependencies,
37162
+ ...packageJson.optionalDependencies
37163
+ };
37164
+ return Object.keys(allDependencies).some((packageName) => SSR_DEPENDENCY_NAMES.has(packageName));
37165
+ };
37088
37166
  const getWorkspacePatterns = (rootDirectory, packageJson) => {
37089
37167
  const pnpmPatterns = parsePnpmWorkspacePatterns(rootDirectory);
37090
37168
  if (pnpmPatterns.length > 0) return pnpmPatterns;
@@ -37225,6 +37303,7 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
37225
37303
  }
37226
37304
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
37227
37305
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
37306
+ facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
37228
37307
  };
37229
37308
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
37230
37309
  const facts = {
@@ -37246,6 +37325,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
37246
37325
  },
37247
37326
  hasReactNativeAwarePackage: false,
37248
37327
  hasReanimatedAwarePackage: false,
37328
+ hasSsrDependency: false,
37249
37329
  reanimatedVersion: null
37250
37330
  };
37251
37331
  evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
@@ -37482,6 +37562,7 @@ const discoverProjectWithoutPackageJson = (directory) => {
37482
37562
  hasTypeScript: hasOwnTsConfig,
37483
37563
  hasReactCompiler: false,
37484
37564
  hasTanStackQuery: false,
37565
+ hasSsrDependency: false,
37485
37566
  preactVersion: null,
37486
37567
  preactMajorVersion: null,
37487
37568
  hasReactNativeWorkspace: false,
@@ -37601,6 +37682,7 @@ const discoverProject = (directory) => {
37601
37682
  hasTypeScript,
37602
37683
  hasReactCompiler: detectReactCompiler(directory, packageJson),
37603
37684
  hasTanStackQuery: hasTanStackQuery(packageJson),
37685
+ hasSsrDependency: workspaceFacts.hasSsrDependency,
37604
37686
  preactVersion,
37605
37687
  preactMajorVersion: parseReactMajor(preactVersion),
37606
37688
  hasReactNativeWorkspace,
@@ -40454,6 +40536,12 @@ const CLIENT_ONLY_FRAMEWORKS = new Set([
40454
40536
  "react-native",
40455
40537
  "expo"
40456
40538
  ]);
40539
+ const SSR_FRAMEWORKS = new Set([
40540
+ "nextjs",
40541
+ "remix",
40542
+ "gatsby",
40543
+ "tanstack-start"
40544
+ ]);
40457
40545
  const addMajorLadder = (capabilities, name, major, earliest, latest) => {
40458
40546
  if (major === null) return;
40459
40547
  const cappedMajor = Math.min(major, latest);
@@ -40466,6 +40554,7 @@ const buildCapabilities = (project) => {
40466
40554
  if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
40467
40555
  if (project.expoVersion !== null) capabilities.add("expo");
40468
40556
  if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
40557
+ if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
40469
40558
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
40470
40559
  if (project.isStaticExport) capabilities.add("nextjs:static-export");
40471
40560
  if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
@@ -43886,6 +43975,8 @@ const spawnLintBatches = async (input) => {
43886
43975
  const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
43887
43976
  reportSkippedFiles(droppedFiles, (fileListPreview) => `${droppedFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
43888
43977
  reportSkippedFiles(outcome.deadlineSkippedFiles, (fileListPreview) => `${outcome.deadlineSkippedFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
43978
+ const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
43979
+ input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
43889
43980
  return dedupeDiagnostics(diagnostics);
43890
43981
  };
43891
43982
  let didValidate = false;
@@ -44142,12 +44233,18 @@ const reactHooksJsPluginDropNote = (error) => {
44142
44233
  * 6. always restore disable directives + clean up the temp dir
44143
44234
  */
44144
44235
  const runOxlint = async (options) => {
44145
- const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), userConfig, configSourceDirectory = rootDirectory, onPartialFailure, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
44236
+ const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
44146
44237
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
44147
44238
  const severityControls = buildRuleSeverityControls(userConfig);
44148
44239
  validateRuleRegistration();
44149
44240
  resetManifestCaches();
44150
- if (includePaths !== void 0 && includePaths.length === 0) return [];
44241
+ if (includePaths !== void 0 && includePaths.length === 0) {
44242
+ onFileCoverage?.({
44243
+ candidateFiles: [],
44244
+ analyzedFiles: []
44245
+ });
44246
+ return [];
44247
+ }
44151
44248
  const pluginPath = resolvePluginPath();
44152
44249
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
44153
44250
  const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
@@ -44208,6 +44305,7 @@ const runOxlint = async (options) => {
44208
44305
  const runConfigOverFiles = async (buildConfigForPass, configFileName, files, fileProgress) => {
44209
44306
  if (files.length === 0) return {
44210
44307
  diagnostics: [],
44308
+ analyzedFiles: [],
44211
44309
  didDropReactHooksJsPlugin: false,
44212
44310
  hadPartialFailure: false
44213
44311
  };
@@ -44219,24 +44317,32 @@ const runOxlint = async (options) => {
44219
44317
  const passConfigPath = Path.join(configDirectory, configFileName);
44220
44318
  const passBaseArgs = makeBaseArgs(passConfigPath);
44221
44319
  const passFileBatches = buildFileBatches(passBaseArgs, files);
44222
- const spawnPass = () => spawnLintBatches({
44223
- baseArgs: passBaseArgs,
44224
- fileBatches: passFileBatches,
44225
- rootDirectory,
44226
- nodeBinaryPath,
44227
- project,
44228
- onPartialFailure: reportPartialFailure,
44229
- onFileProgress: fileProgress,
44230
- spawnTimeoutMs,
44231
- outputMaxBytes,
44232
- concurrency: options.concurrency,
44233
- signal: options.signal,
44234
- deadlineEpochMs: options.deadlineEpochMs
44235
- });
44320
+ let analyzedFiles = [];
44321
+ const spawnPass = () => {
44322
+ analyzedFiles = [];
44323
+ return spawnLintBatches({
44324
+ baseArgs: passBaseArgs,
44325
+ fileBatches: passFileBatches,
44326
+ rootDirectory,
44327
+ nodeBinaryPath,
44328
+ project,
44329
+ onPartialFailure: reportPartialFailure,
44330
+ onAnalyzedFiles: (filePaths) => {
44331
+ analyzedFiles = filePaths;
44332
+ },
44333
+ onFileProgress: fileProgress,
44334
+ spawnTimeoutMs,
44335
+ outputMaxBytes,
44336
+ concurrency: options.concurrency,
44337
+ signal: options.signal,
44338
+ deadlineEpochMs: options.deadlineEpochMs
44339
+ });
44340
+ };
44236
44341
  writeOxlintConfig(passConfigPath, buildConfigForPass({}));
44237
44342
  try {
44238
44343
  return {
44239
44344
  diagnostics: await spawnPass(),
44345
+ analyzedFiles,
44240
44346
  didDropReactHooksJsPlugin: false,
44241
44347
  hadPartialFailure
44242
44348
  };
@@ -44248,6 +44354,7 @@ const runOxlint = async (options) => {
44248
44354
  reportPartialFailure(reactHooksJsDropNote);
44249
44355
  return {
44250
44356
  diagnostics,
44357
+ analyzedFiles,
44251
44358
  didDropReactHooksJsPlugin: true,
44252
44359
  hadPartialFailure
44253
44360
  };
@@ -44323,6 +44430,7 @@ const runOxlint = async (options) => {
44323
44430
  const missFileSet = new Set(missFiles);
44324
44431
  const hitFiles = candidateFiles.filter((candidateFile) => !missFileSet.has(candidateFile));
44325
44432
  const sidecarReplayedDiagnostics = [];
44433
+ const sidecarReplayedFiles = [];
44326
44434
  const sidecarLintFiles = [];
44327
44435
  if (sidecarCache === null) sidecarLintFiles.push(...hitFiles);
44328
44436
  else {
@@ -44330,8 +44438,10 @@ const runOxlint = async (options) => {
44330
44438
  for (const hitFile of hitFiles) {
44331
44439
  const cacheKey = cacheKeyByFile.get(hitFile);
44332
44440
  const entry = cacheKey === void 0 ? null : sidecarCache.lookup(cacheKey);
44333
- if (entry !== null && entry.probes.every((probe) => probeAnswers.answerFor(probe.kind, probe.path) === probe.answer)) sidecarReplayedDiagnostics.push(...entry.diagnostics);
44334
- else sidecarLintFiles.push(hitFile);
44441
+ if (entry !== null && entry.probes.every((probe) => probeAnswers.answerFor(probe.kind, probe.path) === probe.answer)) {
44442
+ sidecarReplayedFiles.push(hitFile);
44443
+ sidecarReplayedDiagnostics.push(...entry.diagnostics);
44444
+ } else sidecarLintFiles.push(hitFile);
44335
44445
  if (performance.now() - verifySliceStartedAt >= 12) {
44336
44446
  await yieldToEventLoop();
44337
44447
  verifySliceStartedAt = performance.now();
@@ -44357,6 +44467,7 @@ const runOxlint = async (options) => {
44357
44467
  sidecarRuleIdFilter: new Set(unboundedSidecarRuleIds)
44358
44468
  }), "oxlintrc.sidecar-unbounded.json", hitFiles, void 0) : {
44359
44469
  diagnostics: [],
44470
+ analyzedFiles: [],
44360
44471
  didDropReactHooksJsPlugin: false,
44361
44472
  hadPartialFailure: false
44362
44473
  };
@@ -44387,6 +44498,15 @@ const runOxlint = async (options) => {
44387
44498
  probesByFile: await missProbesTask
44388
44499
  }]
44389
44500
  });
44501
+ const analyzedFileSet = new Set(fullResult.analyzedFiles);
44502
+ const boundedSidecarAnalyzedFileSet = new Set(boundedSidecarResult.analyzedFiles);
44503
+ const unboundedSidecarAnalyzedFileSet = new Set(unboundedSidecarResult.analyzedFiles);
44504
+ const sidecarReplayedFileSet = new Set(sidecarReplayedFiles);
44505
+ for (const hitFile of hitFiles) if (useSidecarCache ? (sidecarReplayedFileSet.has(hitFile) || boundedSidecarAnalyzedFileSet.has(hitFile)) && (unboundedSidecarRuleIds.length === 0 || unboundedSidecarAnalyzedFileSet.has(hitFile)) : boundedSidecarAnalyzedFileSet.has(hitFile)) analyzedFileSet.add(hitFile);
44506
+ onFileCoverage?.({
44507
+ candidateFiles,
44508
+ analyzedFiles: candidateFiles.filter((candidateFile) => analyzedFileSet.has(candidateFile))
44509
+ });
44390
44510
  return dedupeDiagnostics([
44391
44511
  ...replayedDiagnostics,
44392
44512
  ...fullResult.diagnostics,
@@ -44397,6 +44517,7 @@ const runOxlint = async (options) => {
44397
44517
  }
44398
44518
  const baseArgs = makeBaseArgs(configPath);
44399
44519
  const fileBatches = buildFileBatches(baseArgs, candidateFiles);
44520
+ let analyzedFiles = [];
44400
44521
  const runBatches = () => spawnLintBatches({
44401
44522
  baseArgs,
44402
44523
  fileBatches,
@@ -44404,6 +44525,9 @@ const runOxlint = async (options) => {
44404
44525
  nodeBinaryPath,
44405
44526
  project,
44406
44527
  onPartialFailure,
44528
+ onAnalyzedFiles: (filePaths) => {
44529
+ analyzedFiles = filePaths;
44530
+ },
44407
44531
  onFileProgress: options.onFileProgress,
44408
44532
  spawnTimeoutMs,
44409
44533
  outputMaxBytes,
@@ -44413,7 +44537,12 @@ const runOxlint = async (options) => {
44413
44537
  });
44414
44538
  writeOxlintConfig(configPath, buildConfig({ extendsPaths }));
44415
44539
  try {
44416
- return await runBatches();
44540
+ const diagnostics = await runBatches();
44541
+ onFileCoverage?.({
44542
+ candidateFiles,
44543
+ analyzedFiles
44544
+ });
44545
+ return diagnostics;
44417
44546
  } catch (error) {
44418
44547
  const reactHooksJsDropNote = reactHooksJsPluginDropNote(error);
44419
44548
  if (reactHooksJsDropNote !== null) {
@@ -44423,11 +44552,20 @@ const runOxlint = async (options) => {
44423
44552
  }));
44424
44553
  const diagnostics = await runBatches();
44425
44554
  onPartialFailure?.(reactHooksJsDropNote);
44555
+ onFileCoverage?.({
44556
+ candidateFiles,
44557
+ analyzedFiles
44558
+ });
44426
44559
  return diagnostics;
44427
44560
  }
44428
44561
  if (extendsPaths.length === 0) throw error;
44429
44562
  writeOxlintConfig(configPath, buildConfig({ extendsPaths: [] }));
44430
- return await runBatches();
44563
+ const diagnostics = await runBatches();
44564
+ onFileCoverage?.({
44565
+ candidateFiles,
44566
+ analyzedFiles
44567
+ });
44568
+ return diagnostics;
44431
44569
  }
44432
44570
  } finally {
44433
44571
  restoreDisableDirectives();
@@ -44507,6 +44645,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
44507
44645
  onPartialFailure: (reason) => {
44508
44646
  collectedFailures.push(reason);
44509
44647
  },
44648
+ onFileCoverage: input.onFileCoverage,
44510
44649
  onFileProgress: input.onFileProgress,
44511
44650
  perFileLintCacheEnabled,
44512
44651
  sidecarLintCacheEnabled,
@@ -45214,6 +45353,7 @@ const resolveGithubActionsScoreMetadata = (environment = process.env) => {
45214
45353
  ...actorAssociation !== void 0 ? { githubActorAssociation: actorAssociation } : {}
45215
45354
  };
45216
45355
  };
45356
+ const toNormalizedRelativePath = (filePath, rootDirectory) => Path.relative(Path.resolve(rootDirectory), Path.resolve(rootDirectory, filePath)).replaceAll("\\", "/") || ".";
45217
45357
  const NO_HOOKS = {
45218
45358
  beforeLint: () => void_,
45219
45359
  afterLint: () => void_
@@ -45312,7 +45452,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45312
45452
  repo
45313
45453
  }).pipe(orElseSucceed(() => null)) : succeed$2(null));
45314
45454
  const lintIncludePaths = (input.skipJsxIncludeFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths], project)) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, project);
45315
- const scannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
45455
+ const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
45316
45456
  const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
45317
45457
  const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
45318
45458
  yield* beforeLint(project, lintIncludePaths ?? void 0);
@@ -45417,6 +45557,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45417
45557
  let deadCodeCacheHit = null;
45418
45558
  let deadCodeSummaryCacheHits = null;
45419
45559
  let deadCodeSummaryCacheMisses = null;
45560
+ const lintFileCoverageState = { value: null };
45420
45561
  const baseLintStream = linterService.run({
45421
45562
  rootDirectory: scanDirectory,
45422
45563
  project,
@@ -45432,6 +45573,9 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45432
45573
  lastReportedTotalFileCount = totalFileCount;
45433
45574
  runSync(scanProgress.update(`Scanning files (${scannedFileCount}/${totalFileCount})${workerCountSuffix}...`));
45434
45575
  },
45576
+ onFileCoverage: (coverage) => {
45577
+ lintFileCoverageState.value = coverage;
45578
+ },
45435
45579
  onCacheStats: (cacheHitFileCount, totalConsideredFileCount) => {
45436
45580
  lintCacheHitFileCount = cacheHitFileCount;
45437
45581
  lintCacheTotalFileCount = totalConsideredFileCount;
@@ -45462,7 +45606,10 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45462
45606
  const lintFailureState = yield* get$2(lintFailure);
45463
45607
  yield* afterLint(lintFailureState.didFail);
45464
45608
  if (lintFailureState.didFail) yield* scanProgress.fail(formatLintFailText(lintFailureState.reasonTag, process.version));
45465
- const totalFileCount = lastReportedTotalFileCount || (lintIncludePaths?.length ?? project.sourceFileCount);
45609
+ const candidateFiles = lintFileCoverageState.value === null ? [] : [...new Set(lintFileCoverageState.value.candidateFiles.map((filePath) => toNormalizedRelativePath(filePath, scanDirectory)))];
45610
+ const analyzedFiles = lintFileCoverageState.value === null ? [] : [...new Set(lintFileCoverageState.value.analyzedFiles.map((filePath) => toNormalizedRelativePath(filePath, scanDirectory)))].sort();
45611
+ const totalFileCount = candidateFiles.length || lastReportedTotalFileCount || (lintIncludePaths?.length ?? project.sourceFileCount);
45612
+ const scannedFilePaths = input.suppressScanSummary ? candidateFiles.length > 0 ? candidateFiles.map((filePath) => Path.resolve(scanDirectory, filePath)) : fallbackScannedFilePaths : [];
45466
45613
  const scannedFilesLabel = `${totalFileCount} ${totalFileCount === 1 ? "file" : "files"}`;
45467
45614
  let deadCodeCollected = [];
45468
45615
  if (lintFailureState.didFail) {
@@ -45544,6 +45691,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45544
45691
  deadCodeOverlapped: shouldOverlapDeadCode,
45545
45692
  scannedFileCount: totalFileCount,
45546
45693
  scannedFilePaths,
45694
+ analyzedFiles,
45547
45695
  scanElapsedMilliseconds,
45548
45696
  scanConcurrency,
45549
45697
  supplyChainOverlapTimedOut: supplyChainResult.timedOut,
@@ -45819,7 +45967,7 @@ const buildJsonReportError = (input) => {
45819
45967
  sentryEventId
45820
45968
  };
45821
45969
  return {
45822
- schemaVersion: 1,
45970
+ schemaVersion: 3,
45823
45971
  version: input.version,
45824
45972
  ok: false,
45825
45973
  directory: input.directory,
@@ -45864,6 +46012,7 @@ const summarizeDiagnostics = (diagnostics, worstScore = null, worstScoreLabel =
45864
46012
  * React-runtime rule family was gated off for the project.
45865
46013
  */
45866
46014
  const hasReactRuntime = (project) => project.reactVersion !== null || project.preactVersion !== null;
46015
+ const isScanComplete = (input) => input.analyzedFileCount !== void 0 && input.scannedFileCount !== void 0 && input.skippedCheckCount === 0 && input.skippedCheckReasonCount === 0 && input.analyzedFileCount === input.scannedFileCount;
45867
46016
  const toJsonDiff = (diff) => {
45868
46017
  if (!diff) return null;
45869
46018
  return {
@@ -45886,21 +46035,68 @@ const findWorstScoredProject = (projects) => {
45886
46035
  }
45887
46036
  return worst;
45888
46037
  };
46038
+ const toJsonReportDiagnostic = (diagnostic, projectRoot, reportRoot) => {
46039
+ const normalizedFilePath = toNormalizedRelativePath(diagnostic.filePath, projectRoot);
46040
+ const reportRelativeFilePath = toNormalizedRelativePath(Path.resolve(projectRoot, diagnostic.filePath), reportRoot);
46041
+ const ruleIdentity = getDiagnosticRuleIdentity(diagnostic);
46042
+ return {
46043
+ ...diagnostic,
46044
+ id: buildDiagnosticIdentity({
46045
+ filePath: reportRelativeFilePath,
46046
+ line: diagnostic.line,
46047
+ column: diagnostic.column,
46048
+ plugin: diagnostic.plugin,
46049
+ rule: diagnostic.rule
46050
+ }),
46051
+ normalizedFilePath,
46052
+ category: ruleIdentity.category,
46053
+ tags: [...new Set(ruleIdentity.tags)].sort()
46054
+ };
46055
+ };
45889
46056
  const buildJsonReport = (input) => {
45890
- const projects = input.scans.map(({ directory, result }) => ({
45891
- directory,
45892
- project: result.project,
45893
- diagnostics: result.diagnostics,
45894
- score: result.score,
45895
- skippedChecks: result.skippedChecks,
45896
- ...result.skippedCheckReasons ? { skippedCheckReasons: result.skippedCheckReasons } : {},
45897
- ...typeof result.scannedFileCount === "number" ? { scannedFileCount: result.scannedFileCount } : {},
45898
- elapsedMilliseconds: result.elapsedMilliseconds
45899
- }));
46057
+ const projects = input.scans.map(({ directory, result }) => {
46058
+ const skippedChecks = result.skippedChecks ?? [];
46059
+ const analyzedFiles = [...new Set((result.analyzedFiles ?? []).map((filePath) => toNormalizedRelativePath(filePath, result.project.rootDirectory)))].sort();
46060
+ const scannedFileCount = result.scannedFileCount ?? result.project.sourceFileCount;
46061
+ return {
46062
+ directory,
46063
+ packageRoot: result.project.rootDirectory,
46064
+ framework: result.project.framework,
46065
+ project: result.project,
46066
+ diagnostics: result.diagnostics.map((diagnostic) => toJsonReportDiagnostic(diagnostic, result.project.rootDirectory, input.directory)),
46067
+ score: result.score,
46068
+ skippedChecks,
46069
+ ...result.skippedCheckReasons ? { skippedCheckReasons: result.skippedCheckReasons } : {},
46070
+ analyzedFiles,
46071
+ analyzedFileCount: analyzedFiles.length,
46072
+ complete: isScanComplete({
46073
+ analyzedFileCount: result.analyzedFiles === void 0 ? void 0 : analyzedFiles.length,
46074
+ scannedFileCount,
46075
+ skippedCheckCount: skippedChecks.length,
46076
+ skippedCheckReasonCount: Object.keys(result.skippedCheckReasons ?? {}).length
46077
+ }),
46078
+ ...typeof result.scannedFileCount === "number" ? { scannedFileCount } : {},
46079
+ elapsedMilliseconds: result.elapsedMilliseconds
46080
+ };
46081
+ });
45900
46082
  const flattenedDiagnostics = projects.flatMap((entry) => entry.diagnostics);
45901
46083
  const worstScoredProject = findWorstScoredProject(projects);
45902
- const summary = summarizeDiagnostics(flattenedDiagnostics, worstScoredProject?.score?.score ?? null, worstScoredProject?.score?.label ?? null);
45903
- const shared = {
46084
+ const diagnosticSummary = summarizeDiagnostics(flattenedDiagnostics, worstScoredProject?.score?.score ?? null, worstScoredProject?.score?.label ?? null);
46085
+ const affectedFileCount = projects.reduce((totalAffectedFileCount, project) => totalAffectedFileCount + new Set(project.diagnostics.map((diagnostic) => diagnostic.normalizedFilePath)).size, 0);
46086
+ const summary = {
46087
+ ...diagnosticSummary,
46088
+ affectedFileCount
46089
+ };
46090
+ return {
46091
+ schemaVersion: 3,
46092
+ mode: input.baseline !== void 0 ? "baseline" : input.baselineDegraded && input.mode === "baseline" ? "diff" : input.mode,
46093
+ ...input.baseline ? { baseline: {
46094
+ baseRef: input.baseline.baseRef,
46095
+ newCount: summary.totalDiagnosticCount,
46096
+ fixedCount: input.baseline.fixedCount,
46097
+ baseTotalCount: input.baseline.baseTotalCount
46098
+ } } : {},
46099
+ ...input.baselineDegraded ? { baselineDegraded: true } : {},
45904
46100
  ...input.scans.length > 0 ? { reactDetected: input.scans.some((scan) => hasReactRuntime(scan.result.project)) } : {},
45905
46101
  version: input.version,
45906
46102
  ok: true,
@@ -45912,39 +46108,26 @@ const buildJsonReport = (input) => {
45912
46108
  elapsedMilliseconds: input.totalElapsedMilliseconds,
45913
46109
  error: null
45914
46110
  };
45915
- if (input.baseline) return {
45916
- schemaVersion: 2,
45917
- mode: "baseline",
45918
- baseline: {
45919
- baseRef: input.baseline.baseRef,
45920
- newCount: summary.totalDiagnosticCount,
45921
- fixedCount: input.baseline.fixedCount,
45922
- baseTotalCount: input.baseline.baseTotalCount
45923
- },
45924
- ...shared
45925
- };
45926
- return {
45927
- schemaVersion: 1,
45928
- mode: input.mode,
45929
- ...input.baselineDegraded ? { baselineDegraded: true } : {},
45930
- ...shared
45931
- };
45932
46111
  };
45933
46112
  /**
45934
46113
  * Single source of truth for the skipped-check accounting shared by the
45935
46114
  * CLI renderer (`react-doctor/src/inspect.ts → finalizeAndRender`) and the
45936
46115
  * programmatic shell (`@react-doctor/api → diagnose()`). Both surface a
45937
- * failed lint / dead-code pass instead of a false "all clear", so the
46116
+ * failed or partial analysis pass instead of a false "all clear", so the
45938
46117
  * branch logic lives here once.
45939
46118
  */
45940
46119
  const buildSkippedChecks = (input) => {
45941
46120
  const skippedChecks = [];
45942
46121
  if (input.didLintFail) skippedChecks.push("lint");
45943
46122
  if (input.didDeadCodeFail) skippedChecks.push("dead-code");
46123
+ if (input.supplyChainOverlapTimedOut) skippedChecks.push("supply-chain");
46124
+ if (input.securityScanFailed) skippedChecks.push("security-scan");
45944
46125
  const skippedCheckReasons = {};
45945
46126
  if (input.didLintFail && input.lintFailureReason !== null) skippedCheckReasons.lint = input.lintFailureReason;
45946
46127
  else if (input.lintPartialFailures.length > 0) skippedCheckReasons["lint:partial"] = input.lintPartialFailures.join("; ");
45947
46128
  if (input.didDeadCodeFail && input.deadCodeFailureReason !== null) skippedCheckReasons["dead-code"] = input.deadCodeFailureReason;
46129
+ if (input.supplyChainOverlapTimedOut) skippedCheckReasons["supply-chain"] = "Supply-chain analysis timed out and was skipped.";
46130
+ if (input.securityScanFailed) skippedCheckReasons["security-scan"] = "Security scan failed and was skipped.";
45948
46131
  return {
45949
46132
  skippedChecks,
45950
46133
  skippedCheckReasons
@@ -46359,7 +46542,7 @@ const GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS = 5e3;
46359
46542
  const CI_TRUST_COMPANIES = "PayPal, Rippling, and Alibaba";
46360
46543
  const WELCOME_EXPLANATION_HOLD_MS = 1e3;
46361
46544
  const CATEGORY_COUNTUP_SETTLE_HOLD_MS = 1e3;
46362
- const INTERNAL_ERROR_JSON_FALLBACK = "{\"schemaVersion\":1,\"ok\":false,\"error\":{\"message\":\"Internal error\",\"name\":\"Error\",\"chain\":[]}}\n";
46545
+ const INTERNAL_ERROR_JSON_FALLBACK = "{\"schemaVersion\":3,\"version\":\"unknown\",\"ok\":false,\"directory\":\"\",\"mode\":\"full\",\"diff\":null,\"projects\":[],\"diagnostics\":[],\"summary\":{\"errorCount\":0,\"warningCount\":0,\"affectedFileCount\":0,\"totalDiagnosticCount\":0,\"score\":null,\"scoreLabel\":null},\"elapsedMilliseconds\":0,\"error\":{\"message\":\"Internal error\",\"name\":\"Error\",\"chain\":[]}}\n";
46363
46546
  const SENTRY_FLUSH_TIMEOUT_MS = 2e3;
46364
46547
  const NANOSECONDS_PER_SECOND = 1000000000n;
46365
46548
  const METRIC = {
@@ -46446,7 +46629,7 @@ const makeNoopConsole = () => ({
46446
46629
  });
46447
46630
  //#endregion
46448
46631
  //#region src/cli/utils/version.ts
46449
- const VERSION = "0.7.4-dev.99ac4ff";
46632
+ const VERSION = "0.7.4-dev.b47d053";
46450
46633
  //#endregion
46451
46634
  //#region src/cli/utils/json-mode.ts
46452
46635
  let context = null;
@@ -46815,13 +46998,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
46815
46998
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
46816
46999
  * standard `SENTRY_RELEASE` override.
46817
47000
  */
46818
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.7.4-dev.99ac4ff`;
47001
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.7.4-dev.b47d053`;
46819
47002
  /**
46820
47003
  * Deployment environment shown in Sentry's environment filter. Defaults to
46821
47004
  * `production` for tagged releases and `development` for dev/unbuilt versions,
46822
47005
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
46823
47006
  */
46824
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.7.4-dev.99ac4ff") ? "development" : "production");
47007
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.7.4-dev.b47d053") ? "development" : "production");
46825
47008
  /**
46826
47009
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
46827
47010
  * (set to `0` to disable tracing) and falls back to
@@ -59031,12 +59214,12 @@ const resolveCacheFilePath = (projectDirectory) => path.join(resolveReactDoctorC
59031
59214
  const readPersistedCache = (cacheFilePath) => {
59032
59215
  try {
59033
59216
  const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
59034
- if (!isRecord(parsed) || parsed.version !== 4) return {
59035
- version: 4,
59217
+ if (!isRecord(parsed) || parsed.version !== 5) return {
59218
+ version: 5,
59036
59219
  entries: []
59037
59220
  };
59038
59221
  if (!Array.isArray(parsed.entries)) return {
59039
- version: 4,
59222
+ version: 5,
59040
59223
  entries: []
59041
59224
  };
59042
59225
  const entries = [];
@@ -59046,12 +59229,12 @@ const readPersistedCache = (cacheFilePath) => {
59046
59229
  entries.push(entry);
59047
59230
  }
59048
59231
  return {
59049
- version: 4,
59232
+ version: 5,
59050
59233
  entries
59051
59234
  };
59052
59235
  } catch {
59053
59236
  return {
59054
- version: 4,
59237
+ version: 5,
59055
59238
  entries: []
59056
59239
  };
59057
59240
  }
@@ -59113,7 +59296,7 @@ const buildScanResultCacheKey = (input) => {
59113
59296
  if (headSha === null) return null;
59114
59297
  if (stringifyStableJson(input.userConfig) === null) return null;
59115
59298
  const cacheKeyJson = stringifyStableJson({
59116
- schemaVersion: 4,
59299
+ schemaVersion: 5,
59117
59300
  projectIdentity: resolveProjectIdentity(input.projectDirectory),
59118
59301
  headSha,
59119
59302
  worktreeFingerprint,
@@ -59154,7 +59337,7 @@ const createScanResultCache = (projectDirectory) => {
59154
59337
  for (const entry of persistedCache.entries) entries.set(entry.key, entry);
59155
59338
  const persist = () => {
59156
59339
  writePersistedCache(cacheFilePath, {
59157
- version: 4,
59340
+ version: 5,
59158
59341
  entries: [...entries.values()].sort((firstEntry, secondEntry) => secondEntry.createdAtMs - firstEntry.createdAtMs).slice(0, 20)
59159
59342
  });
59160
59343
  };
@@ -59295,6 +59478,7 @@ const buildOutcomeAttributes = (input) => {
59295
59478
  return withNamespace("outcome", {
59296
59479
  status: "error",
59297
59480
  exitCode: 1,
59481
+ complete: false,
59298
59482
  knownError: known,
59299
59483
  errorTag: known ? error.reason._tag : error instanceof Error ? error.name : null
59300
59484
  });
@@ -59304,8 +59488,13 @@ const buildOutcomeAttributes = (input) => {
59304
59488
  const blockingLevel = resolveTelemetryBlocking(input.userConfig);
59305
59489
  const gateDiagnostics = filterDiagnosticsForSurface(result.diagnostics, "ciFailure", input.userConfig);
59306
59490
  const wouldBlock = !input.scoreOnly && !input.gateExempt && shouldBlockCi(gateDiagnostics, blockingLevel);
59307
- const hasSkippedChecks = result.skippedChecks.length > 0;
59308
- const isClean = result.diagnostics.length === 0 && !hasSkippedChecks;
59491
+ const complete = isScanComplete({
59492
+ analyzedFileCount: result.analyzedFiles?.length,
59493
+ scannedFileCount: result.scannedFileCount,
59494
+ skippedCheckCount: result.skippedChecks.length,
59495
+ skippedCheckReasonCount: Object.keys(result.skippedCheckReasons ?? {}).length
59496
+ });
59497
+ const isClean = result.diagnostics.length === 0 && complete;
59309
59498
  const outcome = wouldBlock ? "blocked" : isClean ? "clean" : "ok";
59310
59499
  const firings = summarizeRuleFirings(result.diagnostics);
59311
59500
  const countByRule = /* @__PURE__ */ new Map();
@@ -59355,6 +59544,7 @@ const buildOutcomeAttributes = (input) => {
59355
59544
  wouldBlock,
59356
59545
  blocking: blockingLevel,
59357
59546
  clean: isClean,
59547
+ complete,
59358
59548
  skippedChecks: result.skippedChecks.length
59359
59549
  }),
59360
59550
  ...withNamespace("diag", {
@@ -61005,6 +61195,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
61005
61195
  directory: output.resolvedDirectory,
61006
61196
  scannedFileCount: output.scannedFileCount,
61007
61197
  scannedFilePaths: output.scannedFilePaths,
61198
+ analyzedFiles: output.analyzedFiles,
61008
61199
  scanElapsedMilliseconds: output.scanElapsedMilliseconds,
61009
61200
  scanConcurrency: output.scanConcurrency,
61010
61201
  baselineDelta,
@@ -61059,9 +61250,12 @@ const renderAndRecordScan = async (input) => {
61059
61250
  lintPartialFailures: input.payload.lintPartialFailures,
61060
61251
  didDeadCodeFail: input.payload.didDeadCodeFail,
61061
61252
  deadCodeFailureReason: input.payload.deadCodeFailureReason,
61253
+ supplyChainOverlapTimedOut: input.payload.supplyChainOverlapTimedOut,
61254
+ securityScanFailed: input.payload.securityScanFailed ?? false,
61062
61255
  directory: input.payload.directory,
61063
61256
  scannedFileCount: input.payload.scannedFileCount,
61064
61257
  scannedFilePaths: input.payload.scannedFilePaths,
61258
+ analyzedFiles: input.payload.analyzedFiles ?? [],
61065
61259
  scanElapsedMilliseconds: input.payload.scanElapsedMilliseconds,
61066
61260
  lintCacheHitFileCount: input.lintCacheHitFileCount ?? null,
61067
61261
  lintCacheTotalFileCount: input.lintCacheTotalFileCount ?? null,
@@ -61109,13 +61303,15 @@ const renderAndRecordScan = async (input) => {
61109
61303
  return result;
61110
61304
  };
61111
61305
  const finalizeAndRender = (input) => gen(function* () {
61112
- const { options, elapsedMilliseconds, diagnostics, score, project, userConfig, didLintFail, lintFailureReason, lintPartialFailures, didDeadCodeFail, deadCodeFailureReason, directory, scannedFileCount, scannedFilePaths, scanElapsedMilliseconds, lintCacheHitFileCount, lintCacheTotalFileCount, lintSidecarReplayedFileCount, lintSidecarTotalFileCount, deadCodeCacheHit, deadCodeSummaryCacheHits, deadCodeSummaryCacheMisses, baselineDelta } = input;
61306
+ const { options, elapsedMilliseconds, diagnostics, score, project, userConfig, didLintFail, lintFailureReason, lintPartialFailures, didDeadCodeFail, deadCodeFailureReason, supplyChainOverlapTimedOut, securityScanFailed, directory, scannedFileCount, scannedFilePaths, analyzedFiles, scanElapsedMilliseconds, lintCacheHitFileCount, lintCacheTotalFileCount, lintSidecarReplayedFileCount, lintSidecarTotalFileCount, deadCodeCacheHit, deadCodeSummaryCacheHits, deadCodeSummaryCacheMisses, baselineDelta } = input;
61113
61307
  const { skippedChecks, skippedCheckReasons } = buildSkippedChecks({
61114
61308
  didLintFail,
61115
61309
  lintFailureReason,
61116
61310
  lintPartialFailures,
61117
61311
  didDeadCodeFail,
61118
- deadCodeFailureReason
61312
+ deadCodeFailureReason,
61313
+ supplyChainOverlapTimedOut,
61314
+ securityScanFailed
61119
61315
  });
61120
61316
  const hasSkippedChecks = skippedChecks.length > 0;
61121
61317
  const noScoreMessage = buildNoScoreMessage(options.noScore);
@@ -61128,6 +61324,7 @@ const finalizeAndRender = (input) => gen(function* () {
61128
61324
  elapsedMilliseconds,
61129
61325
  scannedFileCount,
61130
61326
  scannedFilePaths,
61327
+ analyzedFiles,
61131
61328
  scanElapsedMilliseconds,
61132
61329
  ...lintCacheTotalFileCount !== null ? {
61133
61330
  lintCacheHitFileCount,
@@ -64996,4 +65193,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
64996
65193
  export {};
64997
65194
 
64998
65195
  //# sourceMappingURL=cli.js.map
64999
- //# debugId=ef42af6f-0ecf-599f-a6cb-63bf1f1bd562
65196
+ //# debugId=09731967-e6b8-5d9e-84b7-cb46a451b11a