react-doctor 0.9.11-dev.d23a0d7 → 0.9.11-dev.f1899d2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/{build-section-divider-0X61dfsp.js → build-section-divider-4ZztYtZV.js} +7 -7
  2. package/dist/{ci-urZW0bil.js → ci-B04VkLj2.js} +11 -11
  3. package/dist/cli.js +22 -22
  4. package/dist/{design-7VjeLeaY.js → design-AAjcvExu.js} +4 -4
  5. package/dist/{exit-gracefully-CCXBry_w.js → exit-gracefully-B7v9PIJk.js} +6 -6
  6. package/dist/index.js +123 -20
  7. package/dist/{inspect-9AYPZO5g.js → inspect-CdQJI2XI.js} +16 -16
  8. package/dist/{install-BbsK38HP.js → install-BRU4jf-Y.js} +8 -8
  9. package/dist/{install-doctor-script-dYObdsoT.js → install-doctor-script-Dn69YqKG.js} +4 -4
  10. package/dist/{install-github-workflow-CPrayyr8.js → install-github-workflow-BwELZAhu.js} +6 -6
  11. package/dist/{install-react-doctor-BRJVFDJo.js → install-react-doctor-CcDiKPfC.js} +8 -8
  12. package/dist/lsp.js +27 -16
  13. package/dist/{print-branded-header-BZazy7f_.js → print-branded-header-_kkHIAUd.js} +4 -4
  14. package/dist/{read-object-file-DpFYryjs.js → read-object-file-Bsov5R1-.js} +4 -4
  15. package/dist/{record-metric-DihVLWTw.js → record-metric-CeygoJWT.js} +49 -26
  16. package/dist/{report-error-OnDP4z6M.js → report-error-uffmJocy.js} +5 -5
  17. package/dist/{report-workflow-result-8lD74mh1.js → report-workflow-result-CMtcy7Eb.js} +5 -5
  18. package/dist/{resolve-scope-BTt7-Yy6.js → resolve-scope-CFro-KQO.js} +6 -6
  19. package/dist/{rules-CLbcyk2e.js → rules-BkLea4GL.js} +6 -6
  20. package/dist/{run-scan-app-C6_h7wam.js → run-scan-app-Befn2abh.js} +69 -36
  21. package/dist/{scan-YlECoJP4.js → scan-C00HPxuL.js} +8 -8
  22. package/dist/{should-fail-scan-gate-CwUJxo3V.js → should-fail-scan-gate-BEoC3SoQ.js} +56 -21
  23. package/dist/{should-skip-prompts-AxArMl3d.js → should-skip-prompts-De37OlfL.js} +4 -4
  24. package/dist/{unref-stdin-B9y2rq2D.js → unref-stdin-DklpxlNQ.js} +4 -4
  25. package/dist/{version-vrLffEr-.js → version-CRfqT5pV.js} +4 -4
  26. package/dist/{why-uAScZI5Z.js → why-BTbl-alh.js} +4 -4
  27. package/package.json +3 -5
@@ -1,7 +1,7 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ed19a7ba-c229-50d7-bac4-daef2756c2ae")}catch(e){}}();
3
- import { At as anonymizeInPlace, Fn as scrubSensitivePaths, M as SENTRY_FLUSH_TIMEOUT_MS, Y as CANONICAL_GITHUB_URL, a as isEnvFlagEnabled, cn as highlighter, i as isTelemetryEnabled, jt as anonymizeText, nt as DOCS_URL, o as buildSentryScope } from "./record-metric-DihVLWTw.js";
4
- import { c as isExpectedUserError } from "./unref-stdin-B9y2rq2D.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="98283582-1524-5393-968b-e62c11706c17")}catch(e){}}();
3
+ import { At as anonymizeInPlace, Fn as scrubSensitivePaths, M as SENTRY_FLUSH_TIMEOUT_MS, Y as CANONICAL_GITHUB_URL, a as isEnvFlagEnabled, cn as highlighter, i as isTelemetryEnabled, jt as anonymizeText, nt as DOCS_URL, o as buildSentryScope } from "./record-metric-CeygoJWT.js";
4
+ import { c as isExpectedUserError } from "./unref-stdin-DklpxlNQ.js";
5
5
  import * as Sentry from "@sentry/node";
6
6
  //#region src/cli/utils/scrub-sentry-event.ts
7
7
  /**
@@ -71,13 +71,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
71
71
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
72
72
  * standard `SENTRY_RELEASE` override.
73
73
  */
74
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.11-dev.d23a0d7`;
74
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.11-dev.f1899d2`;
75
75
  /**
76
76
  * Deployment environment shown in Sentry's environment filter. Defaults to
77
77
  * `production` for tagged releases and `development` for dev/unbuilt versions,
78
78
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
79
79
  */
80
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.11-dev.d23a0d7") ? "development" : "production");
80
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.11-dev.f1899d2") ? "development" : "production");
81
81
  //#endregion
82
82
  //#region src/instrument.ts
83
83
  let isInitialized = false;
