react-doctor 0.9.15-dev.3242a81 → 0.9.15-dev.8ed70df

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 (37) hide show
  1. package/README.md +25 -0
  2. package/dist/{build-section-divider-B-Bbahk_.js → build-section-divider-BSEx7sis.js} +4 -4
  3. package/dist/{ci-D_GhoEkY.js → ci-D4R9kdc2.js} +12 -12
  4. package/dist/cli.js +27 -26
  5. package/dist/constants-DJ3RtEMu.js +2 -2
  6. package/dist/{design-B8EMFKlN.js → design-T850ewH9.js} +4 -4
  7. package/dist/{exit-gracefully-BTVhlyoR.js → exit-gracefully-DkeS8hHp.js} +6 -6
  8. package/dist/{handle-error-JId9eFQ_.js → handle-error-RLjKeLDA.js} +5 -5
  9. package/dist/index.d.ts +13 -8
  10. package/dist/index.js +29 -6
  11. package/dist/{inspect-ClJlUcd6.js → inspect-DuT3v6KA.js} +88 -29
  12. package/dist/{install-bAES9fz_.js → install-BeahaWiL.js} +9 -9
  13. package/dist/{install-doctor-script-ByhqWGm4.js → install-doctor-script-B84ViKF6.js} +4 -4
  14. package/dist/{install-github-workflow-CMVYSVGv.js → install-github-workflow-BunRUQaF.js} +4 -4
  15. package/dist/{install-react-doctor-D7cj-Foc.js → install-react-doctor-C5W2i12g.js} +8 -8
  16. package/dist/{jsx-runtime-BSGXwXUT.js → jsx-runtime-DBWv4kid.js} +5 -5
  17. package/dist/{print-branded-header-ToEzN9wS.js → print-branded-header-BNKQT5ZQ.js} +4 -4
  18. package/dist/{prompt-runtime-scan-url-B-N-pmnA.js → prompt-runtime-scan-url-Bly4Vulj.js} +5 -5
  19. package/dist/{read-object-file-BwnK2YRI.js → read-object-file-B-BZ7uYW.js} +4 -4
  20. package/dist/{record-metric-DUV0U_Gf.js → record-metric-Do1JAZVB.js} +51 -23
  21. package/dist/{report-error-Df6kpdn5.js → report-error-DL7M0AGh.js} +5 -5
  22. package/dist/{report-workflow-result-CDjrtaab.js → report-workflow-result-BSLZylKS.js} +5 -5
  23. package/dist/{resolve-scope-BQLYQkzz.js → resolve-scope-_R2u_rWR.js} +6 -6
  24. package/dist/{rules-BvI82y2z.js → rules-DD_Jp7ZA.js} +6 -6
  25. package/dist/{run-scan-app-DUzpuqlt.js → run-scan-app-B2_HYqlM.js} +10 -10
  26. package/dist/{runtime-scan-CxErJEVf.js → runtime-scan-HiSmF8di.js} +9 -9
  27. package/dist/{sanitize-runtime-url-BjEqBgwG.js → sanitize-runtime-url-c0or2L2V.js} +4 -4
  28. package/dist/{scan-Cuyc4IC8.js → scan-B4oVxvqa.js} +9 -9
  29. package/dist/{should-fail-scan-gate-Du7mOvEl.js → should-fail-scan-gate-Bjr43-87.js} +75 -62
  30. package/dist/{should-skip-prompts-DaKPFC6p.js → should-skip-prompts-DKwyzEkM.js} +4 -4
  31. package/dist/{should-use-tui-DZ2iTCn1.js → should-use-tui-DO7NdqR8.js} +4 -4
  32. package/dist/skills/react-doctor/SKILL.md +4 -0
  33. package/dist/{telemetry-runtime-o4N789Mp.js → telemetry-runtime-D3teullu.js} +6 -6
  34. package/dist/{version-CtgKUicn.js → version-Kj44qNuh.js} +4 -4
  35. package/dist/{why-BDgcBrL3.js → why-BV74fXYk.js} +4 -4
  36. package/dist/{with-run-span-Bgitvg5D.js → with-run-span-y8D-ZUGk.js} +5 -5
  37. package/package.json +2 -2
package/README.md CHANGED
@@ -59,6 +59,9 @@ This adds the workflow, scans every pull request, and posts a summary comment. C
59
59
 
60
60
  You can configure which rules to run and how to run them in `doctor.config.ts`.
61
61
 
