react-doctor 0.7.3 → 0.7.4-dev.11333b9

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]="a1ea28f2-3add-5149-82df-ab1cf0c4992e")}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 * as 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";
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";
12
+ import ts from "typescript";
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) => {
@@ -36179,7 +36241,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
36179
36241
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
36180
36242
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
36181
36243
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
36182
- const CORE_PACKAGE_VERSION = "0.7.3";
36244
+ const CORE_PACKAGE_VERSION = "0.7.4";
36183
36245
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
36184
36246
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
36185
36247
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -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,
@@ -38687,6 +38769,14 @@ var AmbiguousProject = class extends TaggedErrorClass()("AmbiguousProject", {
38687
38769
  return `Ambiguous project at ${this.directory}: found ${this.candidates.length} candidates (${this.candidates.join(", ")})`;
38688
38770
  }
38689
38771
  };
38772
+ var ProjectDiscoveryFailed = class extends TaggedErrorClass()("ProjectDiscoveryFailed", {
38773
+ directory: String$1,
38774
+ cause: Unknown
38775
+ }) {
38776
+ get message() {
38777
+ return `Project discovery failed for ${this.directory}: ${pretty(fail$6(this.cause))}`;
38778
+ }
38779
+ };
38690
38780
  var DeadCodeAnalysisFailed = class extends TaggedErrorClass()("DeadCodeAnalysisFailed", { cause: Unknown }) {
38691
38781
  get message() {
38692
38782
  return `Dead-code analysis failed: ${pretty(fail$6(this.cause))}`;
@@ -38721,6 +38811,7 @@ const ReactDoctorErrorReason = Union([
38721
38811
  ProjectNotFound,
38722
38812
  NoReactDependency,
38723
38813
  AmbiguousProject,
38814
+ ProjectDiscoveryFailed,
38724
38815
  DeadCodeAnalysisFailed,
38725
38816
  GitInvocationFailed,
38726
38817
  GitBaseBranchMissing,
@@ -40445,6 +40536,12 @@ const CLIENT_ONLY_FRAMEWORKS = new Set([
40445
40536
  "react-native",
40446
40537
  "expo"
40447
40538
  ]);
40539
+ const SSR_FRAMEWORKS = new Set([
40540
+ "nextjs",
40541
+ "remix",
40542
+ "gatsby",
40543
+ "tanstack-start"
40544
+ ]);
40448
40545
  const addMajorLadder = (capabilities, name, major, earliest, latest) => {
40449
40546
  if (major === null) return;
40450
40547
  const cappedMajor = Math.min(major, latest);
@@ -40457,6 +40554,7 @@ const buildCapabilities = (project) => {
40457
40554
  if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
40458
40555
  if (project.expoVersion !== null) capabilities.add("expo");
40459
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");
40460
40558
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
40461
40559
  if (project.isStaticExport) capabilities.add("nextjs:static-export");
40462
40560
  if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
@@ -43877,6 +43975,8 @@ const spawnLintBatches = async (input) => {
43877
43975
  const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
43878
43976
  reportSkippedFiles(droppedFiles, (fileListPreview) => `${droppedFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
43879
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());
43880
43980
  return dedupeDiagnostics(diagnostics);
43881
43981
  };
43882
43982
  let didValidate = false;
@@ -44133,12 +44233,18 @@ const reactHooksJsPluginDropNote = (error) => {
44133
44233
  * 6. always restore disable directives + clean up the temp dir
44134
44234
  */
44135
44235
  const runOxlint = async (options) => {
44136
- 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;
44137
44237
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
44138
44238
  const severityControls = buildRuleSeverityControls(userConfig);
44139
44239
  validateRuleRegistration();
44140
44240
  resetManifestCaches();
44141
- 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
+ }
44142
44248
  const pluginPath = resolvePluginPath();
44143
44249
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
44144
44250
  const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
@@ -44199,6 +44305,7 @@ const runOxlint = async (options) => {
44199
44305
  const runConfigOverFiles = async (buildConfigForPass, configFileName, files, fileProgress) => {
44200
44306
  if (files.length === 0) return {
44201
44307
  diagnostics: [],
44308
+ analyzedFiles: [],
44202
44309
  didDropReactHooksJsPlugin: false,
44203
44310
  hadPartialFailure: false
44204
44311
  };
@@ -44210,24 +44317,32 @@ const runOxlint = async (options) => {
44210
44317
  const passConfigPath = Path.join(configDirectory, configFileName);
44211
44318
  const passBaseArgs = makeBaseArgs(passConfigPath);
44212
44319
  const passFileBatches = buildFileBatches(passBaseArgs, files);
44213
- const spawnPass = () => spawnLintBatches({
44214
- baseArgs: passBaseArgs,
44215
- fileBatches: passFileBatches,
44216
- rootDirectory,
44217
- nodeBinaryPath,
44218
- project,
44219
- onPartialFailure: reportPartialFailure,
44220
- onFileProgress: fileProgress,
44221
- spawnTimeoutMs,
44222
- outputMaxBytes,
44223
- concurrency: options.concurrency,
44224
- signal: options.signal,
44225
- deadlineEpochMs: options.deadlineEpochMs
44226
- });
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
+ };
44227
44341
  writeOxlintConfig(passConfigPath, buildConfigForPass({}));
44228
44342
  try {
44229
44343
  return {
44230
44344
  diagnostics: await spawnPass(),
44345
+ analyzedFiles,
44231
44346
  didDropReactHooksJsPlugin: false,
44232
44347
  hadPartialFailure
44233
44348
  };
@@ -44239,6 +44354,7 @@ const runOxlint = async (options) => {
44239
44354
  reportPartialFailure(reactHooksJsDropNote);
44240
44355
  return {
44241
44356
  diagnostics,
44357
+ analyzedFiles,
44242
44358
  didDropReactHooksJsPlugin: true,
44243
44359
  hadPartialFailure
44244
44360
  };
@@ -44314,6 +44430,7 @@ const runOxlint = async (options) => {
44314
44430
  const missFileSet = new Set(missFiles);
44315
44431
  const hitFiles = candidateFiles.filter((candidateFile) => !missFileSet.has(candidateFile));
44316
44432
  const sidecarReplayedDiagnostics = [];
44433
+ const sidecarReplayedFiles = [];
44317
44434
  const sidecarLintFiles = [];
44318
44435
  if (sidecarCache === null) sidecarLintFiles.push(...hitFiles);
44319
44436
  else {
@@ -44321,8 +44438,10 @@ const runOxlint = async (options) => {
44321
44438
  for (const hitFile of hitFiles) {
44322
44439
  const cacheKey = cacheKeyByFile.get(hitFile);
44323
44440
  const entry = cacheKey === void 0 ? null : sidecarCache.lookup(cacheKey);
44324
- if (entry !== null && entry.probes.every((probe) => probeAnswers.answerFor(probe.kind, probe.path) === probe.answer)) sidecarReplayedDiagnostics.push(...entry.diagnostics);
44325
- 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);
44326
44445
  if (performance.now() - verifySliceStartedAt >= 12) {
44327
44446
  await yieldToEventLoop();
44328
44447
  verifySliceStartedAt = performance.now();
@@ -44348,6 +44467,7 @@ const runOxlint = async (options) => {
44348
44467
  sidecarRuleIdFilter: new Set(unboundedSidecarRuleIds)
44349
44468
  }), "oxlintrc.sidecar-unbounded.json", hitFiles, void 0) : {
44350
44469
  diagnostics: [],
44470
+ analyzedFiles: [],
44351
44471
  didDropReactHooksJsPlugin: false,
44352
44472
  hadPartialFailure: false
44353
44473
  };
@@ -44378,6 +44498,15 @@ const runOxlint = async (options) => {
44378
44498
  probesByFile: await missProbesTask
44379
44499
  }]
44380
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
+ });
44381
44510
  return dedupeDiagnostics([
44382
44511
  ...replayedDiagnostics,
44383
44512
  ...fullResult.diagnostics,
@@ -44388,6 +44517,7 @@ const runOxlint = async (options) => {
44388
44517
  }
44389
44518
  const baseArgs = makeBaseArgs(configPath);
44390
44519
  const fileBatches = buildFileBatches(baseArgs, candidateFiles);
44520
+ let analyzedFiles = [];
44391
44521
  const runBatches = () => spawnLintBatches({
44392
44522
  baseArgs,
44393
44523
  fileBatches,
@@ -44395,6 +44525,9 @@ const runOxlint = async (options) => {
44395
44525
  nodeBinaryPath,
44396
44526
  project,
44397
44527
  onPartialFailure,
44528
+ onAnalyzedFiles: (filePaths) => {
44529
+ analyzedFiles = filePaths;
44530
+ },
44398
44531
  onFileProgress: options.onFileProgress,
44399
44532
  spawnTimeoutMs,
44400
44533
  outputMaxBytes,
@@ -44404,7 +44537,12 @@ const runOxlint = async (options) => {
44404
44537
  });
44405
44538
  writeOxlintConfig(configPath, buildConfig({ extendsPaths }));
44406
44539
  try {
44407
- return await runBatches();
44540
+ const diagnostics = await runBatches();
44541
+ onFileCoverage?.({
44542
+ candidateFiles,
44543
+ analyzedFiles
44544
+ });
44545
+ return diagnostics;
44408
44546
  } catch (error) {
44409
44547
  const reactHooksJsDropNote = reactHooksJsPluginDropNote(error);
44410
44548
  if (reactHooksJsDropNote !== null) {
@@ -44414,11 +44552,20 @@ const runOxlint = async (options) => {
44414
44552
  }));
44415
44553
  const diagnostics = await runBatches();
44416
44554
  onPartialFailure?.(reactHooksJsDropNote);
44555
+ onFileCoverage?.({
44556
+ candidateFiles,
44557
+ analyzedFiles
44558
+ });
44417
44559
  return diagnostics;
44418
44560
  }
44419
44561
  if (extendsPaths.length === 0) throw error;
44420
44562
  writeOxlintConfig(configPath, buildConfig({ extendsPaths: [] }));
44421
- return await runBatches();
44563
+ const diagnostics = await runBatches();
44564
+ onFileCoverage?.({
44565
+ candidateFiles,
44566
+ analyzedFiles
44567
+ });
44568
+ return diagnostics;
44422
44569
  }
44423
44570
  } finally {
44424
44571
  restoreDisableDirectives();
@@ -44498,6 +44645,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
44498
44645
  onPartialFailure: (reason) => {
44499
44646
  collectedFailures.push(reason);
44500
44647
  },
44648
+ onFileCoverage: input.onFileCoverage,
44501
44649
  onFileProgress: input.onFileProgress,
44502
44650
  perFileLintCacheEnabled,
44503
44651
  sidecarLintCacheEnabled,
@@ -44590,7 +44738,10 @@ const translateProjectInfoError = (cause, directory) => {
44590
44738
  directory: cause.directory,
44591
44739
  candidates: cause.candidates
44592
44740
  }) });
44593
- return new ReactDoctorError({ reason: new ProjectNotFound({ directory }) });
44741
+ return new ReactDoctorError({ reason: new ProjectDiscoveryFailed({
44742
+ directory,
44743
+ cause
44744
+ }) });
44594
44745
  };
44595
44746
  var Project = class Project extends Service()("react-doctor/Project") {
44596
44747
  static layerNode = succeed$3(Project, Project.of({ discover: fn("Project.discover")(function* (directory) {
@@ -45202,6 +45353,7 @@ const resolveGithubActionsScoreMetadata = (environment = process.env) => {
45202
45353
  ...actorAssociation !== void 0 ? { githubActorAssociation: actorAssociation } : {}
45203
45354
  };
45204
45355
  };
45356
+ const toNormalizedRelativePath = (filePath, rootDirectory) => Path.relative(Path.resolve(rootDirectory), Path.resolve(rootDirectory, filePath)).replaceAll("\\", "/") || ".";
45205
45357
  const NO_HOOKS = {
45206
45358
  beforeLint: () => void_,
45207
45359
  afterLint: () => void_
@@ -45300,7 +45452,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45300
45452
  repo
45301
45453
  }).pipe(orElseSucceed(() => null)) : succeed$2(null));
45302
45454
  const lintIncludePaths = (input.skipJsxIncludeFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths], project)) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, project);
45303
- 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)) : [];
45304
45456
  const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
45305
45457
  const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
45306
45458
  yield* beforeLint(project, lintIncludePaths ?? void 0);
@@ -45405,6 +45557,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45405
45557
  let deadCodeCacheHit = null;
45406
45558
  let deadCodeSummaryCacheHits = null;
45407
45559
  let deadCodeSummaryCacheMisses = null;
45560
+ const lintFileCoverageState = { value: null };
45408
45561
  const baseLintStream = linterService.run({
45409
45562
  rootDirectory: scanDirectory,
45410
45563
  project,
@@ -45420,6 +45573,9 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45420
45573
  lastReportedTotalFileCount = totalFileCount;
45421
45574
  runSync(scanProgress.update(`Scanning files (${scannedFileCount}/${totalFileCount})${workerCountSuffix}...`));
45422
45575
  },
45576
+ onFileCoverage: (coverage) => {
45577
+ lintFileCoverageState.value = coverage;
45578
+ },
45423
45579
  onCacheStats: (cacheHitFileCount, totalConsideredFileCount) => {
45424
45580
  lintCacheHitFileCount = cacheHitFileCount;
45425
45581
  lintCacheTotalFileCount = totalConsideredFileCount;
@@ -45450,7 +45606,10 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45450
45606
  const lintFailureState = yield* get$2(lintFailure);
45451
45607
  yield* afterLint(lintFailureState.didFail);
45452
45608
  if (lintFailureState.didFail) yield* scanProgress.fail(formatLintFailText(lintFailureState.reasonTag, process.version));
45453
- 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 : [];
45454
45613
  const scannedFilesLabel = `${totalFileCount} ${totalFileCount === 1 ? "file" : "files"}`;
45455
45614
  let deadCodeCollected = [];
45456
45615
  if (lintFailureState.didFail) {
@@ -45532,6 +45691,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
45532
45691
  deadCodeOverlapped: shouldOverlapDeadCode,
45533
45692
  scannedFileCount: totalFileCount,
45534
45693
  scannedFilePaths,
45694
+ analyzedFiles,
45535
45695
  scanElapsedMilliseconds,
45536
45696
  scanConcurrency,
45537
45697
  supplyChainOverlapTimedOut: supplyChainResult.timedOut,
@@ -45807,7 +45967,7 @@ const buildJsonReportError = (input) => {
45807
45967
  sentryEventId
45808
45968
  };
45809
45969
  return {
45810
- schemaVersion: 1,
45970
+ schemaVersion: 3,
45811
45971
  version: input.version,
45812
45972
  ok: false,
45813
45973
  directory: input.directory,
@@ -45852,6 +46012,7 @@ const summarizeDiagnostics = (diagnostics, worstScore = null, worstScoreLabel =
45852
46012
  * React-runtime rule family was gated off for the project.
45853
46013
  */
45854
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;
45855
46016
  const toJsonDiff = (diff) => {
45856
46017
  if (!diff) return null;
45857
46018
  return {
@@ -45874,21 +46035,68 @@ const findWorstScoredProject = (projects) => {
45874
46035
  }
45875
46036
  return worst;
45876
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
+ };
45877
46056
  const buildJsonReport = (input) => {
45878
- const projects = input.scans.map(({ directory, result }) => ({
45879
- directory,
45880
- project: result.project,
45881
- diagnostics: result.diagnostics,
45882
- score: result.score,
45883
- skippedChecks: result.skippedChecks,
45884
- ...result.skippedCheckReasons ? { skippedCheckReasons: result.skippedCheckReasons } : {},
45885
- ...typeof result.scannedFileCount === "number" ? { scannedFileCount: result.scannedFileCount } : {},
45886
- elapsedMilliseconds: result.elapsedMilliseconds
45887
- }));
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
+ });
45888
46082
  const flattenedDiagnostics = projects.flatMap((entry) => entry.diagnostics);
45889
46083
  const worstScoredProject = findWorstScoredProject(projects);
45890
- const summary = summarizeDiagnostics(flattenedDiagnostics, worstScoredProject?.score?.score ?? null, worstScoredProject?.score?.label ?? null);
45891
- 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 } : {},
45892
46100
  ...input.scans.length > 0 ? { reactDetected: input.scans.some((scan) => hasReactRuntime(scan.result.project)) } : {},
45893
46101
  version: input.version,
45894
46102
  ok: true,
@@ -45900,39 +46108,26 @@ const buildJsonReport = (input) => {
45900
46108
  elapsedMilliseconds: input.totalElapsedMilliseconds,
45901
46109
  error: null
45902
46110
  };
45903
- if (input.baseline) return {
45904
- schemaVersion: 2,
45905
- mode: "baseline",
45906
- baseline: {
45907
- baseRef: input.baseline.baseRef,
45908
- newCount: summary.totalDiagnosticCount,
45909
- fixedCount: input.baseline.fixedCount,
45910
- baseTotalCount: input.baseline.baseTotalCount
45911
- },
45912
- ...shared
45913
- };
45914
- return {
45915
- schemaVersion: 1,
45916
- mode: input.mode,
45917
- ...input.baselineDegraded ? { baselineDegraded: true } : {},
45918
- ...shared
45919
- };
45920
46111
  };
45921
46112
  /**
45922
46113
  * Single source of truth for the skipped-check accounting shared by the
45923
46114
  * CLI renderer (`react-doctor/src/inspect.ts → finalizeAndRender`) and the
45924
46115
  * programmatic shell (`@react-doctor/api → diagnose()`). Both surface a
45925
- * 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
45926
46117
  * branch logic lives here once.
45927
46118
  */
45928
46119
  const buildSkippedChecks = (input) => {
45929
46120
  const skippedChecks = [];
45930
46121
  if (input.didLintFail) skippedChecks.push("lint");
45931
46122
  if (input.didDeadCodeFail) skippedChecks.push("dead-code");
46123
+ if (input.supplyChainOverlapTimedOut) skippedChecks.push("supply-chain");
46124
+ if (input.securityScanFailed) skippedChecks.push("security-scan");
45932
46125
  const skippedCheckReasons = {};
45933
46126
  if (input.didLintFail && input.lintFailureReason !== null) skippedCheckReasons.lint = input.lintFailureReason;
45934
46127
  else if (input.lintPartialFailures.length > 0) skippedCheckReasons["lint:partial"] = input.lintPartialFailures.join("; ");
45935
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.";
45936
46131
  return {
45937
46132
  skippedChecks,
45938
46133
  skippedCheckReasons
@@ -46347,7 +46542,7 @@ const GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS = 5e3;
46347
46542
  const CI_TRUST_COMPANIES = "PayPal, Rippling, and Alibaba";
46348
46543
  const WELCOME_EXPLANATION_HOLD_MS = 1e3;
46349
46544
  const CATEGORY_COUNTUP_SETTLE_HOLD_MS = 1e3;
46350
- 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";
46351
46546
  const SENTRY_FLUSH_TIMEOUT_MS = 2e3;
46352
46547
  const NANOSECONDS_PER_SECOND = 1000000000n;
46353
46548
  const METRIC = {
@@ -46434,7 +46629,7 @@ const makeNoopConsole = () => ({
46434
46629
  });
46435
46630
  //#endregion
46436
46631
  //#region src/cli/utils/version.ts
46437
- const VERSION = "0.7.3";
46632
+ const VERSION = "0.7.4-dev.11333b9";
46438
46633
  //#endregion
46439
46634
  //#region src/cli/utils/json-mode.ts
46440
46635
  let context = null;
@@ -46803,13 +46998,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
46803
46998
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
46804
46999
  * standard `SENTRY_RELEASE` override.
46805
47000
  */
46806
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.7.3`;
47001
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.7.4-dev.11333b9`;
46807
47002
  /**
46808
47003
  * Deployment environment shown in Sentry's environment filter. Defaults to
46809
47004
  * `production` for tagged releases and `development` for dev/unbuilt versions,
46810
47005
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
46811
47006
  */
46812
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.7.3") ? "development" : "production");
47007
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.7.4-dev.11333b9") ? "development" : "production");
46813
47008
  /**
46814
47009
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
46815
47010
  * (set to `0` to disable tracing) and falls back to
@@ -59019,12 +59214,12 @@ const resolveCacheFilePath = (projectDirectory) => path.join(resolveReactDoctorC
59019
59214
  const readPersistedCache = (cacheFilePath) => {
59020
59215
  try {
59021
59216
  const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
59022
- if (!isRecord(parsed) || parsed.version !== 4) return {
59023
- version: 4,
59217
+ if (!isRecord(parsed) || parsed.version !== 5) return {
59218
+ version: 5,
59024
59219
  entries: []
59025
59220
  };
59026
59221
  if (!Array.isArray(parsed.entries)) return {
59027
- version: 4,
59222
+ version: 5,
59028
59223
  entries: []
59029
59224
  };
59030
59225
  const entries = [];
@@ -59034,12 +59229,12 @@ const readPersistedCache = (cacheFilePath) => {
59034
59229
  entries.push(entry);
59035
59230
  }
59036
59231
  return {
59037
- version: 4,
59232
+ version: 5,
59038
59233
  entries
59039
59234
  };
59040
59235
  } catch {
59041
59236
  return {
59042
- version: 4,
59237
+ version: 5,
59043
59238
  entries: []
59044
59239
  };
59045
59240
  }
@@ -59101,7 +59296,7 @@ const buildScanResultCacheKey = (input) => {
59101
59296
  if (headSha === null) return null;
59102
59297
  if (stringifyStableJson(input.userConfig) === null) return null;
59103
59298
  const cacheKeyJson = stringifyStableJson({
59104
- schemaVersion: 4,
59299
+ schemaVersion: 5,
59105
59300
  projectIdentity: resolveProjectIdentity(input.projectDirectory),
59106
59301
  headSha,
59107
59302
  worktreeFingerprint,
@@ -59142,7 +59337,7 @@ const createScanResultCache = (projectDirectory) => {
59142
59337
  for (const entry of persistedCache.entries) entries.set(entry.key, entry);
59143
59338
  const persist = () => {
59144
59339
  writePersistedCache(cacheFilePath, {
59145
- version: 4,
59340
+ version: 5,
59146
59341
  entries: [...entries.values()].sort((firstEntry, secondEntry) => secondEntry.createdAtMs - firstEntry.createdAtMs).slice(0, 20)
59147
59342
  });
59148
59343
  };
@@ -59283,6 +59478,7 @@ const buildOutcomeAttributes = (input) => {
59283
59478
  return withNamespace("outcome", {
59284
59479
  status: "error",
59285
59480
  exitCode: 1,
59481
+ complete: false,
59286
59482
  knownError: known,
59287
59483
  errorTag: known ? error.reason._tag : error instanceof Error ? error.name : null
59288
59484
  });
@@ -59292,8 +59488,13 @@ const buildOutcomeAttributes = (input) => {
59292
59488
  const blockingLevel = resolveTelemetryBlocking(input.userConfig);
59293
59489
  const gateDiagnostics = filterDiagnosticsForSurface(result.diagnostics, "ciFailure", input.userConfig);
59294
59490
  const wouldBlock = !input.scoreOnly && !input.gateExempt && shouldBlockCi(gateDiagnostics, blockingLevel);
59295
- const hasSkippedChecks = result.skippedChecks.length > 0;
59296
- 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;
59297
59498
  const outcome = wouldBlock ? "blocked" : isClean ? "clean" : "ok";
59298
59499
  const firings = summarizeRuleFirings(result.diagnostics);
59299
59500
  const countByRule = /* @__PURE__ */ new Map();
@@ -59343,6 +59544,7 @@ const buildOutcomeAttributes = (input) => {
59343
59544
  wouldBlock,
59344
59545
  blocking: blockingLevel,
59345
59546
  clean: isClean,
59547
+ complete,
59346
59548
  skippedChecks: result.skippedChecks.length
59347
59549
  }),
59348
59550
  ...withNamespace("diag", {
@@ -60993,6 +61195,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
60993
61195
  directory: output.resolvedDirectory,
60994
61196
  scannedFileCount: output.scannedFileCount,
60995
61197
  scannedFilePaths: output.scannedFilePaths,
61198
+ analyzedFiles: output.analyzedFiles,
60996
61199
  scanElapsedMilliseconds: output.scanElapsedMilliseconds,
60997
61200
  scanConcurrency: output.scanConcurrency,
60998
61201
  baselineDelta,
@@ -61047,9 +61250,12 @@ const renderAndRecordScan = async (input) => {
61047
61250
  lintPartialFailures: input.payload.lintPartialFailures,
61048
61251
  didDeadCodeFail: input.payload.didDeadCodeFail,
61049
61252
  deadCodeFailureReason: input.payload.deadCodeFailureReason,
61253
+ supplyChainOverlapTimedOut: input.payload.supplyChainOverlapTimedOut,
61254
+ securityScanFailed: input.payload.securityScanFailed ?? false,
61050
61255
  directory: input.payload.directory,
61051
61256
  scannedFileCount: input.payload.scannedFileCount,
61052
61257
  scannedFilePaths: input.payload.scannedFilePaths,
61258
+ analyzedFiles: input.payload.analyzedFiles ?? [],
61053
61259
  scanElapsedMilliseconds: input.payload.scanElapsedMilliseconds,
61054
61260
  lintCacheHitFileCount: input.lintCacheHitFileCount ?? null,
61055
61261
  lintCacheTotalFileCount: input.lintCacheTotalFileCount ?? null,
@@ -61097,13 +61303,15 @@ const renderAndRecordScan = async (input) => {
61097
61303
  return result;
61098
61304
  };
61099
61305
  const finalizeAndRender = (input) => gen(function* () {
61100
- 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;
61101
61307
  const { skippedChecks, skippedCheckReasons } = buildSkippedChecks({
61102
61308
  didLintFail,
61103
61309
  lintFailureReason,
61104
61310
  lintPartialFailures,
61105
61311
  didDeadCodeFail,
61106
- deadCodeFailureReason
61312
+ deadCodeFailureReason,
61313
+ supplyChainOverlapTimedOut,
61314
+ securityScanFailed
61107
61315
  });
61108
61316
  const hasSkippedChecks = skippedChecks.length > 0;
61109
61317
  const noScoreMessage = buildNoScoreMessage(options.noScore);
@@ -61116,6 +61324,7 @@ const finalizeAndRender = (input) => gen(function* () {
61116
61324
  elapsedMilliseconds,
61117
61325
  scannedFileCount,
61118
61326
  scannedFilePaths,
61327
+ analyzedFiles,
61119
61328
  scanElapsedMilliseconds,
61120
61329
  ...lintCacheTotalFileCount !== null ? {
61121
61330
  lintCacheHitFileCount,
@@ -64984,4 +65193,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
64984
65193
  export {};
64985
65194
 
64986
65195
  //# sourceMappingURL=cli.js.map
64987
- //# debugId=a1ea28f2-3add-5149-82df-ab1cf0c4992e
65196
+ //# debugId=09731967-e6b8-5d9e-84b7-cb46a451b11a