@@ -227,5 +227,5 @@ const buildSectionDivider = () => highlighter.dim(`${DIVIDER_INDENT}${"─".repe
227
227
  //#endregion
228
228
  export { initializeSentry as a, flushSentry as i, buildFooterLinkLines as n, activeScanAbortRegistry as r, buildSectionDivider as t };
229
229
 
230
- //# sourceMappingURL=build-section-divider-0X61dfsp.js.map
231
- //# debugId=ed19a7ba-c229-50d7-bac4-daef2756c2ae
230
+ //# sourceMappingURL=build-section-divider-4ZztYtZV.js.map
231
+ //# debugId=98283582-1524-5393-968b-e62c11706c17
@@ -1,14 +1,14 @@
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]="81dd891c-085f-5cfd-9cd9-93c8fe9f1936")}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]="c4506989-df5f-5e29-890d-9feb446fc7b1")}catch(e){}}();
3
3
  import { n as __require, r as __toESM, t as __commonJSMin } from "./chunk-q7NCDQ7-.js";
4
- import { X as CI_URL, ar as runSync, cn as highlighter, ot as GITHUB_ACTIONS_SETUP_URL, t as recordCount, w as METRIC } from "./record-metric-DihVLWTw.js";
5
- import { c as isExpectedUserError } from "./unref-stdin-B9y2rq2D.js";
6
- import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-OnDP4z6M.js";
7
- import { L as cliLogger, c as spinner, n as findNearestPackageDirectory } from "./install-doctor-script-dYObdsoT.js";
8
- import { a as readReactDoctorWorkflow, d as detectDefaultBranch, f as runCommand, l as prompts, n as getReactDoctorWorkflowPath, s as upgradeWorkflowActionToV2, t as buildWorkflowContent } from "./install-github-workflow-CPrayyr8.js";
9
- import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, n as isScopeValue } from "./resolve-scope-BTt7-Yy6.js";
10
- import { t as shouldSkipPrompts } from "./should-skip-prompts-AxArMl3d.js";
11
- import { t as printBrandedHeader } from "./print-branded-header-BZazy7f_.js";
4
+ import { X as CI_URL, ar as runSync, cn as highlighter, ot as GITHUB_ACTIONS_SETUP_URL, t as recordCount, w as METRIC } from "./record-metric-CeygoJWT.js";
5
+ import { c as isExpectedUserError } from "./unref-stdin-DklpxlNQ.js";
6
+ import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-uffmJocy.js";
7
+ import { L as cliLogger, c as spinner, n as findNearestPackageDirectory } from "./install-doctor-script-Dn69YqKG.js";
8
+ import { a as readReactDoctorWorkflow, d as detectDefaultBranch, f as runCommand, l as prompts, n as getReactDoctorWorkflowPath, s as upgradeWorkflowActionToV2, t as buildWorkflowContent } from "./install-github-workflow-BwELZAhu.js";
9
+ import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, n as isScopeValue } from "./resolve-scope-CFro-KQO.js";
10
+ import { t as shouldSkipPrompts } from "./should-skip-prompts-De37OlfL.js";
11
+ import { t as printBrandedHeader } from "./print-branded-header-_kkHIAUd.js";
12
12
  import * as path$1 from "node:path";
13
13
  import * as fs$1 from "node:fs";
14
14
  //#region src/cli/utils/ci/ci-provider.ts
@@ -7497,5 +7497,5 @@ const ciConfigAction = (options) => runCiCommand("config", runCiConfig, options)
7497
7497
  //#endregion
7498
7498
  export { ciConfigAction, ciInstallAction, ciUpgradeAction };
7499
7499
 
7500
- //# sourceMappingURL=ci-urZW0bil.js.map
7501
- //# debugId=81dd891c-085f-5cfd-9cd9-93c8fe9f1936
7500
+ //# sourceMappingURL=ci-B04VkLj2.js.map
7501
+ //# debugId=c4506989-df5f-5e29-890d-9feb446fc7b1
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
 
2
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]="c779427c-ed7c-5be4-b123-73410d3af015")}catch(e){}}();
3
3
  import { n as __require, r as __toESM, t as __commonJSMin } from "./chunk-q7NCDQ7-.js";
4
- import { In as setColorEnabled, R as CliInputError, V as isDebugFlagEnabled, X as CI_URL, Y as CANONICAL_GITHUB_URL, cn as highlighter, d as isJsonModeActive, g as VERSION, i as isTelemetryEnabled, m as writeJsonErrorReport } from "./record-metric-DihVLWTw.js";
5
- import { c as isExpectedUserError, r as getLastRunTraceId, s as shutdownTelemetry, t as unrefStdin } from "./unref-stdin-B9y2rq2D.js";
6
- import { a as initializeSentry, i as flushSentry } from "./build-section-divider-0X61dfsp.js";
7
- import { t as exitGracefully } from "./exit-gracefully-CCXBry_w.js";
8
- import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-OnDP4z6M.js";
4
+ import { In as setColorEnabled, R as CliInputError, V as isDebugFlagEnabled, X as CI_URL, Y as CANONICAL_GITHUB_URL, cn as highlighter, d as isJsonModeActive, g as VERSION, i as isTelemetryEnabled, m as writeJsonErrorReport } from "./record-metric-CeygoJWT.js";
5
+ import { c as isExpectedUserError, r as getLastRunTraceId, s as shutdownTelemetry, t as unrefStdin } from "./unref-stdin-DklpxlNQ.js";
6
+ import { a as initializeSentry, i as flushSentry } from "./build-section-divider-4ZztYtZV.js";
7
+ import { t as exitGracefully } from "./exit-gracefully-B7v9PIJk.js";
8
+ import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-uffmJocy.js";
9
9
  import { execFileSync } from "node:child_process";
10
10
  //#region ../../node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/error.js
11
11
  var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
@@ -3481,7 +3481,7 @@ ${highlighter.dim("Learn more:")}
3481
3481
  const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
3482
3482
  const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("--no-cache", "disable all scan caches for this run").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS and inline HTML script source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks (honors --project and config `projects`; exits 0 when nothing is staged)").option("--max-duration <seconds>", MAX_DURATION_OPTION_DESCRIPTION).option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
3483
3483
  program.action(async (directory = ".", flags) => {
3484
- const { runScanCommand } = await import("./scan-YlECoJP4.js");
3484
+ const { runScanCommand } = await import("./scan-C00HPxuL.js");
3485
3485
  return runScanCommand({
3486
3486
  directory,
3487
3487
  flags,
@@ -3489,72 +3489,72 @@ program.action(async (directory = ".", flags) => {
3489
3489
  });
3490
3490
  });
3491
3491
  program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action(async (directory, _options, command) => {
3492
- const { designAction } = await import("./design-7VjeLeaY.js");
3492
+ const { designAction } = await import("./design-AAjcvExu.js");
3493
3493
  return designAction(directory ?? ".", command.optsWithGlobals());
3494
3494
  });
3495
3495
  program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async (location, options) => {
3496
- const { whyAction } = await import("./why-uAScZI5Z.js");
3496
+ const { whyAction } = await import("./why-BTbl-alh.js");
3497
3497
  return whyAction(location, options);
3498
3498
  });
3499
3499
  program.command("install").alias("setup").description("Install the react-doctor skill into your coding agents and optional git hook").option("-y, --yes", "skip prompts, install for all detected agents").option("--dry-run", "show what would be installed without writing files").option("--agent-hooks", "install native non-blocking agent hooks for Claude Code and Cursor").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderInstallHelpEpilog).action(async (options, command) => {
3500
- const { installAction } = await import("./install-BbsK38HP.js");
3500
+ const { installAction } = await import("./install-BRU4jf-Y.js");
3501
3501
  return installAction(options, command);
3502
3502
  });
3503
3503
  const providerOption = ["--provider <name>", "ci provider: github-actions or gitlab-ci (auto-detected by default)"];
3504
3504
  const prOption = ["--pr", "open a pull request with the change instead of writing it to the working tree"];
3505
3505
  const ci = program.command("ci").description("Set up, upgrade, and configure React Doctor in your CI");
3506
3506
  ci.command("install").description("Add a CI workflow that scans every pull request").option(...providerOption).option(...prOption).option("--blocking <level>", "gate level: none (advisory, default), warning, or error").option("--scope <value>", "what a pull-request scan reports: changed (default), files, lines, full").option("--comment", "post a summary comment on each pull request").option("--no-comment", "don't post a summary comment").option("--review-comments", "add inline review comments on changed lines").option("--no-review-comments", "don't add inline review comments").option("--commit-status", "report a commit status with the health score").option("--no-commit-status", "don't report a commit status").option("-y, --yes", "skip prompts; use the defaults").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderCiHelpEpilog).action(async (_options, command) => {
3507
- const { ciInstallAction } = await import("./ci-urZW0bil.js");
3507
+ const { ciInstallAction } = await import("./ci-B04VkLj2.js");
3508
3508
  return ciInstallAction(command.optsWithGlobals());
3509
3509
  });
3510
3510
  ci.command("config").description("Change the gate, scan scope, and pull-request reporting").option(...providerOption).option("--blocking <level>", "gate level: none (advisory), warning, or error").option("--scope <value>", "what a pull-request scan reports: changed, files, lines, or full").option("--comment", "post a summary comment on each pull request").option("--no-comment", "don't post a summary comment").option("--review-comments", "add inline review comments on changed lines").option("--no-review-comments", "don't add inline review comments").option("--commit-status", "report a commit status with the health score").option("--no-commit-status", "don't report a commit status").option("-y, --yes", "skip prompts; print the current settings").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async (_options, command) => {
3511
- const { ciConfigAction } = await import("./ci-urZW0bil.js");
3511
+ const { ciConfigAction } = await import("./ci-B04VkLj2.js");
3512
3512
  return ciConfigAction(command.optsWithGlobals());
3513
3513
  });
3514
3514
  ci.command("upgrade").description("Upgrade the CI workflow to the action's current major").option(...providerOption).option(...prOption).option("-y, --yes", "skip prompts").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async (_options, command) => {
3515
- const { ciUpgradeAction } = await import("./ci-urZW0bil.js");
3515
+ const { ciUpgradeAction } = await import("./ci-B04VkLj2.js");
3516
3516
  return ciUpgradeAction(command.optsWithGlobals());
3517
3517
  });
3518
3518
  program.command("version").description("show the version with Node and platform info").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async () => {
3519
- const { versionAction } = await import("./version-vrLffEr-.js");
3519
+ const { versionAction } = await import("./version-CRfqT5pV.js");
3520
3520
  return versionAction();
3521
3521
  });
3522
3522
  const rules = program.command("rules").description("List, explain, and configure which React Doctor rules run");
3523
3523
  rules.command("list").description("List rules and the severity they run at under your config").option("--category <name>", "only show rules in a category (e.g. Performance)").option("--tag <name>", "only show rules with a tag (e.g. design, test-noise)").option("--framework <name>", "only show rules for a framework (e.g. global, nextjs)").option("--configured", "only show rules your config has changed from the default").option("--json", "output a structured JSON array").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (_options, command) => {
3524
- const { rulesListAction } = await import("./rules-CLbcyk2e.js");
3524
+ const { rulesListAction } = await import("./rules-BkLea4GL.js");
3525
3525
  return rulesListAction(command.optsWithGlobals());
3526
3526
  });
3527
3527
  rules.command("explain <rule>").description("Explain why a rule matters, its current severity, and how to configure it").option("--json", "output a structured JSON object").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, _options, command) => {
3528
- const { rulesExplainAction } = await import("./rules-CLbcyk2e.js");
3528
+ const { rulesExplainAction } = await import("./rules-BkLea4GL.js");
3529
3529
  return rulesExplainAction(rule, command.optsWithGlobals());
3530
3530
  });
3531
3531
  rules.command("set <rule> <severity>").description("Set a rule's severity: off, warn, or error").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, severity, _options, command) => {
3532
- const { rulesSetAction } = await import("./rules-CLbcyk2e.js");
3532
+ const { rulesSetAction } = await import("./rules-BkLea4GL.js");
3533
3533
  return rulesSetAction(rule, severity, command.optsWithGlobals());
3534
3534
  });
3535
3535
  rules.command("enable <rule>").description("Enable a rule at its recommended severity (or pass --severity)").option("--severity <level>", "severity to enable at: warn or error").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, _options, command) => {
3536
- const { rulesEnableAction } = await import("./rules-CLbcyk2e.js");
3536
+ const { rulesEnableAction } = await import("./rules-BkLea4GL.js");
3537
3537
  return rulesEnableAction(rule, command.optsWithGlobals());
3538
3538
  });
3539
3539
  rules.command("disable <rule>").description("Disable a rule so it never runs").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, _options, command) => {
3540
- const { rulesDisableAction } = await import("./rules-CLbcyk2e.js");
3540
+ const { rulesDisableAction } = await import("./rules-BkLea4GL.js");
3541
3541
  return rulesDisableAction(rule, command.optsWithGlobals());
3542
3542
  });
3543
3543
  rules.command("category <category> <severity>").description("Set the severity for a whole category (off, warn, error)").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (category, severity, _options, command) => {
3544
- const { rulesCategoryAction } = await import("./rules-CLbcyk2e.js");
3544
+ const { rulesCategoryAction } = await import("./rules-BkLea4GL.js");
3545
3545
  return rulesCategoryAction(category, severity, command.optsWithGlobals());
3546
3546
  });
3547
3547
  rules.command("ignore-tag <tag>").description("Skip a whole rule family by tag before linting (e.g. design)").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (tag, _options, command) => {
3548
- const { rulesIgnoreTagAction } = await import("./rules-CLbcyk2e.js");
3548
+ const { rulesIgnoreTagAction } = await import("./rules-BkLea4GL.js");
3549
3549
  return rulesIgnoreTagAction(tag, command.optsWithGlobals());
3550
3550
  });
3551
3551
  rules.command("unignore-tag <tag>").description("Stop ignoring a tag previously skipped via ignore-tag").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (tag, _options, command) => {
3552
- const { rulesUnignoreTagAction } = await import("./rules-CLbcyk2e.js");
3552
+ const { rulesUnignoreTagAction } = await import("./rules-BkLea4GL.js");
3553
3553
  return rulesUnignoreTagAction(tag, command.optsWithGlobals());
3554
3554
  });
3555
3555
  program.command("experimental-lsp", { hidden: false }).description("[experimental] run the React Doctor language server over stdio (for editors)").allowUnknownOption().action(() => {});
3556
3556
  program.command("experimental-tui [directory]", { hidden: true }).description("[experimental] interactive, scrollable scan report").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").option("--no-dead-code", "skip dead-code analysis").option("--no-supply-chain", "skip the dependency supply-chain scan").option("--score", "only print the numeric score (for scripts and CI)").option("--no-score", "skip the score API, the share URL, and crash reporting").option("--no-cache", "disable all scan caches for this run").option("--max-duration <seconds>", MAX_DURATION_OPTION_DESCRIPTION).option("-p, --project <names>", "scan specific workspace projects (comma-separated, or *)").option("-y, --yes", "skip the project prompt and scan every discovered project").action(async (directory = ".", _localOptions, command) => {
3557
- const { runScanCommand } = await import("./scan-YlECoJP4.js");
3557
+ const { runScanCommand } = await import("./scan-C00HPxuL.js");
3558
3558
  return runScanCommand({
3559
3559
  directory,
3560
3560
  flags: command.optsWithGlobals(),
@@ -1,6 +1,6 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="514aaf5d-9670-5a91-8c10-a752ac7766fc")}catch(e){}}();
3
- import { t as inspectAction } from "./inspect-9AYPZO5g.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="dac5c105-2ed3-5d50-962d-63be8c6c658f")}catch(e){}}();
3
+ import { t as inspectAction } from "./inspect-CdQJI2XI.js";
4
4
  //#region src/cli/commands/design.ts
5
5
  const designAction = async (directory, flags) => inspectAction(directory, {
6
6
  ...flags,
@@ -10,5 +10,5 @@ const designAction = async (directory, flags) => inspectAction(directory, {
10
10
  //#endregion
11
11
  export { designAction };
12
12
 
13
- //# sourceMappingURL=design-7VjeLeaY.js.map
14
- //# debugId=514aaf5d-9670-5a91-8c10-a752ac7766fc
13
+ //# sourceMappingURL=design-AAjcvExu.js.map
14
+ //# debugId=dac5c105-2ed3-5d50-962d-63be8c6c658f
@@ -1,8 +1,8 @@
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]="9d54ed8a-bca9-5d17-a520-ddaf37ea4796")}catch(e){}}();
3
- import { d as isJsonModeActive, m as writeJsonErrorReport } from "./record-metric-DihVLWTw.js";
4
- import { s as shutdownTelemetry } from "./unref-stdin-B9y2rq2D.js";
5
- import { i as flushSentry, n as buildFooterLinkLines, r as activeScanAbortRegistry, t as buildSectionDivider } from "./build-section-divider-0X61dfsp.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="78c092a4-60b1-52cf-8077-171cd2763aad")}catch(e){}}();
3
+ import { d as isJsonModeActive, m as writeJsonErrorReport } from "./record-metric-CeygoJWT.js";
4
+ import { s as shutdownTelemetry } from "./unref-stdin-DklpxlNQ.js";
5
+ import { i as flushSentry, n as buildFooterLinkLines, r as activeScanAbortRegistry, t as buildSectionDivider } from "./build-section-divider-4ZztYtZV.js";
6
6
  //#region src/cli/utils/active-tui-renderer.ts
7
7
  let activeTuiRenderer = null;
8
8
  const registerActiveTuiRenderer = (renderer) => {
@@ -44,5 +44,5 @@ const exitGracefully = () => {
44
44
  //#endregion
45
45
  export { registerActiveTuiRenderer as n, exitGracefully as t };
46
46
 
47
- //# sourceMappingURL=exit-gracefully-CCXBry_w.js.map
48
- //# debugId=9d54ed8a-bca9-5d17-a520-ddaf37ea4796
47
+ //# sourceMappingURL=exit-gracefully-B7v9PIJk.js.map
48
+ //# debugId=78c092a4-60b1-52cf-8077-171cd2763aad
package/dist/index.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]="f242ba00-ff72-511c-8c6f-3b9b01029d57")}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]="b86d99be-a791-5cdc-81b1-adc1959ba874")}catch(e){}}();
3
3
  import { i as __toESM$1, r as __require, t as __commonJSMin$1 } from "./chunk-ChKA3wi6.js";
4
4
  import { createRequire } from "node:module";
5
5
  import { 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, REACT_DOCTOR_RULE_REGISTRY, REACT_DOCTOR_SCAN_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor/core";
@@ -64303,7 +64303,8 @@ const listSourceFilesViaFilesystemCooperative = async (rootDirectory, signal) =>
64303
64303
  const listSourceFilePaths = (rootDirectory) => (listSourceFilesViaGit(rootDirectory) ?? listSourceFilesViaFilesystem(rootDirectory)).sort();
64304
64304
  const listSourceFilePathsCooperative = async (rootDirectory, signal) => (await listSourceFilesViaGitCooperative(rootDirectory, signal) ?? await listSourceFilesViaFilesystemCooperative(rootDirectory, signal)).sort();
64305
64305
  const listSourceFilesWithSize = (rootDirectory) => collectSizedSourceFiles(rootDirectory, listSourceFilePaths(rootDirectory));
64306
- const listSourceFilesCooperative = async (rootDirectory, signal) => (await collectSizedSourceFilesCooperative(rootDirectory, await listSourceFilePathsCooperative(rootDirectory, signal), signal)).map((entry) => entry.path);
64306
+ const listSourceFilesWithSizeCooperative = async (rootDirectory, signal) => collectSizedSourceFilesCooperative(rootDirectory, await listSourceFilePathsCooperative(rootDirectory, signal), signal);
64307
+ const listSourceFilesCooperative = async (rootDirectory, signal) => (await listSourceFilesWithSizeCooperative(rootDirectory, signal)).map((entry) => entry.path);
64307
64308
  const listSourceFiles = (rootDirectory) => listSourceFilesWithSize(rootDirectory).map((entry) => entry.path);
64308
64309
  const countSourceFiles = (rootDirectory) => listSourceFilesWithSize(rootDirectory).length;
64309
64310
  const NEXT_CONFIG_FILENAMES = [
@@ -74320,6 +74321,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
74320
74321
  };
74321
74322
  };
74322
74323
  const parseRuleCode = (code) => {
74324
+ if (typeof code !== "string" || code.length === 0) return {
74325
+ plugin: "unknown",
74326
+ rule: "unknown"
74327
+ };
74323
74328
  const match = code.match(/^(.+)\((.+)\)$/);
74324
74329
  if (!match) return {
74325
74330
  plugin: "unknown",
@@ -75403,7 +75408,7 @@ const runOxlint = async (options) => {
75403
75408
  const pluginPath = resolvePluginPath();
75404
75409
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
75405
75410
  const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
75406
- const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
75411
+ const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths ?? options.precomputedSourceFiles?.map((sourceFile) => sourceFile.path));
75407
75412
  const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
75408
75413
  const configPath = Path.join(configDirectory, "oxlintrc.json");
75409
75414
  try {
@@ -75436,8 +75441,8 @@ const runOxlint = async (options) => {
75436
75441
  ...sharedArgs
75437
75442
  ];
75438
75443
  await yieldToEventLoop();
75439
- const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
75440
- const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
75444
+ const sizedScanFiles = options.precomputedSourceFiles ?? (includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null);
75445
+ const candidateFiles = sizedScanFiles === null ? includePaths ?? [] : sizedScanFiles.map((entry) => entry.path);
75441
75446
  const projectIndexModuleSources = includePaths === void 0 && options.deadlineEpochMs === void 0 ? await collectProjectIndexModuleSources(rootDirectory, candidateFiles) : void 0;
75442
75447
  unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
75443
75448
  rootDirectory,
@@ -75817,6 +75822,7 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
75817
75822
  rootDirectory: input.rootDirectory,
75818
75823
  project: input.project,
75819
75824
  includePaths: input.includePaths ? [...input.includePaths] : void 0,
75825
+ precomputedSourceFiles: input.precomputedSourceFiles,
75820
75826
  nodeBinaryPath: input.nodeBinaryPath,
75821
75827
  customRulesOnly: input.customRulesOnly,
75822
75828
  respectInlineDisables: input.respectInlineDisables,
@@ -76614,22 +76620,23 @@ const runInspect = (input, hooks = {}) => gen(function* () {
76614
76620
  const relativeFilePath = toNormalizedRelativePath(diagnostic.filePath, scanDirectory);
76615
76621
  return excludedProjectRelativePaths.some((excludedRelativePath) => relativeFilePath === excludedRelativePath || relativeFilePath.startsWith(`${excludedRelativePath}/`));
76616
76622
  };
76617
- const precomputedSourceFiles = input.suppressScanSummary === true || excludedProjectDirectories.length > 0 ? yield* filesService.listSourceFilesCooperative({
76623
+ const shouldListSourceFiles = input.precomputedSourceFiles === void 0 && (input.suppressScanSummary === true || excludedProjectDirectories.length > 0);
76624
+ const precomputedSourceFilePaths = input.precomputedSourceFiles?.map((sourceFile) => sourceFile.path) ?? (shouldListSourceFiles ? yield* filesService.listSourceFilesCooperative({
76618
76625
  rootDirectory: scanDirectory,
76619
76626
  signal: input.signal
76620
- }) : null;
76621
- const includedPrecomputedSourceFiles = precomputedSourceFiles !== null && excludedProjectDirectories.length > 0 ? filterPathsOutsideDirectories({
76627
+ }) : null);
76628
+ const includedPrecomputedSourceFilePaths = precomputedSourceFilePaths !== null && excludedProjectDirectories.length > 0 ? filterPathsOutsideDirectories({
76622
76629
  rootDirectory: scanDirectory,
76623
- relativePaths: precomputedSourceFiles,
76630
+ relativePaths: precomputedSourceFilePaths,
76624
76631
  excludedDirectories: excludedProjectDirectories
76625
- }) : precomputedSourceFiles;
76626
- const sourceFileCount = excludedProjectDirectories.length > 0 ? includedPrecomputedSourceFiles?.length : input.precomputedSourceFileCount ?? includedPrecomputedSourceFiles?.length;
76632
+ }) : precomputedSourceFilePaths;
76633
+ const sourceFileCount = excludedProjectDirectories.length > 0 ? includedPrecomputedSourceFilePaths?.length : input.precomputedSourceFiles?.length ?? input.precomputedSourceFileCount ?? includedPrecomputedSourceFilePaths?.length;
76627
76634
  const project = yield* projectService.discover({
76628
76635
  directory: scanDirectory,
76629
76636
  sourceFileCount
76630
76637
  });
76631
76638
  if (!isAnalyzableProject(project)) return yield* new ReactDoctorError({ reason: new NoReactDependency({ directory: scanDirectory }) });
76632
- const deadCodeSourceFileCount = input.retainExcludedProjectDeadCodeDiagnostics === true && precomputedSourceFiles !== null ? precomputedSourceFiles.length : project.sourceFileCount;
76639
+ const deadCodeSourceFileCount = input.retainExcludedProjectDeadCodeDiagnostics === true && precomputedSourceFilePaths !== null ? precomputedSourceFilePaths.length : project.sourceFileCount;
76633
76640
  const [repo, sha, defaultBranch] = yield* all([
76634
76641
  gitService.githubRepo(scanDirectory).pipe(orElseSucceed(() => null)),
76635
76642
  gitService.headSha(scanDirectory).pipe(orElseSucceed(() => null)),
@@ -76640,13 +76647,16 @@ const runInspect = (input, hooks = {}) => gen(function* () {
76640
76647
  directory: scanDirectory,
76641
76648
  repo
76642
76649
  }).pipe(orElseSucceed(() => null)) : succeed$2(null));
76643
- let lintIncludePaths = (input.skipExplicitIncludePathFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths])) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, includedPrecomputedSourceFiles ?? void 0);
76650
+ let lintIncludePaths = (input.skipExplicitIncludePathFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths])) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, includedPrecomputedSourceFilePaths ?? void 0);
76644
76651
  if (excludedProjectDirectories.length > 0) lintIncludePaths = filterPathsOutsideDirectories({
76645
76652
  rootDirectory: scanDirectory,
76646
- relativePaths: lintIncludePaths ?? includedPrecomputedSourceFiles ?? (yield* filesService.listSourceFiles(scanDirectory)),
76653
+ relativePaths: lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? (yield* filesService.listSourceFiles(scanDirectory)),
76647
76654
  excludedDirectories: excludedProjectDirectories
76648
76655
  });
76649
- const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? includedPrecomputedSourceFiles ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
76656
+ const suppliedSourceFiles = input.precomputedSourceFiles;
76657
+ const includedPrecomputedSourceFilePathSet = suppliedSourceFiles === void 0 || input.includePaths.length > 0 ? null : new Set(lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? []);
76658
+ const precomputedLintSourceFiles = includedPrecomputedSourceFilePathSet === null || suppliedSourceFiles === void 0 ? void 0 : suppliedSourceFiles.filter((sourceFile) => includedPrecomputedSourceFilePathSet.has(sourceFile.path));
76659
+ const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? includedPrecomputedSourceFilePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
76650
76660
  const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
76651
76661
  const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
76652
76662
  yield* beforeLint(project);
@@ -76779,6 +76789,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
76779
76789
  rootDirectory: scanDirectory,
76780
76790
  project,
76781
76791
  includePaths: lintIncludePaths ?? void 0,
76792
+ precomputedSourceFiles: precomputedLintSourceFiles,
76782
76793
  nodeBinaryPath: input.nodeBinaryPath,
76783
76794
  customRulesOnly: input.customRulesOnly,
76784
76795
  respectInlineDisables: input.respectInlineDisables,
@@ -77375,6 +77386,39 @@ const getDiffInfo = (directory, explicitBaseBranch, includeUntracked) => runProm
77375
77386
  };
77376
77387
  }).pipe(provide(Git.layerNode)));
77377
77388
  const filterSourceFiles = (filePaths) => filePaths.filter(isLintableSourceFile);
77389
+ const collectSourceFilesByDirectory = async (rootDirectory, projectDirectories, signal) => {
77390
+ const resolvedRootDirectory = Path.resolve(rootDirectory);
77391
+ const sourceFilesByDirectory = /* @__PURE__ */ new Map();
77392
+ const projectDirectoryByRelativePath = /* @__PURE__ */ new Map();
77393
+ for (const projectDirectory of projectDirectories) {
77394
+ const resolvedProjectDirectory = Path.resolve(projectDirectory);
77395
+ const relativeDirectory = Path.relative(resolvedRootDirectory, resolvedProjectDirectory);
77396
+ if (Path.isAbsolute(relativeDirectory) || relativeDirectory === ".." || relativeDirectory.startsWith(`..${Path.sep}`)) continue;
77397
+ sourceFilesByDirectory.set(resolvedProjectDirectory, []);
77398
+ projectDirectoryByRelativePath.set(relativeDirectory.replaceAll(Path.sep, "/"), resolvedProjectDirectory);
77399
+ }
77400
+ const sourceFiles = await listSourceFilesWithSizeCooperative(resolvedRootDirectory, signal);
77401
+ for (const sourceFile of sourceFiles) {
77402
+ let relativeDirectory = Path.posix.dirname(sourceFile.path);
77403
+ while (true) {
77404
+ const normalizedRelativeDirectory = relativeDirectory === "." ? "" : relativeDirectory;
77405
+ const projectDirectory = projectDirectoryByRelativePath.get(normalizedRelativeDirectory);
77406
+ if (projectDirectory !== void 0) {
77407
+ const projectRelativePath = Path.posix.relative(normalizedRelativeDirectory, sourceFile.path);
77408
+ const projectSourceFiles = sourceFilesByDirectory.get(projectDirectory);
77409
+ if (projectSourceFiles === void 0) break;
77410
+ projectSourceFiles.push({
77411
+ path: projectRelativePath,
77412
+ sizeBytes: sourceFile.sizeBytes
77413
+ });
77414
+ break;
77415
+ }
77416
+ if (relativeDirectory === ".") break;
77417
+ relativeDirectory = Path.posix.dirname(relativeDirectory);
77418
+ }
77419
+ }
77420
+ return sourceFilesByDirectory;
77421
+ };
77378
77422
  const createLintPhaseAbortError = () => new ReactDoctorError({ reason: new OxlintSpawnFailed({ cause: "lint phase aborted" }) });
77379
77423
  const createOxlintSpawnSlots = (concurrency) => createWorkerSlots({
77380
77424
  slotCount: resolveScanConcurrency(concurrency),
@@ -77462,6 +77506,60 @@ const mergeReactDoctorConfigs = (baseConfig, overrideConfig) => {
77462
77506
  };
77463
77507
  //#endregion
77464
77508
  //#region ../api/dist/index.js
77509
+ const resolveProjectGroupRoot = (projectDirectory) => {
77510
+ try {
77511
+ return isMonorepoRoot(projectDirectory) ? projectDirectory : findMonorepoRoot(projectDirectory);
77512
+ } catch {
77513
+ return null;
77514
+ }
77515
+ };
77516
+ const containsNestedProjectDirectories = (projectDirectories) => projectDirectories.some((projectDirectory, projectIndex) => projectDirectories.some((candidateDirectory, candidateIndex) => candidateIndex !== projectIndex && isPathInsideDirectory(candidateDirectory, projectDirectory)));
77517
+ const resolveCommonAncestorDirectory = (projectDirectories) => {
77518
+ let commonDirectory = projectDirectories[0];
77519
+ for (const projectDirectory of projectDirectories.slice(1)) while (commonDirectory !== projectDirectory && !isPathInsideDirectory(projectDirectory, commonDirectory)) commonDirectory = Path.dirname(commonDirectory);
77520
+ return commonDirectory;
77521
+ };
77522
+ const collectGroupSourceFiles = async (projectDirectories) => {
77523
+ if (projectDirectories.length === 1 || containsNestedProjectDirectories(projectDirectories)) return /* @__PURE__ */ new Map();
77524
+ try {
77525
+ return await collectSourceFilesByDirectory(resolveCommonAncestorDirectory(projectDirectories), projectDirectories);
77526
+ } catch {
77527
+ return /* @__PURE__ */ new Map();
77528
+ }
77529
+ };
77530
+ const compareProjectPlanEntries = (leftEntry, rightEntry) => {
77531
+ const leftSourceFileCount = leftEntry.precomputedSourceFiles?.length;
77532
+ const rightSourceFileCount = rightEntry.precomputedSourceFiles?.length;
77533
+ if (leftSourceFileCount === rightSourceFileCount) return leftEntry.originalIndex - rightEntry.originalIndex;
77534
+ if (leftSourceFileCount === void 0) return 1;
77535
+ if (rightSourceFileCount === void 0) return -1;
77536
+ return rightSourceFileCount - leftSourceFileCount;
77537
+ };
77538
+ const buildDiagnoseProjectPlan = async (projects) => {
77539
+ const projectDirectoriesByRootDirectory = /* @__PURE__ */ new Map();
77540
+ for (const project of projects) {
77541
+ const projectDirectory = Path.resolve(project.directory);
77542
+ const rootDirectory = resolveProjectGroupRoot(projectDirectory);
77543
+ if (rootDirectory === null) continue;
77544
+ const projectDirectories = projectDirectoriesByRootDirectory.get(rootDirectory);
77545
+ if (projectDirectories === void 0) projectDirectoriesByRootDirectory.set(rootDirectory, [projectDirectory]);
77546
+ else projectDirectories.push(projectDirectory);
77547
+ }
77548
+ const groupedSourceFiles = await Promise.all([...projectDirectoriesByRootDirectory.values()].map(collectGroupSourceFiles));
77549
+ const sourceFilesByDirectory = /* @__PURE__ */ new Map();
77550
+ for (const sourceFilesByProjectDirectory of groupedSourceFiles) for (const [projectDirectory, sourceFiles] of sourceFilesByProjectDirectory) {
77551
+ if (sourceFiles.length === 0) continue;
77552
+ sourceFilesByDirectory.set(projectDirectory, sourceFiles);
77553
+ }
77554
+ return projects.map((projectDefinition, originalIndex) => {
77555
+ const precomputedSourceFiles = sourceFilesByDirectory.get(Path.resolve(projectDefinition.directory));
77556
+ return {
77557
+ originalIndex,
77558
+ projectDefinition,
77559
+ ...precomputedSourceFiles === void 0 ? {} : { precomputedSourceFiles }
77560
+ };
77561
+ }).toSorted(compareProjectPlanEntries);
77562
+ };
77465
77563
  let didWarnAiTraining = false;
77466
77564
  const warnIfAiTrainingEnvironment = () => {
77467
77565
  if (didWarnAiTraining || detectAiTrainingEnvironment() === null) return;
@@ -77478,12 +77576,13 @@ const buildDiagnoseLayer = (input) => {
77478
77576
  });
77479
77577
  return mergeAll$1(Project.layerNode, configLayer, input.shouldRunDeadCode ? DeadCode.layerNode : DeadCode.layerOf([]), Files.layerNode, Git.layerNode, input.shouldRunLint ? Linter.layerOxlint : Linter.layerOf([]), LintPartialFailures.layerLive, succeed$3(OxlintConcurrency, input.oxlintConcurrency), succeed$3(OxlintSpawnSlots, input.oxlintSpawnSlots), Progress.layerNoop, Reporter.layerNoop, Score.layerHttp, input.config?.supplyChain?.enabled !== false ? SupplyChain.layerNode : SupplyChain.layerOf([]));
77480
77578
  };
77481
- const buildInspectProgram = (scanTarget, options, configOverride) => {
77579
+ const buildInspectProgram = (scanTarget, options, configOverride, precomputedSourceFiles) => {
77482
77580
  const effectiveConfig = configOverride ?? scanTarget.userConfig;
77483
77581
  const includePaths = options.includePaths ?? [];
77484
77582
  const shouldRunDeadCode = resolveShouldRunDeadCode(options, effectiveConfig);
77485
77583
  return runInspect({
77486
77584
  directory: scanTarget.resolvedDirectory,
77585
+ precomputedSourceFiles,
77487
77586
  includePaths,
77488
77587
  customRulesOnly: effectiveConfig?.customRulesOnly ?? false,
77489
77588
  respectInlineDisables: options.respectInlineDisables ?? effectiveConfig?.respectInlineDisables ?? true,
@@ -77539,7 +77638,7 @@ const findWorstScore = (projectResults) => {
77539
77638
  }
77540
77639
  return worstResult;
77541
77640
  };
77542
- const diagnoseProject = async (projectDefinition, baseOptions, batchConfig, oxlintConcurrency, oxlintSpawnSlots) => {
77641
+ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig, oxlintConcurrency, oxlintSpawnSlots, precomputedSourceFiles) => {
77543
77642
  const startTime = globalThis.performance.now();
77544
77643
  try {
77545
77644
  const scanTarget = await resolveScanTarget(projectDefinition.directory);
@@ -77552,7 +77651,8 @@ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig, oxli
77552
77651
  };
77553
77652
  const shouldRunLint = resolveShouldRunLint(mergedOptions, effectiveConfig);
77554
77653
  const shouldRunDeadCode = resolveShouldRunDeadCode(mergedOptions, effectiveConfig);
77555
- const program = buildInspectProgram(scanTarget, mergedOptions, effectiveConfig ?? void 0);
77654
+ const canReusePrecomputedSourceFiles = Path.resolve(projectDefinition.directory) === Path.resolve(scanTarget.resolvedDirectory);
77655
+ const program = buildInspectProgram(scanTarget, mergedOptions, effectiveConfig ?? void 0, canReusePrecomputedSourceFiles ? precomputedSourceFiles : void 0);
77556
77656
  const didOverridePlugins = batchConfig?.plugins !== void 0 || projectConfig?.plugins !== void 0;
77557
77657
  const layer = buildDiagnoseLayer(didOverrideConfig ? {
77558
77658
  config: effectiveConfig,
@@ -77590,7 +77690,10 @@ const diagnoseProjectBatch = async (input) => {
77590
77690
  const { projects, concurrency, config: batchConfig, ...baseOptions } = input;
77591
77691
  const oxlintConcurrency = runSync(OxlintConcurrency);
77592
77692
  const oxlintSpawnSlots = createOxlintSpawnSlots(oxlintConcurrency);
77593
- const projectResults = await mapWithConcurrency(projects, concurrency ?? 4, (projectDefinition) => diagnoseProject(projectDefinition, baseOptions, batchConfig, oxlintConcurrency, oxlintSpawnSlots));
77693
+ const projectResults = (await mapWithConcurrency(await buildDiagnoseProjectPlan(projects), concurrency ?? 4, async (projectPlanEntry) => ({
77694
+ originalIndex: projectPlanEntry.originalIndex,
77695
+ result: await diagnoseProject(projectPlanEntry.projectDefinition, baseOptions, batchConfig, oxlintConcurrency, oxlintSpawnSlots, projectPlanEntry.precomputedSourceFiles)
77696
+ }))).toSorted((leftProject, rightProject) => leftProject.originalIndex - rightProject.originalIndex).map((completedProject) => completedProject.result);
77594
77697
  const succeededProjects = projectResults.filter((projectResult) => projectResult.ok);
77595
77698
  return {
77596
77699
  projects: projectResults,
@@ -77635,4 +77738,4 @@ const toJsonReport = (result, options) => buildJsonReport({
77635
77738
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
77636
77739
 
77637
77740
  //# sourceMappingURL=index.js.map
77638
- //# debugId=f242ba00-ff72-511c-8c6f-3b9b01029d57
77741
+ //# debugId=b86d99be-a791-5cdc-81b1-adc1959ba874
@@ -1,17 +1,17 @@
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]="033a9730-de20-5018-88ec-b4d3adf1ded9")}catch(e){}}();
3
- import { Cn as mapWithConcurrency, Dn as remainingDeadlineBudgetMs, En as messageFromUnknown, F as STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES, G as isCiOrCodingAgentEnvironment, Gt as discoverReactSubprojects, K as isCodingAgentEnvironment, Mn as resolveScanTarget, Nt as buildJsonReport, Ot as StagedFiles, P as STAGED_FILES_TEMP_DIR_PREFIX, Qt as getBaselineDiffPlan, R as CliInputError, Tt as STAGED_FILES_PROJECT_CONFIG_FILENAMES, V as isDebugFlagEnabled, Wt as detectAiTrainingEnvironment, Xn as gen, Y as CANONICAL_GITHUB_URL, Yt as findLegacyConfig, cn as highlighter, ct as Git, dr as provide, en as getChangedLineRanges, f as setJsonReportDirectory, g as VERSION, h as writeJsonReport, ir as runPromise, m as writeJsonErrorReport, mn as isPlainObject, n as recordDistribution, nn as getDiffInfo, on as hasReactRuntime, p as setJsonReportMode, pn as isPathInsideDirectory, t as recordCount, tr as provide$1, u as enableJsonMode, un as isErrnoException, w as METRIC, xn as listWorkspacePackages, zn as toRelativePath } from "./record-metric-DihVLWTw.js";
4
- import { c as isExpectedUserError, s as shutdownTelemetry } from "./unref-stdin-B9y2rq2D.js";
5
- import { i as flushSentry } from "./build-section-divider-0X61dfsp.js";
6
- import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-OnDP4z6M.js";
7
- import { F as runGitRaw, L as cliLogger, c as spinner, i as hasDoctorScript, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-dYObdsoT.js";
8
- import { a as readReactDoctorWorkflow, c as workflowUsesV1Action, i as isReactDoctorWorkflowInstalled, l as prompts, s as upgradeWorkflowActionToV2 } from "./install-github-workflow-CPrayyr8.js";
9
- import { c as openWorkflowPullRequest, i as warnDeprecatedDiff, l as stageWorkflowFile, r as resolveScope, s as resolveBlockingLevel, t as finalizeScope, u as toForwardSlashes } from "./resolve-scope-BTt7-Yy6.js";
10
- import { t as shouldSkipPrompts } from "./should-skip-prompts-AxArMl3d.js";
11
- import { A as resolveMergeBaseRef, B as buildEmptyReportMessage, C as copyToClipboard, D as deduplicateProjectScans, E as collectProjectSourceFileCounts, F as printDiagnosticsDump, O as createInvocationInspect, R as filterDiagnosticsByCategories, S as CLI_AGENT_BINARIES, T as buildHandoffPayload, _ as resolveCliInspectOptions, a as projectManifestChanged, b as setUpGitHubActions, c as selectProjects, d as resolveProjectChangedLineRanges, f as resolveProjectDiffIncludePaths, g as resolveWorkspaceDeadCodeOwner, h as retryMissingProjectScores, i as validateModeFlags, j as printHeadlessReport, k as inspect, l as buildCodeFrame, m as resolveProjectRelativeDirectory, n as formatSkippedProjectsMessage, o as partitionProjectScanOutcomes, p as resolveProjectSourceFilePaths, r as validateIncludeUntrackedScope, t as shouldFailScanGate, u as resolveProjectScan, v as filterScansForSurface, w as launchCliAgent, x as detectLaunchableAgents, y as countUniqueScannedFiles } from "./should-fail-scan-gate-CwUJxo3V.js";
12
- import { a as recordGate, i as readPreference, o as runMigrations, p as SETUP_HINT_EVENT, r as isGatePending, s as writePreference, u as HANDOFF_TARGET_PREFERENCE_ID } from "./report-workflow-result-8lD74mh1.js";
13
- import { a as askUpgradeActionVersion, c as recordCiPromptDecision, i as installReactDoctorAgentHooks, l as hasHandledActionUpgrade, o as askAddToGitHubActions, r as findAgentsWithLegacyShellHooks, s as hasHandledCiPrompt, t as getSkillSourceDirectory, u as recordActionUpgradeDecision } from "./install-react-doctor-BRJVFDJo.js";
14
- import { t as readObjectFile } from "./read-object-file-DpFYryjs.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c230a02a-29bb-5b01-b0a5-4bd9caed97cc")}catch(e){}}();
3
+ import { Cn as mapWithConcurrency, Dn as remainingDeadlineBudgetMs, En as messageFromUnknown, F as STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES, G as isCiOrCodingAgentEnvironment, Gt as discoverReactSubprojects, K as isCodingAgentEnvironment, Mn as resolveScanTarget, Nt as buildJsonReport, Ot as StagedFiles, P as STAGED_FILES_TEMP_DIR_PREFIX, Qt as getBaselineDiffPlan, R as CliInputError, Tt as STAGED_FILES_PROJECT_CONFIG_FILENAMES, V as isDebugFlagEnabled, Wt as detectAiTrainingEnvironment, Xn as gen, Y as CANONICAL_GITHUB_URL, Yt as findLegacyConfig, cn as highlighter, ct as Git, dr as provide, en as getChangedLineRanges, f as setJsonReportDirectory, g as VERSION, h as writeJsonReport, ir as runPromise, m as writeJsonErrorReport, mn as isPlainObject, n as recordDistribution, nn as getDiffInfo, on as hasReactRuntime, p as setJsonReportMode, pn as isPathInsideDirectory, t as recordCount, tr as provide$1, u as enableJsonMode, un as isErrnoException, w as METRIC, xn as listWorkspacePackages, zn as toRelativePath } from "./record-metric-CeygoJWT.js";
4
+ import { c as isExpectedUserError, s as shutdownTelemetry } from "./unref-stdin-DklpxlNQ.js";
5
+ import { i as flushSentry } from "./build-section-divider-4ZztYtZV.js";
6
+ import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-uffmJocy.js";
7
+ import { F as runGitRaw, L as cliLogger, c as spinner, i as hasDoctorScript, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-Dn69YqKG.js";
8
+ import { a as readReactDoctorWorkflow, c as workflowUsesV1Action, i as isReactDoctorWorkflowInstalled, l as prompts, s as upgradeWorkflowActionToV2 } from "./install-github-workflow-BwELZAhu.js";
9
+ import { c as openWorkflowPullRequest, i as warnDeprecatedDiff, l as stageWorkflowFile, r as resolveScope, s as resolveBlockingLevel, t as finalizeScope, u as toForwardSlashes } from "./resolve-scope-CFro-KQO.js";
10
+ import { t as shouldSkipPrompts } from "./should-skip-prompts-De37OlfL.js";
11
+ import { A as resolveMergeBaseRef, B as buildEmptyReportMessage, C as copyToClipboard, D as deduplicateProjectScans, E as collectProjectSourceFileCounts, F as printDiagnosticsDump, O as createInvocationInspect, R as filterDiagnosticsByCategories, S as CLI_AGENT_BINARIES, T as buildHandoffPayload, _ as resolveCliInspectOptions, a as projectManifestChanged, b as setUpGitHubActions, c as selectProjects, d as resolveProjectChangedLineRanges, f as resolveProjectDiffIncludePaths, g as resolveWorkspaceDeadCodeOwner, h as retryMissingProjectScores, i as validateModeFlags, j as printHeadlessReport, k as inspect, l as buildCodeFrame, m as resolveProjectRelativeDirectory, n as formatSkippedProjectsMessage, o as partitionProjectScanOutcomes, p as resolveProjectSourceFilePaths, r as validateIncludeUntrackedScope, t as shouldFailScanGate, u as resolveProjectScan, v as filterScansForSurface, w as launchCliAgent, x as detectLaunchableAgents, y as countUniqueScannedFiles } from "./should-fail-scan-gate-BEoC3SoQ.js";
12
+ import { a as recordGate, i as readPreference, o as runMigrations, p as SETUP_HINT_EVENT, r as isGatePending, s as writePreference, u as HANDOFF_TARGET_PREFERENCE_ID } from "./report-workflow-result-CMtcy7Eb.js";
13
+ import { a as askUpgradeActionVersion, c as recordCiPromptDecision, i as installReactDoctorAgentHooks, l as hasHandledActionUpgrade, o as askAddToGitHubActions, r as findAgentsWithLegacyShellHooks, s as hasHandledCiPrompt, t as getSkillSourceDirectory, u as recordActionUpgradeDecision } from "./install-react-doctor-CcDiKPfC.js";
14
+ import { t as readObjectFile } from "./read-object-file-Bsov5R1-.js";
15
15
  import * as path$1 from "node:path";
16
16
  import * as fs$1 from "node:fs";
17
17
  import { tmpdir } from "node:os";
@@ -659,7 +659,7 @@ const parseStagedSnapshotDivergences = (statusOutput) => {
659
659
  const hasRenameOrCopySource = indexStatus === "R" || indexStatus === "C" || worktreeStatus === "R" || worktreeStatus === "C";
660
660
  const sourcePath = hasRenameOrCopySource ? statusEntries[entryIndex + 1] : void 0;
661
661
  const worktreePaths = worktreeStatus === "R" || worktreeStatus === "C" ? [filePath, sourcePath] : [filePath];
662
- if (worktreeStatus !== " ") {
662
+ if (worktreeStatus !== " " && worktreeStatus !== "!") {
663
663
  for (const worktreePath of worktreePaths) if (worktreePath && SNAPSHOT_CONFIG_FILENAMES.has(path$1.basename(worktreePath))) divergentConfigFiles.add(worktreePath);
664
664
  }
665
665
  if (hasRenameOrCopySource) entryIndex += 1;
@@ -1439,5 +1439,5 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
1439
1439
  //#endregion
1440
1440
  export { warnDeprecatedFailOn as n, runProjectMigrations as r, inspectAction as t };
1441
1441
 
1442
- //# sourceMappingURL=inspect-9AYPZO5g.js.map
1443
- //# debugId=033a9730-de20-5018-88ec-b4d3adf1ded9
1442
+ //# sourceMappingURL=inspect-CdQJI2XI.js.map
1443
+ //# debugId=c230a02a-29bb-5b01-b0a5-4bd9caed97cc
@@ -1,10 +1,10 @@
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]="861d9cb7-d9cc-5b36-9ac4-cdca99528775")}catch(e){}}();
3
- import { ar as runSync, t as recordCount, w as METRIC } from "./record-metric-DihVLWTw.js";
4
- import { c as isExpectedUserError } from "./unref-stdin-B9y2rq2D.js";
5
- import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-OnDP4z6M.js";
6
- import { t as printBrandedHeader } from "./print-branded-header-BZazy7f_.js";
7
- import { n as runInstallReactDoctor } from "./install-react-doctor-BRJVFDJo.js";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1b04cd8c-6d2b-5b04-bf05-6ef485988eb7")}catch(e){}}();
3
+ import { ar as runSync, t as recordCount, w as METRIC } from "./record-metric-CeygoJWT.js";
4
+ import { c as isExpectedUserError } from "./unref-stdin-DklpxlNQ.js";
5
+ import { n as handleError, r as handleUserError, t as reportErrorToSentry } from "./report-error-uffmJocy.js";
6
+ import { t as printBrandedHeader } from "./print-branded-header-_kkHIAUd.js";
7
+ import { n as runInstallReactDoctor } from "./install-react-doctor-CcDiKPfC.js";
8
8
  //#region src/cli/commands/install.ts
9
9
  const installAction = async (options, command) => {
10
10
  recordCount(METRIC.cliInvoked, 1, { command: "install" });
@@ -28,5 +28,5 @@ const installAction = async (options, command) => {
28
28
  //#endregion
29
29
  export { installAction };
30
30
 
31
- //# sourceMappingURL=install-BbsK38HP.js.map
32
- //# debugId=861d9cb7-d9cc-5b36-9ac4-cdca99528775
31
+ //# sourceMappingURL=install-BRU4jf-Y.js.map
32
+ //# debugId=1b04cd8c-6d2b-5b04-bf05-6ef485988eb7