62
+ The pnpm hardening check is off by default. To enable it, set
63
+ `rules: { "react-doctor/require-pnpm-hardening": "warn" }` in your config.
64
+
62
65
  [Learn more →](https://react.doctor/docs/configuration/config-files)
63
66
 
64
67
  ## Runtime performance traces
@@ -88,6 +91,28 @@ pages. It closes blank startup tabs before tracing and closes its scan tab after
88
91
  browser stays open. The trace is stored locally and is never uploaded, but it can contain page
89
92
  URLs, source paths, and React profiling details. Treat it as sensitive application data.
90
93
 
94
+ ## Scan scope
95
+
96
+ `--scope changed --base <ref>` reports only new findings in files touched by the diff. It scans those files at the base and in the current tree. Uncommitted changes use `HEAD` when the base is the current branch.
97
+
98
+ A match uses the rule ID, file path (following Git renames), diagnostic message, and a fingerprint of the flagged source span with whitespace normalized. Line and column numbers do not affect the match. Each base finding matches at most one current finding: two matching findings at base and three now produce one new finding. Changes elsewhere in a function do not change a finding's fingerprint. Changed flagged code or a changed message can produce a new finding.
99
+
100
+ New files have no base findings. Add `--include-untracked` to scan untracked files too. Deleted files and removed findings are not reported. `--blocking`, the exit code, and summary counts use only the unmatched current findings. The score still describes the current scan.
101
+
102
+ Use `--scope lines` to report findings on changed lines, or `--scope files` to report all findings in changed files. The default `--scope full` scans the full project.
103
+
104
+ Save a full scan once, then reuse it as the comparison base:
105
+
106
+ ```bash
107
+ react-doctor --json --blocking none > base-report.json
108
+ react-doctor --baseline base-report.json --blocking warning
109
+ react-doctor --scope changed --baseline base-report.json --blocking warning
110
+ ```
111
+
112
+ `--baseline` uses the same matching rules and skips the base scan. Use the same React Doctor version, rules, and scan options for both scans. The saved report must be a complete scan with fingerprints, not a previous comparison result. Regenerate older reports that lack fingerprints. Without Git, a saved report still works; rename matching requires Git history for the report's `sourceRevision`. With `--scope changed`, Git limits the scan to changed files when available; otherwise the full current tree is compared.
113
+
114
+ JSON reports keep schema version 3 and add optional diagnostic `fingerprint` and report `sourceRevision` fields. The `baseline` block records `source` (`"base"` or `"baseline"`), `baseRef`, `baselineFile` for saved reports, and `matchedCount`. `newCount` equals the summary finding count.
115
+
91
116
  ## Telemetry
92
117
 
93
118
  The CLI reports crashes, basic run traces, and anonymous usage counters to [Sentry](https://sentry.io/) to help us fix bugs and prioritize work.
@@ -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]="c53b4ec0-7ac7-5ffa-bdd1-c1dc074e27ea")}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]="f514ec13-e923-5fb4-9160-12c362951239")}catch(e){}}();
3
3
  import { bt as DOCS_URL, lt as CANONICAL_GITHUB_URL } from "./constants-DJ3RtEMu.js";
4
- import { Ot as highlighter } from "./record-metric-DUV0U_Gf.js";
4
+ import { kt as highlighter } from "./record-metric-Do1JAZVB.js";
5
5
  //#region src/cli/utils/resolve-measure-width.ts
6
6
  const resolveClampedWidth = (input) => {
7
7
  const terminalColumns = process.stdout.columns;
@@ -77,5 +77,5 @@ const buildSectionDivider = () => highlighter.dim(`${DIVIDER_INDENT}${"─".repe
77
77
  //#endregion
78
78
  export { buildFooterLinkLines as n, buildSectionDivider as t };
79
79
 
80
- //# sourceMappingURL=build-section-divider-B-Bbahk_.js.map
81
- //# debugId=c53b4ec0-7ac7-5ffa-bdd1-c1dc074e27ea
80
+ //# sourceMappingURL=build-section-divider-BSEx7sis.js.map
81
+ //# debugId=f514ec13-e923-5fb4-9160-12c362951239
@@ -1,16 +1,16 @@
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]="6bebe060-0f7b-51c9-afb6-d5a47c42a01f")}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]="cfbd6c92-741c-53ee-9fe2-02bf2f83f79c")}catch(e){}}();
3
3
  import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
4
4
  import { kt as GITHUB_ACTIONS_SETUP_URL, u as METRIC, ut as CI_URL } from "./constants-DJ3RtEMu.js";
5
- import { Ot as highlighter, t as recordCount, yn as runSync } from "./record-metric-DUV0U_Gf.js";
6
- import { o as isExpectedUserError } from "./telemetry-runtime-o4N789Mp.js";
7
- import { n as handleUserError, t as handleError } from "./handle-error-JId9eFQ_.js";
8
- import { t as reportErrorToSentry } from "./report-error-Df6kpdn5.js";
9
- import { N as cliLogger, c as spinner, n as findNearestPackageDirectory } from "./install-doctor-script-ByhqWGm4.js";
10
- 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-CMVYSVGv.js";
11
- import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, n as isScopeValue } from "./resolve-scope-BQLYQkzz.js";
12
- import { t as shouldSkipPrompts } from "./should-skip-prompts-DaKPFC6p.js";
13
- import { t as printBrandedHeader } from "./print-branded-header-ToEzN9wS.js";
5
+ import { kt as highlighter, t as recordCount, xn as runSync } from "./record-metric-Do1JAZVB.js";
6
+ import { o as isExpectedUserError } from "./telemetry-runtime-D3teullu.js";
7
+ import { n as handleUserError, t as handleError } from "./handle-error-RLjKeLDA.js";
8
+ import { t as reportErrorToSentry } from "./report-error-DL7M0AGh.js";
9
+ import { N as cliLogger, c as spinner, n as findNearestPackageDirectory } from "./install-doctor-script-B84ViKF6.js";
10
+ 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-BunRUQaF.js";
11
+ import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, n as isScopeValue } from "./resolve-scope-_R2u_rWR.js";
12
+ import { t as shouldSkipPrompts } from "./should-skip-prompts-DKwyzEkM.js";
13
+ import { t as printBrandedHeader } from "./print-branded-header-BNKQT5ZQ.js";
14
14
  import * as fs$1 from "node:fs";
15
15
  import * as path$1 from "node:path";
16
16
  //#region src/cli/utils/ci/ci-provider.ts
@@ -7499,5 +7499,5 @@ const ciConfigAction = (options) => runCiCommand("config", runCiConfig, options)
7499
7499
  //#endregion
7500
7500
  export { ciConfigAction, ciInstallAction, ciUpgradeAction };
7501
7501
 
7502
- //# sourceMappingURL=ci-D_GhoEkY.js.map
7503
- //# debugId=6bebe060-0f7b-51c9-afb6-d5a47c42a01f
7502
+ //# sourceMappingURL=ci-D4R9kdc2.js.map
7503
+ //# debugId=cfbd6c92-741c-53ee-9fe2-02bf2f83f79c
package/dist/cli.js CHANGED
@@ -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]="d3696fb6-15d5-5a85-b708-3f058c610990")}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]="cc8f2e34-2b12-55f0-907a-f0131fd67226")}catch(e){}}();
3
3
  import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
4
4
  import { lt as CANONICAL_GITHUB_URL, ut as CI_URL } from "./constants-DJ3RtEMu.js";
5
5
  import "./start-scan-preamble-DZknzhHU.js";
6
- import { In as isDirectory, Ot as highlighter, Rn as isFile, S as isDebugFlagEnabled, Yt as setColorEnabled, _ as VERSION, d as isJsonModeActive, h as writeJsonErrorReport, ht as filterSourceFiles, i as isTelemetryEnabled, kt as isPathInsideDirectory, y as CliInputError } from "./record-metric-DUV0U_Gf.js";
7
- import { a as initializeSentry, n as shutdownTelemetry, o as isExpectedUserError, r as flushSentry } from "./telemetry-runtime-o4N789Mp.js";
8
- import { t as exitGracefully } from "./exit-gracefully-BTVhlyoR.js";
9
- import { n as handleUserError, t as handleError } from "./handle-error-JId9eFQ_.js";
6
+ import { At as isPathInsideDirectory, Bn as isFile, Rn as isDirectory, S as isDebugFlagEnabled, Xt as setColorEnabled, _ as VERSION, d as isJsonModeActive, h as writeJsonErrorReport, ht as filterSourceFiles, i as isTelemetryEnabled, kt as highlighter, y as CliInputError } from "./record-metric-Do1JAZVB.js";
7
+ import { a as initializeSentry, n as shutdownTelemetry, o as isExpectedUserError, r as flushSentry } from "./telemetry-runtime-D3teullu.js";
8
+ import { t as exitGracefully } from "./exit-gracefully-DkeS8hHp.js";
9
+ import { n as handleUserError, t as handleError } from "./handle-error-RLjKeLDA.js";
10
10
  import { n as getLastRunTraceId } from "./active-run-trace-Dewycxda.js";
11
- import { t as reportErrorToSentry } from "./report-error-Df6kpdn5.js";
11
+ import { t as reportErrorToSentry } from "./report-error-DL7M0AGh.js";
12
12
  import { t as toForwardSlashes } from "./path-format-By20mo8A.js";
13
13
  import { t as unrefStdin } from "./unref-stdin-D-NZBFpg.js";
14
14
  import * as path$1 from "node:path";
@@ -3232,6 +3232,7 @@ const ROOT_FLAG_SPEC = {
3232
3232
  ]),
3233
3233
  longOptionsWithRequiredValues: new Set([
3234
3234
  "--base",
3235
+ "--baseline",
3235
3236
  "--category",
3236
3237
  "--changed-files-from",
3237
3238
  "--blocking",
@@ -3557,9 +3558,9 @@ ${highlighter.dim("Learn more:")}
3557
3558
  ${highlighter.info(CI_URL)}
3558
3559
  `;
3559
3560
  const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
3560
- const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[paths...]", "one project directory or source file paths to scan").option("--lint", "enable linting").option("--no-lint", "skip linting").addOption(new Option("--dead-code").hideHelp()).addOption(new Option("--no-dead-code").hideHelp()).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);
3561
+ const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[paths...]", "one project directory or source file paths to scan").option("--lint", "enable linting").option("--no-lint", "skip linting").addOption(new Option("--dead-code").hideHelp()).addOption(new Option("--no-dead-code").hideHelp()).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("--baseline <report.json>", "report only new issues compared with a saved JSON report").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);
3561
3562
  program.action(async (positionalPaths = [], flags) => {
3562
- const { runScanCommand } = await import("./scan-Cuyc4IC8.js");
3563
+ const { runScanCommand } = await import("./scan-B4oVxvqa.js");
3563
3564
  return runScanCommand({
3564
3565
  ...resolvePositionalScanInput(positionalPaths),
3565
3566
  flags,
@@ -3567,75 +3568,75 @@ program.action(async (positionalPaths = [], flags) => {
3567
3568
  });
3568
3569
  });
3569
3570
  program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action(async (directory, _options, command) => {
3570
- const { designAction } = await import("./design-B8EMFKlN.js");
3571
+ const { designAction } = await import("./design-T850ewH9.js");
3571
3572
  return designAction(directory ?? ".", command.optsWithGlobals());
3572
3573
  });
3573
3574
  program.command("scan").description("Scan a React interaction in Chrome until you press Enter").argument("[url]", "HTTP(S) URL of the running React app; detects local apps when omitted").option("-f, --format <format>", "report format: text, json, or jsonl", "text").option("--cdp <url>", "reuse Chrome at this remote-debugging endpoint").option("--trace-out <path>", "save the compressed .json.gz DevTools trace at this path").addHelpText("after", renderRuntimeScanHelpEpilog).action(async (url, options) => {
3574
- const { runtimeScanAction } = await import("./runtime-scan-CxErJEVf.js");
3575
+ const { runtimeScanAction } = await import("./runtime-scan-HiSmF8di.js");
3575
3576
  return runtimeScanAction(url, options);
3576
3577
  });
3577
3578
  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) => {
3578
- const { whyAction } = await import("./why-BDgcBrL3.js");
3579
+ const { whyAction } = await import("./why-BV74fXYk.js");
3579
3580
  return whyAction(location, options);
3580
3581
  });
3581
3582
  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 end-of-turn 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) => {
3582
- const { installAction } = await import("./install-bAES9fz_.js");
3583
+ const { installAction } = await import("./install-BeahaWiL.js");
3583
3584
  return installAction(options, command);
3584
3585
  });
3585
3586
  const providerOption = ["--provider <name>", "ci provider: github-actions or gitlab-ci (auto-detected by default)"];
3586
3587
  const prOption = ["--pr", "open a pull request with the change instead of writing it to the working tree"];
3587
3588
  const ci = program.command("ci").description("Set up, upgrade, and configure React Doctor in your CI");
3588
3589
  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) => {
3589
- const { ciInstallAction } = await import("./ci-D_GhoEkY.js");
3590
+ const { ciInstallAction } = await import("./ci-D4R9kdc2.js");
3590
3591
  return ciInstallAction(command.optsWithGlobals());
3591
3592
  });
3592
3593
  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) => {
3593
- const { ciConfigAction } = await import("./ci-D_GhoEkY.js");
3594
+ const { ciConfigAction } = await import("./ci-D4R9kdc2.js");
3594
3595
  return ciConfigAction(command.optsWithGlobals());
3595
3596
  });
3596
3597
  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) => {
3597
- const { ciUpgradeAction } = await import("./ci-D_GhoEkY.js");
3598
+ const { ciUpgradeAction } = await import("./ci-D4R9kdc2.js");
3598
3599
  return ciUpgradeAction(command.optsWithGlobals());
3599
3600
  });
3600
3601
  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 () => {
3601
- const { versionAction } = await import("./version-CtgKUicn.js");
3602
+ const { versionAction } = await import("./version-Kj44qNuh.js");
3602
3603
  return versionAction();
3603
3604
  });
3604
3605
  const rules = program.command("rules").description("List, explain, and configure which React Doctor rules run");
3605
3606
  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) => {
3606
- const { rulesListAction } = await import("./rules-BvI82y2z.js");
3607
+ const { rulesListAction } = await import("./rules-DD_Jp7ZA.js");
3607
3608
  return rulesListAction(command.optsWithGlobals());
3608
3609
  });
3609
3610
  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) => {
3610
- const { rulesExplainAction } = await import("./rules-BvI82y2z.js");
3611
+ const { rulesExplainAction } = await import("./rules-DD_Jp7ZA.js");
3611
3612
  return rulesExplainAction(rule, command.optsWithGlobals());
3612
3613
  });
3613
3614
  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) => {
3614
- const { rulesSetAction } = await import("./rules-BvI82y2z.js");
3615
+ const { rulesSetAction } = await import("./rules-DD_Jp7ZA.js");
3615
3616
  return rulesSetAction(rule, severity, command.optsWithGlobals());
3616
3617
  });
3617
3618
  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) => {
3618
- const { rulesEnableAction } = await import("./rules-BvI82y2z.js");
3619
+ const { rulesEnableAction } = await import("./rules-DD_Jp7ZA.js");
3619
3620
  return rulesEnableAction(rule, command.optsWithGlobals());
3620
3621
  });
3621
3622
  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) => {
3622
- const { rulesDisableAction } = await import("./rules-BvI82y2z.js");
3623
+ const { rulesDisableAction } = await import("./rules-DD_Jp7ZA.js");
3623
3624
  return rulesDisableAction(rule, command.optsWithGlobals());
3624
3625
  });
3625
3626
  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) => {
3626
- const { rulesCategoryAction } = await import("./rules-BvI82y2z.js");
3627
+ const { rulesCategoryAction } = await import("./rules-DD_Jp7ZA.js");
3627
3628
  return rulesCategoryAction(category, severity, command.optsWithGlobals());
3628
3629
  });
3629
3630
  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) => {
3630
- const { rulesIgnoreTagAction } = await import("./rules-BvI82y2z.js");
3631
+ const { rulesIgnoreTagAction } = await import("./rules-DD_Jp7ZA.js");
3631
3632
  return rulesIgnoreTagAction(tag, command.optsWithGlobals());
3632
3633
  });
3633
3634
  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) => {
3634
- const { rulesUnignoreTagAction } = await import("./rules-BvI82y2z.js");
3635
+ const { rulesUnignoreTagAction } = await import("./rules-DD_Jp7ZA.js");
3635
3636
  return rulesUnignoreTagAction(tag, command.optsWithGlobals());
3636
3637
  });
3637
3638
  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)").addOption(new Option("--no-dead-code").hideHelp()).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) => {
3638
- const { runScanCommand } = await import("./scan-Cuyc4IC8.js");
3639
+ const { runScanCommand } = await import("./scan-B4oVxvqa.js");
3639
3640
  return runScanCommand({
3640
3641
  directory,
3641
3642
  flags: command.optsWithGlobals(),
@@ -3675,4 +3676,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
3675
3676
  export {};
3676
3677
 
3677
3678
  //# sourceMappingURL=cli.js.map
3678
- //# debugId=d3696fb6-15d5-5a85-b708-3f058c610990
3679
+ //# debugId=cc8f2e34-2b12-55f0-907a-f0131fd67226
@@ -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]="3b95005b-24cd-50cf-8561-851ccaa5a388")}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]="b07ab884-a667-5937-9ca2-c09876a82e13")}catch(e){}}();
3
3
  import { createRequire } from "node:module";
4
4
  import * as fs$1 from "node:fs";
5
5
  import fs from "node:fs";
@@ -1032,4 +1032,4 @@ const METRIC = {
1032
1032
  export { warmReactCompilerDetection as $, OXLINT_WORKER_JOB_END_MARKER as $t, buildGitSourceListingRequest as A, TARGET_BLANK_BROWSER_SUPPORT as An, GITHUB_VIEWER_PERMISSION_TIMEOUT_MS as At, resolveGitCommand as B, MAINTAINABILITY_DUPLICATE_JSX_RULE as Bt, SENTRY_RELEASE_PREFIX as C, SUPPLY_CHAIN_CACHE_TTL_MS as Cn, ES_TARGET_YEAR_BY_NAME as Ct, TUI_REPORT_COMPACT_MAX_ROWS as D, SUPPLY_CHAIN_PLUGIN as Dn, GENERATED_BUNDLE_FILE_PATTERN as Dt, TRACKED_FILE_FLAGS_GIT_ARGUMENTS as E, SUPPLY_CHAIN_OVERLAP_TIMEOUT_MS as En, FILE_LINT_CACHE_MAX_FILE_COUNT as Et, lowerChildProcessPriority as F, VERCEL_NEXTJS_SECURITY_RELEASE_URL as Fn, HTML_FILE_PATTERN as Ft, resolvePluginPath as G, MINIFIED_SNIFF_BYTES as Gt, resolveOxlintThreadCount as H, MAINTAINABILITY_SOURCE_FILE_PATTERN as Ht, prefetchGitCommand as I, getCategoryImpact as In, IGNORED_DIRECTORIES as It, resolveTsConfigRelativePath as J, OXLINT_NODE_REQUIREMENT as Jt, resolveReactDoctorCacheDir as K, OCCURRENCE_MATCHED_CATEGORIES as Kt, prespawnOxlintWorkers as L, JSX_DUPLICATION_SOURCE_FILE_PATTERN as Lt, buildOxlintWorkerSpawnSpec as M, TELEMETRY_SHUTDOWN_TIMEOUT_MS as Mn, GIT_LS_FILES_MAX_BUFFER_BYTES as Mt, discardPrefetchedGitCommands as N, TSCONFIG_FILENAMES as Nn, GIT_SHOW_MAX_BUFFER_BYTES as Nt, TUI_REPORT_DETAIL_WIDTH_FRACTION as O, SUPPLY_CHAIN_RULE as On, GENERATED_SOURCE_DIRECTORY_PATTERN as Ot, killUnadoptedOxlintWorkers as P, TYPESCRIPT_DECLARATION_FILE_PATTERN as Pn, GIT_SOURCE_LISTING_ARGUMENTS as Pt, takeReactCompilerDetection as Q, OXLINT_SPLIT_TOTAL_BUDGET_MS as Qt, readSystemConcurrencyFacts as R, JSX_FILE_PATTERN as Rt, SENTRY_FLUSH_TIMEOUT_MS as S, SUPPLY_CHAIN_CACHE_SUBDIR as Sn, ENTERPRISE_CONTACT_URL as St, STAGED_SNAPSHOT_ADDITIONAL_CONFIG_FILENAMES as T, SUPPLY_CHAIN_IGNORED_PACKAGES as Tn, FILE_LINT_CACHE_FILENAME as Tt, resolveOxlintToolchainVersions as U, MAX_GLOB_PATTERN_LENGTH_CHARS as Ut, resolveOxlintBinary as V, MAINTAINABILITY_PLUGIN as Vt, resolveOxlintWorkerRuntime as W, MILLISECONDS_PER_SECOND as Wt, spawnOxlintWorkerProcess as X, OXLINT_OUTPUT_MAX_BYTES as Xt, setChildProcessRef as Y, OXLINT_OOM_RESCUE_BUDGET_MS as Yt, takePrespawnedOxlintWorker as Z, OXLINT_SPAWN_TIMEOUT_MS as Zt, SCAN_PREAMBLE_SKIP_FLAGS as _, SOURCE_FILE_PATTERN as _n, DIAGNOSTIC_CATEGORY_BUCKETS as _t, CACHE_DISABLED_VALUES as a, REACT_ROUTER_CAPABILITY_THRESHOLDS as an, AXIOM_METRICS_DATASET_HEADER as at, SCAN_RESULT_CACHE_MAX_HASHED_FILE_SIZE_BYTES as b, SPAWN_ARGS_MAX_LENGTH_CHARS_POSIX as bn, DOCS_URL as bt, HEAD_SHA_GIT_ARGUMENTS as c, ROOT_CAUSE_GROUPABLE_RULE_KEYS as cn, CANONICAL_DISCORD_URL as ct, METRIC_DISTRIBUTION_BOUNDARIES as d, SHARE_BASE_URL as dn, COMPILER_CLEANUP_BUCKET as dt, PROJECT_ANALYSIS_WORKER_MAX_OLD_SPACE_MB as en, ABORT_EXIT_CODES as et, MINIMUM_VTE_VERSION_FOR_HYPERLINKS as f, SIDECAR_LINT_CACHE_FILENAME as fn, COMPILER_CLEANUP_RULE_KEYS as ft, RUN_GIT_MAX_BUFFER_BYTES as g, SOCKET_PACKAGE_PAGE_BASE as gn, DEFAULT_BRANCH_CANDIDATES as gt, REPOSITORY_ROOT_GIT_ARGUMENTS as h, SOCKET_FREE_USER_AGENT as hn, CONFIG_SCHEMA_URL as ht, BASELINE_FILES_TEMP_DIR_PREFIX as i, REACT_BLOG_RSC_ADVISORY_URL as in, AXIOM_DEFAULT_DOMAIN as it, buildOxlintChildEnv as j, TELEMETRY_EXPORT_INTERVAL_MS as jn, GIT_CHECK_ATTR_MAX_BUFFER_BYTES as jt, WORKTREE_STATUS_GIT_ARGUMENTS as k, TAILWIND_POSTCSS7_COMPAT_ALIAS as kn, GITHUB_ACTIONS_SETUP_URL as kt, INTERNAL_ERROR_JSON_FALLBACK as l, SCANNED_DOT_DIRECTORIES as ln, CANONICAL_GITHUB_URL as lt, REACT_DOCTOR_CONFIG_PROJECT_NAME as m, SOCKET_FREE_PURL_API_BASE as mn, CONFIG_FINGERPRINT_FILENAMES as mt, AXIOM_METRICS_DATASET as n, PROJECT_ANALYSIS_WORKER_TIMEOUT_CEILING_MS as nn, APP_ONLY_RULE_KEYS as nt, CI_TRUST_COMPANIES as o, REACT_SERVER_DOM_PACKAGES as on, AXIOM_METRICS_PATH as ot, NANOSECONDS_PER_MILLISECOND as p, SKILL_NAME as pn, CONFIG_CACHE_TTL_MS as pt, resolveScanConcurrency as q, OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES as qt, AXIOM_TRACES_DATASET as r, PROJECT_ANALYSIS_WORKER_TIMEOUT_MS as rn, AXIOM_DATASET_HEADER as rt, GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS as s, RECOMMENDED_PNPM_MINIMUM_RELEASE_AGE_MINUTES as sn, AXIOM_TRACES_PATH as st, AXIOM_INGEST_TOKEN as t, PROJECT_ANALYSIS_WORKER_MEMORY_BUDGET_BYTES as tn, ADOPTABLE_LINT_CONFIG_FILENAMES as tt, METRIC as u, SCORE_API_URL as un, CI_URL as ut, SCAN_RESULT_CACHE_FILENAME as v, SPAWN_ARGS_MAX_LENGTH_CHARS as vn, DISABLE_DIRECTIVE_BACKUP_DIRECTORY_SEGMENTS as vt, STAGED_FILES_TEMP_DIR_PREFIX as w, SUPPLY_CHAIN_CATEGORY as wn, FETCH_TIMEOUT_MS as wt, SENTRY_DSN as x, STAGED_FILES_PROJECT_CONFIG_FILENAMES as xn, DUPLICATE_JSX_WORKER_IDLE_TIMEOUT_MS as xt, SCAN_RESULT_CACHE_GIT_ARGUMENTS as y, SPAWN_ARGS_MAX_LENGTH_CHARS_DARWIN as yn, DOCS_RULES_BASE_URL as yt, resolveConfiguredScanConcurrency as z, MAINTAINABILITY_CATEGORY as zt };
1033
1033
 
1034
1034
  //# sourceMappingURL=constants-DJ3RtEMu.js.map
1035
- //# debugId=3b95005b-24cd-50cf-8561-851ccaa5a388
1035
+ //# debugId=b07ab884-a667-5937-9ca2-c09876a82e13
@@ -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]="756ec694-1485-54d4-abaf-f39049149c20")}catch(e){}}();
3
- import { t as inspectAction } from "./inspect-ClJlUcd6.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]="e5ffd13c-b6d2-55b0-a232-c75049f3b405")}catch(e){}}();
3
+ import { t as inspectAction } from "./inspect-DuT3v6KA.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-B8EMFKlN.js.map
14
- //# debugId=756ec694-1485-54d4-abaf-f39049149c20
13
+ //# sourceMappingURL=design-T850ewH9.js.map
14
+ //# debugId=e5ffd13c-b6d2-55b0-a232-c75049f3b405
@@ -1,9 +1,9 @@
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]="32063c9c-da9d-5dfe-947f-19e8269c2729")}catch(e){}}();
3
- import { d as isJsonModeActive, m as writeJsonCancellationReport } from "./record-metric-DUV0U_Gf.js";
4
- import { n as shutdownTelemetry, r as flushSentry } from "./telemetry-runtime-o4N789Mp.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]="d971a325-9627-5365-ae95-48fe23dd3762")}catch(e){}}();
3
+ import { d as isJsonModeActive, m as writeJsonCancellationReport } from "./record-metric-Do1JAZVB.js";
4
+ import { n as shutdownTelemetry, r as flushSentry } from "./telemetry-runtime-D3teullu.js";
5
5
  import { t as activeScanAbortRegistry } from "./active-scan-abort-registry-CCTgal0O.js";
6
- import { n as buildFooterLinkLines, t as buildSectionDivider } from "./build-section-divider-B-Bbahk_.js";
6
+ import { n as buildFooterLinkLines, t as buildSectionDivider } from "./build-section-divider-BSEx7sis.js";
7
7
  //#region src/cli/utils/active-tui-renderer.ts
8
8
  let activeTuiRenderer = null;
9
9
  const registerActiveTuiRenderer = (renderer) => {
@@ -50,5 +50,5 @@ const exitGracefully = () => {
50
50
  //#endregion
51
51
  export { registerActiveTuiRenderer as n, exitGracefully as t };
52
52
 
53
- //# sourceMappingURL=exit-gracefully-BTVhlyoR.js.map
54
- //# debugId=32063c9c-da9d-5dfe-947f-19e8269c2729
53
+ //# sourceMappingURL=exit-gracefully-DkeS8hHp.js.map
54
+ //# debugId=d971a325-9627-5365-ae95-48fe23dd3762
@@ -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]="0f6436d5-fd1a-5ef8-9484-8b07ae867c1a")}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]="b73a4025-411c-54ee-9e80-13716c33dab0")}catch(e){}}();
3
3
  import { ct as CANONICAL_DISCORD_URL, lt as CANONICAL_GITHUB_URL, u as METRIC } from "./constants-DJ3RtEMu.js";
4
- import { Ln as isErrnoException, Ot as highlighter, _ as VERSION, _t as formatErrorChain, jt as isReactDoctorError, rn as error, t as recordCount, un as gen, vt as formatReactDoctorError, yn as runSync } from "./record-metric-DUV0U_Gf.js";
5
- import { c as isNpmCacheCorruptionError, l as formatEnvironmentError, s as formatNpmCacheCorruptionError, u as isEnvironmentError } from "./telemetry-runtime-o4N789Mp.js";
4
+ import { Mt as isReactDoctorError, _ as VERSION, fn as gen, in as error, kt as highlighter, t as recordCount, vt as formatErrorChain, xn as runSync, yt as formatReactDoctorError, zn as isErrnoException } from "./record-metric-Do1JAZVB.js";
5
+ import { c as isNpmCacheCorruptionError, l as formatEnvironmentError, s as formatNpmCacheCorruptionError, u as isEnvironmentError } from "./telemetry-runtime-D3teullu.js";
6
6
  //#region src/cli/utils/handle-error.ts
7
7
  const OTLP_ENDPOINT_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_ENDPOINT";
8
8
  const OTLP_AUTH_HEADER_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_AUTH_HEADER";
@@ -111,5 +111,5 @@ const handleUserError = (error$1, options = {}) => {
111
111
  //#endregion
112
112
  export { handleUserError as n, handleError as t };
113
113
 
114
- //# sourceMappingURL=handle-error-JId9eFQ_.js.map
115
- //# debugId=0f6436d5-fd1a-5ef8-9484-8b07ae867c1a
114
+ //# sourceMappingURL=handle-error-RLjKeLDA.js.map
115
+ //# debugId=b73a4025-411c-54ee-9e80-13716c33dab0
package/dist/index.d.ts CHANGED
@@ -341,7 +341,7 @@ interface Pipeable {
341
341
  */
342
342
  declare const Class$1: new () => Pipeable;
343
343
  //#endregion
344
- //#region ../core/dist/resolve-scan-concurrency-ByLNS-wF.d.ts
344
+ //#region ../core/dist/resolve-scan-concurrency-CVKviZpM.d.ts
345
345
  /**
346
346
  * A secondary source location attached to a diagnostic (oxlint's
347
347
  * non-primary labels). Editors render these as
@@ -363,6 +363,7 @@ interface DiagnosticRelatedLocation {
363
363
  }
364
364
  type DiagnosticFileContext = "test" | "story" | "production";
365
365
  interface Diagnostic {
366
+ fingerprint?: string;
366
367
  filePath: string;
367
368
  plugin: string;
368
369
  rule: string;
@@ -1271,7 +1272,10 @@ interface InspectResult {
1271
1272
  * carries the comparison totals for Codecov-style delta reporting.
1272
1273
  */
1273
1274
  baselineDelta?: {
1274
- /** The commit the base content was read from (resolved merge-base). */baseRef: string; /** Findings present at base but gone at head — resolved by the change. */
1275
+ /** Git ref or saved report path used for comparison. */baseRef: string;
1276
+ source?: "base" | "baseline";
1277
+ baselineFile?: string;
1278
+ matchedCount?: number; /** Findings present at base but gone at head — resolved by the change. */
1275
1279
  fixedCount: number; /** Total findings at base (over the same files), for context. */
1276
1280
  baseTotalCount: number; /** Pre-existing findings matched after moving to a different file. */
1277
1281
  crossFileMatchCount?: number;
@@ -1323,7 +1327,10 @@ interface DiffInfo {
1323
1327
  }
1324
1328
  type JsonReportMode = "full" | "diff" | "staged" | "baseline";
1325
1329
  interface JsonReportBaselineInfo {
1326
- /** Resolved base commit (merge-base) the head was compared against. */
1330
+ source?: "base" | "baseline";
1331
+ baselineFile?: string;
1332
+ matchedCount?: number;
1333
+ /** Git ref or saved report path used for comparison. */
1327
1334
  baseRef: string;
1328
1335
  /** Count of introduced findings (equals `summary.totalDiagnosticCount`). */
1329
1336
  newCount: number;
@@ -1447,6 +1454,7 @@ interface JsonReportV2 extends Omit<JsonReportV1, "schemaVersion" | "baselineDeg
1447
1454
  }
1448
1455
  interface JsonReportV3 extends Omit<JsonReportV1, "schemaVersion" | "projects" | "diagnostics"> {
1449
1456
  schemaVersion: 3;
1457
+ sourceRevision?: string;
1450
1458
  baseline?: JsonReportBaselineInfo;
1451
1459
  projects: JsonReportProjectEntryV3[];
1452
1460
  diagnostics: JsonReportDiagnosticV3[];
@@ -10920,6 +10928,7 @@ interface BuildJsonReportErrorInput {
10920
10928
  declare const buildJsonReportError: (input: BuildJsonReportErrorInput) => JsonReport; //#endregion
10921
10929
  //#region src/build-json-report.d.ts
10922
10930
  interface BuildJsonReportInput {
10931
+ sourceRevision?: string;
10923
10932
  version: string;
10924
10933
  directory: string;
10925
10934
  mode: JsonReportMode;
@@ -10935,11 +10944,7 @@ interface BuildJsonReportInput {
10935
10944
  * introduced findings only. Emits a `schemaVersion: 3` report with the
10936
10945
  * delta totals and `mode: "baseline"`.
10937
10946
  */
10938
- baseline?: {
10939
- baseRef: string;
10940
- fixedCount: number;
10941
- baseTotalCount: number;
10942
- };
10947
+ baseline?: InspectResult["baselineDelta"];
10943
10948
  /**
10944
10949
  * True when a `changed` run was intended but its baseline delta couldn't be
10945
10950
  * computed (no merge base — usually a shallow CI checkout — or a failed
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]="1ddac246-1e0a-5a02-a193-6a2c2645e7ae")}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]="7e9d79da-4d8f-5537-8aff-436f2fb3d131")}catch(e){}}();
3
3
  import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
4
4
  import { createRequire } from "node:module";
5
5
  import * as fs$1$2 from "node:fs";
@@ -25235,6 +25235,7 @@ var Diagnostic = class extends Class("Diagnostic")({
25235
25235
  endLine: optional(Number$1),
25236
25236
  endColumn: optional(Number$1),
25237
25237
  category: String$1,
25238
+ fingerprint: optional(String$1),
25238
25239
  matchByOccurrence: optional(Boolean$1),
25239
25240
  fileContext: optional(Literals(["test", "story"])),
25240
25241
  suppressionHint: optional(String$1),
@@ -25260,6 +25261,7 @@ var JsonReportDiagnosticV3 = class extends Class("JsonReportDiagnosticV3")({
25260
25261
  endLine: optional(Number$1),
25261
25262
  endColumn: optional(Number$1),
25262
25263
  category: String$1,
25264
+ fingerprint: optional(String$1),
25263
25265
  matchByOccurrence: optional(Boolean$1),
25264
25266
  fileContext: optional(Literals(["test", "story"])),
25265
25267
  suppressionHint: optional(String$1),
@@ -25373,6 +25375,9 @@ var JsonReportV1 = class extends Class("JsonReportV1")({
25373
25375
  }) {};
25374
25376
  var JsonReportBaseline = class extends Class("JsonReportBaseline")({
25375
25377
  baseRef: String$1,
25378
+ source: optional(Literals(["base", "baseline"])),
25379
+ baselineFile: optional(String$1),
25380
+ matchedCount: optional(Number$1),
25376
25381
  newCount: Number$1,
25377
25382
  fixedCount: Number$1,
25378
25383
  baseTotalCount: Number$1
@@ -25402,6 +25407,7 @@ var JsonReportV2 = class extends Class("JsonReportV2")({
25402
25407
  }) {};
25403
25408
  var JsonReportV3 = class extends Class("JsonReportV3")({
25404
25409
  schemaVersion: Literal(3),
25410
+ sourceRevision: optional(String$1),
25405
25411
  version: String$1,
25406
25412
  ok: Boolean$1,
25407
25413
  directory: String$1,
@@ -73219,12 +73225,22 @@ const parseGithubViewerPermission = (stdout) => {
73219
73225
  const splitNullSeparated = (value) => value.split("\0").filter((entry) => entry.length > 0);
73220
73226
  const parseBaselineDiffPlan = (value) => {
73221
73227
  const entries = splitNullSeparated(value);
73228
+ const renamedFiles = {};
73222
73229
  const baseFiles = /* @__PURE__ */ new Set();
73223
73230
  const headFiles = /* @__PURE__ */ new Set();
73224
73231
  for (let entryIndex = 0; entryIndex < entries.length; entryIndex += 2) {
73225
73232
  const status = entries[entryIndex];
73226
73233
  const filePath = entries[entryIndex + 1];
73227
- if (status === void 0 || filePath === void 0 || status.length !== 1) return null;
73234
+ if (status === void 0 || filePath === void 0) return null;
73235
+ if (/^R\d+$/.test(status)) {
73236
+ const headPath = entries[entryIndex + 2];
73237
+ if (headPath === void 0) return null;
73238
+ baseFiles.add(filePath);
73239
+ headFiles.add(headPath);
73240
+ renamedFiles[filePath] = headPath;
73241
+ entryIndex += 1;
73242
+ continue;
73243
+ }
73228
73244
  if (status === "A") {
73229
73245
  headFiles.add(filePath);
73230
73246
  continue;
@@ -73243,7 +73259,8 @@ const parseBaselineDiffPlan = (value) => {
73243
73259
  return {
73244
73260
  baseFiles: [...baseFiles],
73245
73261
  headFiles: [...headFiles],
73246
- untrackedFiles: []
73262
+ untrackedFiles: [],
73263
+ ...Object.keys(renamedFiles).length > 0 ? { renamedFiles } : {}
73247
73264
  };
73248
73265
  };
73249
73266
  const UNTRACKED_FILE_LAST_LINE = Number.MAX_SAFE_INTEGER;
@@ -73474,7 +73491,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
73474
73491
  "diff",
73475
73492
  "--no-ext-diff",
73476
73493
  "--no-textconv",
73477
- "--no-renames",
73494
+ "--find-renames",
73478
73495
  "-z",
73479
73496
  "--name-status",
73480
73497
  "--relative",
@@ -73491,6 +73508,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
73491
73508
  ]);
73492
73509
  if (untracked.status !== 0) return null;
73493
73510
  return {
73511
+ ...plan,
73494
73512
  baseFiles: plan.baseFiles,
73495
73513
  headFiles: plan.headFiles,
73496
73514
  untrackedFiles: splitNullSeparated(untracked.stdout)
@@ -78230,9 +78248,10 @@ const runInspect = (input, hooks = {}) => gen(function* () {
78230
78248
  return filteredDiagnostic === null ? none() : some(filteredDiagnostic);
78231
78249
  })));
78232
78250
  const applyPerElementPipeline = (rawStream) => filterPerElementPipeline(rawStream).pipe(tap((diagnostic) => reporterService.emit(diagnostic)));
78251
+ const pnpmHardeningSeverity = resolveRuleSeverityOverride({ ruleKey: "react-doctor/require-pnpm-hardening" }, buildRuleSeverityControls(resolvedConfig.config));
78233
78252
  const envCollected = yield* runCollect(applyPerElementPipeline(fromIterable$1(isDiffMode ? [] : [
78234
78253
  ...checkReducedMotion(scanDirectory),
78235
- ...checkPnpmHardening(scanDirectory),
78254
+ ...pnpmHardeningSeverity === "warn" || pnpmHardeningSeverity === "error" ? checkPnpmHardening(scanDirectory) : [],
78236
78255
  ...checkReactServerComponentsAdvisory(scanDirectory, project, invocationCaches?.workspaceProbes ?? null),
78237
78256
  ...checkExpoProject(scanDirectory, project),
78238
78257
  ...checkReactNativeProject(scanDirectory, project)
@@ -78852,9 +78871,13 @@ const buildJsonReport = (input) => {
78852
78871
  };
78853
78872
  return {
78854
78873
  schemaVersion: 3,
78874
+ ...input.sourceRevision ? { sourceRevision: input.sourceRevision } : {},
78855
78875
  mode: input.baseline !== void 0 ? "baseline" : input.baselineDegraded && input.mode === "baseline" ? "diff" : input.mode,
78856
78876
  ...input.baseline ? { baseline: {
78857
78877
  baseRef: input.baseline.baseRef,
78878
+ source: input.baseline.source ?? "base",
78879
+ baselineFile: input.baseline.baselineFile,
78880
+ matchedCount: input.baseline.matchedCount ?? input.baseline.baseTotalCount - input.baseline.fixedCount,
78858
78881
  newCount: summary.totalDiagnosticCount,
78859
78882
  fixedCount: input.baseline.fixedCount,
78860
78883
  baseTotalCount: input.baseline.baseTotalCount
@@ -79289,4 +79312,4 @@ const toJsonReport = (result, options) => buildJsonReport({
79289
79312
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
79290
79313
 
79291
79314
  //# sourceMappingURL=index.js.map
79292
- //# debugId=1ddac246-1e0a-5a02-a193-6a2c2645e7ae
79315
+ //# debugId=7e9d79da-4d8f-5537-8aff-436f2fb3d131