react-doctor 0.9.3-dev.0b673cc → 0.9.3-dev.4e4740d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +125 -71
- package/dist/lsp.js +6 -3
- package/dist/run-scan-app-DtYeufgr.js +2195 -0
- package/package.json +4 -3
- package/dist/run-scan-app-DHRvqfkX.js +0 -1733
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
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]="e4075e6f-4128-5af6-bc97-656272450282")}catch(e){}}();
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import * as NodeChildProcess from "node:child_process";
|
|
5
5
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
@@ -78911,7 +78911,7 @@ const BASELINE_FILES_TEMP_DIR_PREFIX = "react-doctor-baseline-";
|
|
|
78911
78911
|
const SCAN_RESULT_CACHE_FILENAME = "scan-cache.json";
|
|
78912
78912
|
const RUN_GIT_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
|
|
78913
78913
|
const GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS = 5e3;
|
|
78914
|
-
const TUI_REPORT_COMPACT_MAX_ROWS =
|
|
78914
|
+
const TUI_REPORT_COMPACT_MAX_ROWS = 23;
|
|
78915
78915
|
const TUI_REPORT_DETAIL_WIDTH_FRACTION = .6;
|
|
78916
78916
|
const CI_TRUST_COMPANIES = "PayPal, Rippling, and Alibaba";
|
|
78917
78917
|
const WELCOME_EXPLANATION_HOLD_MS = 1e3;
|
|
@@ -78962,9 +78962,12 @@ const METRIC = {
|
|
|
78962
78962
|
lspScanCompleted: "lsp.scan.completed",
|
|
78963
78963
|
lspScanDuration: "lsp.scan.duration",
|
|
78964
78964
|
lspScanDiagnostics: "lsp.scan.diagnostics",
|
|
78965
|
-
tuiActionMenuOpened: "tui.action_menu_opened",
|
|
78966
78965
|
tuiCompactReportShown: "tui.compact_report_shown",
|
|
78967
78966
|
tuiFindingNavigated: "tui.finding_navigated",
|
|
78967
|
+
tuiIssueStreamShown: "tui.issue_stream_shown",
|
|
78968
|
+
tuiProjectPathContextShown: "tui.project_path_context_shown",
|
|
78969
|
+
tuiReportActionSelected: "tui.report_action_selected",
|
|
78970
|
+
tuiCancelled: "tui.cancelled",
|
|
78968
78971
|
tuiStackedReportCapped: "tui.stacked_report_capped",
|
|
78969
78972
|
aiTrainingWarningShown: "ai.training.warning_shown",
|
|
78970
78973
|
jsonOutUsed: "json.out_used"
|
|
@@ -79010,7 +79013,7 @@ const makeNoopConsole = () => ({
|
|
|
79010
79013
|
});
|
|
79011
79014
|
//#endregion
|
|
79012
79015
|
//#region src/cli/utils/version.ts
|
|
79013
|
-
const VERSION = "0.9.3-dev.
|
|
79016
|
+
const VERSION = "0.9.3-dev.4e4740d";
|
|
79014
79017
|
//#endregion
|
|
79015
79018
|
//#region src/cli/utils/json-mode.ts
|
|
79016
79019
|
let context = null;
|
|
@@ -79368,13 +79371,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
79368
79371
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
79369
79372
|
* standard `SENTRY_RELEASE` override.
|
|
79370
79373
|
*/
|
|
79371
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.3-dev.
|
|
79374
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.3-dev.4e4740d`;
|
|
79372
79375
|
/**
|
|
79373
79376
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
79374
79377
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
79375
79378
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
79376
79379
|
*/
|
|
79377
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.3-dev.
|
|
79380
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.3-dev.4e4740d") ? "development" : "production");
|
|
79378
79381
|
/**
|
|
79379
79382
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
79380
79383
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -92535,6 +92538,14 @@ const buildNoScoreMessage = (isScoreDisabled, disabledMessage) => {
|
|
|
92535
92538
|
return `${isScoreDisabled ? disabledMessage ?? "Score disabled by --no-score." : "Score unavailable (could not reach the score API)."} ${ENTERPRISE_CONTACT_HINT}`;
|
|
92536
92539
|
};
|
|
92537
92540
|
//#endregion
|
|
92541
|
+
//#region src/cli/utils/build-empty-report-message.ts
|
|
92542
|
+
const buildEmptyReportMessage = (input) => {
|
|
92543
|
+
const categoryFilters = [...input.categoryFilters];
|
|
92544
|
+
if (categoryFilters.length > 0) return `No issues found in category ${categoryFilters.join(", ")}!`;
|
|
92545
|
+
if (input.demotedDiagnosticCount > 0) return `No issues found! (${input.demotedDiagnosticCount} demoted from the ${input.outputSurface} surface — see config.surfaces.)`;
|
|
92546
|
+
return "No issues found!";
|
|
92547
|
+
};
|
|
92548
|
+
//#endregion
|
|
92538
92549
|
//#region src/cli/utils/render-agent-guidance.ts
|
|
92539
92550
|
const AGENT_GUIDANCE_LINES = [
|
|
92540
92551
|
"Treat React Doctor diagnostics as starting hypotheses. Read the relevant code before confirming or suppressing each finding.",
|
|
@@ -93495,6 +93506,26 @@ const printNoScoreHeader = (noScoreMessage) => gen(function* () {
|
|
|
93495
93506
|
yield* log("");
|
|
93496
93507
|
});
|
|
93497
93508
|
//#endregion
|
|
93509
|
+
//#region src/cli/utils/build-footer-description-lines.ts
|
|
93510
|
+
const FOOTER_DESCRIPTION_INDENT = " ";
|
|
93511
|
+
const buildFooterDescriptionLines = (description) => {
|
|
93512
|
+
return wrapTextToWidth(description, resolveMeasureWidth(2)).map((line) => highlighter.dim(`${FOOTER_DESCRIPTION_INDENT}${line}`));
|
|
93513
|
+
};
|
|
93514
|
+
//#endregion
|
|
93515
|
+
//#region src/cli/utils/build-footer-link-lines.ts
|
|
93516
|
+
const buildFooterLinkLines = ({ shareUrl }) => [
|
|
93517
|
+
...shareUrl === null ? [] : [
|
|
93518
|
+
` ${highlighter.bold("Share:")} ${highlighter.info(shareUrl)}`,
|
|
93519
|
+
...buildFooterDescriptionLines("Tell others how you did on socials"),
|
|
93520
|
+
""
|
|
93521
|
+
],
|
|
93522
|
+
` ${highlighter.bold("Docs:")} ${highlighter.info(DOCS_URL)}`,
|
|
93523
|
+
...buildFooterDescriptionLines("Learn more about fixing issues, setting up CI/CD, and configuring rules with a config file"),
|
|
93524
|
+
"",
|
|
93525
|
+
` ${highlighter.bold("GitHub:")} ${highlighter.info(CANONICAL_GITHUB_URL)}`,
|
|
93526
|
+
...buildFooterDescriptionLines("Report issues and star the repository!")
|
|
93527
|
+
];
|
|
93528
|
+
//#endregion
|
|
93498
93529
|
//#region src/cli/utils/write-diagnostics-directory.ts
|
|
93499
93530
|
const ruleDumpFileName = (ruleKey) => ruleKey.replace(/\//g, "--") + ".txt";
|
|
93500
93531
|
const readPreviousRuleDumpFileNames = (directory) => {
|
|
@@ -93515,11 +93546,6 @@ const writeDiagnosticsDirectory = (diagnostics, outputDirectory) => {
|
|
|
93515
93546
|
};
|
|
93516
93547
|
//#endregion
|
|
93517
93548
|
//#region src/cli/utils/render-summary.ts
|
|
93518
|
-
const FOOTER_DESCRIPTION_INDENT = " ";
|
|
93519
|
-
const printFooterDescription = (description) => gen(function* () {
|
|
93520
|
-
const wrapWidth = resolveMeasureWidth(2);
|
|
93521
|
-
for (const line of wrapTextToWidth(description, wrapWidth)) yield* log(highlighter.dim(`${FOOTER_DESCRIPTION_INDENT}${line}`));
|
|
93522
|
-
});
|
|
93523
93549
|
const buildShareUrl = (diagnostics, scoreResult, projectName) => {
|
|
93524
93550
|
const errorCount = diagnostics.filter((diagnostic) => diagnostic.severity === "error").length;
|
|
93525
93551
|
const warningCount = diagnostics.filter((diagnostic) => diagnostic.severity === "warning").length;
|
|
@@ -93536,17 +93562,8 @@ const printFooter = (input) => gen(function* () {
|
|
|
93536
93562
|
yield* log("");
|
|
93537
93563
|
yield* log(buildSectionDivider());
|
|
93538
93564
|
yield* log("");
|
|
93539
|
-
|
|
93540
|
-
|
|
93541
|
-
yield* log(` ${highlighter.bold("Share:")} ${highlighter.info(shareUrl)}`);
|
|
93542
|
-
yield* printFooterDescription("Tell others how you did on socials");
|
|
93543
|
-
yield* log("");
|
|
93544
|
-
}
|
|
93545
|
-
yield* log(` ${highlighter.bold("Docs:")} ${highlighter.info(DOCS_URL)}`);
|
|
93546
|
-
yield* printFooterDescription("Learn more about fixing issues, setting up CI/CD, and configuring rules with a config file");
|
|
93547
|
-
yield* log("");
|
|
93548
|
-
yield* log(` ${highlighter.bold("GitHub:")} ${highlighter.info(CANONICAL_GITHUB_URL)}`);
|
|
93549
|
-
yield* printFooterDescription("Report issues and star the repository!");
|
|
93565
|
+
const shareUrl = input.isOffline ? null : buildShareUrl(input.diagnostics, input.scoreResult, input.projectName);
|
|
93566
|
+
for (const line of buildFooterLinkLines({ shareUrl })) yield* log(line);
|
|
93550
93567
|
});
|
|
93551
93568
|
const printDiagnosticsDump = (diagnostics, outputDirectory, verbose, stream = "stdout") => gen(function* () {
|
|
93552
93569
|
const writtenDirectory = yield* try_({
|
|
@@ -93655,7 +93672,6 @@ const recordOnboardingCompletion = (options) => {
|
|
|
93655
93672
|
isNonInteractiveEnvironment: options.isNonInteractiveEnvironment
|
|
93656
93673
|
})) markOnboardingComplete();
|
|
93657
93674
|
};
|
|
93658
|
-
const formatCategorySelection = (categoryFilters) => [...categoryFilters].join(", ");
|
|
93659
93675
|
const buildChangedLineMatcher = (directory, changedLineRanges) => {
|
|
93660
93676
|
const rangesByFile = /* @__PURE__ */ new Map();
|
|
93661
93677
|
for (const entry of changedLineRanges) rangesByFile.set(toForwardSlashes(entry.file), entry.ranges);
|
|
@@ -94183,9 +94199,11 @@ const finalizeAndRender = (input) => gen(function* () {
|
|
|
94183
94199
|
if (hasSkippedChecks) {
|
|
94184
94200
|
const skippedLabel = skippedChecks.join(" and ");
|
|
94185
94201
|
yield* warn$1(highlighter.warn(`No issues detected, but ${skippedLabel} checks failed — results are incomplete.`));
|
|
94186
|
-
} else
|
|
94187
|
-
|
|
94188
|
-
|
|
94202
|
+
} else yield* log(highlighter.success(buildEmptyReportMessage({
|
|
94203
|
+
categoryFilters: options.categoryFilters,
|
|
94204
|
+
demotedDiagnosticCount,
|
|
94205
|
+
outputSurface: options.outputSurface
|
|
94206
|
+
})));
|
|
94189
94207
|
yield* log("");
|
|
94190
94208
|
yield* pause;
|
|
94191
94209
|
if (hasSkippedChecks) {
|
|
@@ -94276,7 +94294,7 @@ const buildHandoffPayload = (input) => {
|
|
|
94276
94294
|
try {
|
|
94277
94295
|
outputDirectory = writeDiagnosticsDirectory([...input.diagnostics], input.outputDirectory);
|
|
94278
94296
|
} catch {}
|
|
94279
|
-
const lines = [`
|
|
94297
|
+
const lines = [`Review and fix the top ${topGroups.length} React Doctor ${topGroups.length === 1 ? "finding" : "findings"} in ${input.projectName}. Leave the rest for a follow-up.`, ""];
|
|
94280
94298
|
topGroups.forEach(([ruleKey, ruleDiagnostics], index) => {
|
|
94281
94299
|
const representative = ruleDiagnostics[0];
|
|
94282
94300
|
const severityLabel = representative.severity === "error" ? "ERROR" : "WARN";
|
|
@@ -94304,7 +94322,7 @@ const buildHandoffPayload = (input) => {
|
|
|
94304
94322
|
const ruleSummaries = deferredMigrationBuckets.map((bucket) => `${bucket.title} (${bucket.fileCount} files)`).join(", ");
|
|
94305
94323
|
lines.push(`Some of the rest are migration-scale (span dozens of files): ${ruleSummaries}. For each, fix a representative sample, confirm the recipe holds, and get the code owner's sign-off before changing the rest in one pass.`, "");
|
|
94306
94324
|
}
|
|
94307
|
-
lines.push("
|
|
94325
|
+
lines.push("Stop after this pass. Summarize the remaining findings for a follow-up.");
|
|
94308
94326
|
return lines.join("\n");
|
|
94309
94327
|
};
|
|
94310
94328
|
//#endregion
|
|
@@ -94514,20 +94532,20 @@ const resolveOpenCommand = (url) => {
|
|
|
94514
94532
|
args: [url]
|
|
94515
94533
|
};
|
|
94516
94534
|
};
|
|
94517
|
-
const openUrl = (url) => {
|
|
94535
|
+
const openUrl = (url) => new Promise((resolve) => {
|
|
94518
94536
|
try {
|
|
94519
94537
|
const { command, args } = resolveOpenCommand(url);
|
|
94520
94538
|
const child = spawn(command, args, {
|
|
94521
94539
|
detached: true,
|
|
94522
94540
|
stdio: "ignore"
|
|
94523
94541
|
});
|
|
94524
|
-
child.
|
|
94542
|
+
child.once("spawn", () => resolve(true));
|
|
94543
|
+
child.once("error", () => resolve(false));
|
|
94525
94544
|
child.unref();
|
|
94526
|
-
return true;
|
|
94527
94545
|
} catch {
|
|
94528
|
-
|
|
94546
|
+
resolve(false);
|
|
94529
94547
|
}
|
|
94530
|
-
};
|
|
94548
|
+
});
|
|
94531
94549
|
//#endregion
|
|
94532
94550
|
//#region src/cli/utils/ask-add-to-github-actions.ts
|
|
94533
94551
|
const CI_YES_CHOICE = "ci-yes";
|
|
@@ -94568,7 +94586,7 @@ const askAddToGitHubActions = async (prompt = prompts) => {
|
|
|
94568
94586
|
if (ciChoice === void 0) return "cancel";
|
|
94569
94587
|
if (ciChoice === CI_YES_CHOICE) return "yes";
|
|
94570
94588
|
if (ciChoice === CI_NO_CHOICE) return "no";
|
|
94571
|
-
const opened = openUrl(GITHUB_ACTIONS_SETUP_URL);
|
|
94589
|
+
const opened = await openUrl(GITHUB_ACTIONS_SETUP_URL);
|
|
94572
94590
|
cliLogger.log(opened ? `Opened ${highlighter.info(GITHUB_ACTIONS_SETUP_URL)} in your browser.` : `Visit ${highlighter.info(GITHUB_ACTIONS_SETUP_URL)} to learn more.`);
|
|
94573
94591
|
cliLogger.break();
|
|
94574
94592
|
}
|
|
@@ -97261,6 +97279,55 @@ const installAction = async (options, command) => {
|
|
|
97261
97279
|
}
|
|
97262
97280
|
};
|
|
97263
97281
|
//#endregion
|
|
97282
|
+
//#region src/cli/utils/should-use-tui.ts
|
|
97283
|
+
const shouldUseTui = (input) => {
|
|
97284
|
+
if (input.isNonInteractiveEnvironment || !input.stdinIsTty || !input.stdoutIsTty || !input.supportsRawMode || input.nodeMajorVersion < 22 || input.terminalName === "dumb") return false;
|
|
97285
|
+
const flags = input.flags;
|
|
97286
|
+
let requiresStableConfiguredScope = false;
|
|
97287
|
+
if (input.userConfig?.scope !== void 0) requiresStableConfiguredScope = input.userConfig.scope !== "full";
|
|
97288
|
+
else if (input.userConfig?.diff !== void 0) requiresStableConfiguredScope = input.userConfig.diff !== false && input.userConfig.diff !== "false";
|
|
97289
|
+
else if (input.userConfig?.base !== void 0) requiresStableConfiguredScope = true;
|
|
97290
|
+
return !(flags.verbose === true || flags.outputDir !== void 0 || flags.score === true || flags.json === true || flags.jsonCompact === true || flags.jsonOut !== void 0 || flags.staged === true || flags.scope !== void 0 || flags.base !== void 0 || flags.includeUntracked === true || flags.diff !== void 0 || flags.changedFilesFrom !== void 0 || flags.debug === true || flags.failOn !== void 0 || requiresStableConfiguredScope);
|
|
97291
|
+
};
|
|
97292
|
+
//#endregion
|
|
97293
|
+
//#region src/cli/commands/scan.ts
|
|
97294
|
+
const runScanCommand = async (input) => {
|
|
97295
|
+
const nodeMajorVersion = Number(process.versions.node.split(".")[0]);
|
|
97296
|
+
const tuiEnvironment = {
|
|
97297
|
+
flags: input.flags,
|
|
97298
|
+
isNonInteractiveEnvironment: isNonInteractiveEnvironment(),
|
|
97299
|
+
nodeMajorVersion,
|
|
97300
|
+
stdinIsTty: process.stdin.isTTY === true,
|
|
97301
|
+
stdoutIsTty: process.stdout.isTTY === true,
|
|
97302
|
+
supportsRawMode: typeof process.stdin.setRawMode === "function",
|
|
97303
|
+
terminalName: process.env.TERM
|
|
97304
|
+
};
|
|
97305
|
+
if (!shouldUseTui(tuiEnvironment)) {
|
|
97306
|
+
await inspectAction(input.directory, input.flags, input.invocationCommand);
|
|
97307
|
+
return;
|
|
97308
|
+
}
|
|
97309
|
+
await runProjectMigrations(path.resolve(input.directory));
|
|
97310
|
+
const scanTarget = await resolveScanTarget(input.directory, { allowAmbiguous: true });
|
|
97311
|
+
if (!shouldUseTui({
|
|
97312
|
+
...tuiEnvironment,
|
|
97313
|
+
userConfig: scanTarget.userConfig
|
|
97314
|
+
})) {
|
|
97315
|
+
await inspectAction(input.directory, input.flags, input.invocationCommand);
|
|
97316
|
+
return;
|
|
97317
|
+
}
|
|
97318
|
+
recordCount(METRIC.cliInvoked, 1, { command: input.invocationCommand });
|
|
97319
|
+
const { runScanApp } = await import("./run-scan-app-DtYeufgr.js");
|
|
97320
|
+
const { shouldFail } = await runScanApp({
|
|
97321
|
+
directory: input.directory,
|
|
97322
|
+
scanTarget,
|
|
97323
|
+
options: resolveCliInspectOptions(input.flags, null),
|
|
97324
|
+
projectFlag: input.flags.project,
|
|
97325
|
+
skipPrompts: input.flags.yes ?? false,
|
|
97326
|
+
blocking: input.flags.blocking
|
|
97327
|
+
});
|
|
97328
|
+
if (shouldFail) process.exitCode = 1;
|
|
97329
|
+
};
|
|
97330
|
+
//#endregion
|
|
97264
97331
|
//#region src/cli/utils/rule-catalog.ts
|
|
97265
97332
|
const buildRuleCatalog = () => REACT_DOCTOR_RULES.map((entry) => ({
|
|
97266
97333
|
key: entry.key,
|
|
@@ -97902,12 +97969,22 @@ const ensureWindowsUtf8Console = () => {
|
|
|
97902
97969
|
};
|
|
97903
97970
|
//#endregion
|
|
97904
97971
|
//#region src/cli/utils/exit-gracefully.ts
|
|
97972
|
+
let didStartExiting = false;
|
|
97905
97973
|
const exitGracefully = () => {
|
|
97974
|
+
if (didStartExiting) return process.exit(130);
|
|
97975
|
+
didStartExiting = true;
|
|
97906
97976
|
try {
|
|
97907
97977
|
if (isJsonModeActive()) writeJsonErrorReport(/* @__PURE__ */ new Error("Scan cancelled by user (SIGINT/SIGTERM)"));
|
|
97908
|
-
else console.log(
|
|
97978
|
+
else console.log([
|
|
97979
|
+
"",
|
|
97980
|
+
"Cancelled.",
|
|
97981
|
+
"",
|
|
97982
|
+
buildSectionDivider(),
|
|
97983
|
+
"",
|
|
97984
|
+
...buildFooterLinkLines({ shareUrl: null })
|
|
97985
|
+
].join("\n"));
|
|
97909
97986
|
} catch {}
|
|
97910
|
-
process.exit(130);
|
|
97987
|
+
flushSentry().finally(() => process.exit(130));
|
|
97911
97988
|
};
|
|
97912
97989
|
//#endregion
|
|
97913
97990
|
//#region src/cli/utils/guard-stdin.ts
|
|
@@ -98316,7 +98393,11 @@ ${highlighter.dim("Learn more:")}
|
|
|
98316
98393
|
`;
|
|
98317
98394
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
98318
98395
|
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("-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>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").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);
|
|
98319
|
-
program.action(
|
|
98396
|
+
program.action((directory = ".", flags) => runScanCommand({
|
|
98397
|
+
directory,
|
|
98398
|
+
flags,
|
|
98399
|
+
invocationCommand: "inspect"
|
|
98400
|
+
}));
|
|
98320
98401
|
program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
|
|
98321
98402
|
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((location, options) => whyAction(location, options));
|
|
98322
98403
|
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(installAction);
|
|
@@ -98337,38 +98418,11 @@ rules.command("category <category> <severity>").description("Set the severity fo
|
|
|
98337
98418
|
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((tag, _options, command) => rulesIgnoreTagAction(tag, command.optsWithGlobals()));
|
|
98338
98419
|
rules.command("unignore-tag <tag>").description("Stop ignoring a tag previously skipped via ignore-tag").option("-c, --cwd <cwd>", "working directory", process.cwd()).action((tag, _options, command) => rulesUnignoreTagAction(tag, command.optsWithGlobals()));
|
|
98339
98420
|
program.command("experimental-lsp", { hidden: false }).description("[experimental] run the React Doctor language server over stdio (for editors)").allowUnknownOption().action(() => {});
|
|
98340
|
-
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("--no-score", "skip the score API, the share URL, and crash reporting").option("-p, --project <names>", "scan specific workspace projects (comma-separated, or *)").option("-y, --yes", "skip the project prompt and scan every discovered project").action(
|
|
98341
|
-
|
|
98342
|
-
|
|
98343
|
-
|
|
98344
|
-
|
|
98345
|
-
const nodeMajorVersion = Number(process.versions.node.split(".")[0]);
|
|
98346
|
-
if (process.stdout.isTTY !== true || process.stdin.isTTY !== true || isNonInteractiveEnvironment() || nodeMajorVersion < 22) {
|
|
98347
|
-
await inspectAction(directory, {
|
|
98348
|
-
deadCode,
|
|
98349
|
-
score: options.score === false ? false : void 0,
|
|
98350
|
-
supplyChain,
|
|
98351
|
-
project: options.project,
|
|
98352
|
-
yes: options.yes,
|
|
98353
|
-
blocking: options.blocking
|
|
98354
|
-
});
|
|
98355
|
-
return;
|
|
98356
|
-
}
|
|
98357
|
-
recordCount(METRIC.cliInvoked, 1, { command: "experimental-tui" });
|
|
98358
|
-
const { runScanApp } = await import("./run-scan-app-DHRvqfkX.js");
|
|
98359
|
-
const { shouldFail } = await runScanApp({
|
|
98360
|
-
directory,
|
|
98361
|
-
options: {
|
|
98362
|
-
deadCode,
|
|
98363
|
-
noScore,
|
|
98364
|
-
supplyChain
|
|
98365
|
-
},
|
|
98366
|
-
projectFlag: options.project,
|
|
98367
|
-
skipPrompts: options.yes ?? false,
|
|
98368
|
-
blocking: options.blocking
|
|
98369
|
-
});
|
|
98370
|
-
if (shouldFail) process.exitCode = 1;
|
|
98371
|
-
});
|
|
98421
|
+
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("-p, --project <names>", "scan specific workspace projects (comma-separated, or *)").option("-y, --yes", "skip the project prompt and scan every discovered project").action((directory = ".", _localOptions, command) => runScanCommand({
|
|
98422
|
+
directory,
|
|
98423
|
+
flags: command.optsWithGlobals(),
|
|
98424
|
+
invocationCommand: "experimental-tui"
|
|
98425
|
+
}));
|
|
98372
98426
|
process.stdout.on("error", (error) => {
|
|
98373
98427
|
if (error.code === "EPIPE") process.exit(0);
|
|
98374
98428
|
});
|
|
@@ -98395,7 +98449,7 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
98395
98449
|
handleError(error, { sentryEventId });
|
|
98396
98450
|
});
|
|
98397
98451
|
//#endregion
|
|
98398
|
-
export {
|
|
98452
|
+
export { highlighter as $, hasLintHardFailure as A, isUnicodeSupported as B, shouldRecordOnboarding as C, buildCodeFrame as D, formatElapsedTime as E, resolveBlockingLevel as F, isCiEnvironment as G, METRIC as H, isReactDoctorWorkflowInstalled as I, Progress as J, DIAGNOSTIC_CATEGORY_BUCKETS as K, recordCount as L, buildSortedRuleGroups as M, formatFixRecipeLine as N, buildEmptyReportMessage as O, formatLearnMoreLine as P, hasPublishedFixRecipe as Q, toForwardSlashes as R, isOnboardingForced as S, computeProjectedScore as T, TUI_REPORT_COMPACT_MAX_ROWS as U, CI_TRUST_COMPANIES as V, TUI_REPORT_DETAIL_WIDTH_FRACTION as W, buildRuleDocsUrl as X, Reporter as Y, getCategoryImpact as Z, printFooter as _, resolveCliInspectOptions as a, void_ as at, markOnboardingComplete as b, setUpGitHubActions as c, CLI_AGENT_BINARIES as d, mapWithConcurrency as et, copyToClipboard as f, createInvocationInspect as g, isShareOptedOut as h, selectProjects as i, sync as it, buildRulePriorityMap as j, buildNoScoreMessage as k, openUrl as l, buildHandoffPayload as m, shouldFailScanGate as n, resolveScanTarget as nt, filterScansForSurface as o, succeed$3 as ot, launchCliAgent as p, GITHUB_ACTIONS_SETUP_URL as q, discoverWorkspacePackages as r, runPromise as rt, countUniqueScannedFiles as s, exitGracefully as t, mergeReactDoctorConfigs as tt, detectLaunchableAgents as u, easeOutCubic as v, filterDiagnosticsByCategories as w, canAnimateOnboarding as x, doctorFace as y, findNearestPackageDirectory as z };
|
|
98399
98453
|
|
|
98400
98454
|
//# sourceMappingURL=cli.js.map
|
|
98401
|
-
//# debugId=
|
|
98455
|
+
//# debugId=e4075e6f-4128-5af6-bc97-656272450282
|
package/dist/lsp.js
CHANGED
|
@@ -76795,9 +76795,12 @@ const METRIC = {
|
|
|
76795
76795
|
lspScanCompleted: "lsp.scan.completed",
|
|
76796
76796
|
lspScanDuration: "lsp.scan.duration",
|
|
76797
76797
|
lspScanDiagnostics: "lsp.scan.diagnostics",
|
|
76798
|
-
tuiActionMenuOpened: "tui.action_menu_opened",
|
|
76799
76798
|
tuiCompactReportShown: "tui.compact_report_shown",
|
|
76800
76799
|
tuiFindingNavigated: "tui.finding_navigated",
|
|
76800
|
+
tuiIssueStreamShown: "tui.issue_stream_shown",
|
|
76801
|
+
tuiProjectPathContextShown: "tui.project_path_context_shown",
|
|
76802
|
+
tuiReportActionSelected: "tui.report_action_selected",
|
|
76803
|
+
tuiCancelled: "tui.cancelled",
|
|
76801
76804
|
tuiStackedReportCapped: "tui.stacked_report_capped",
|
|
76802
76805
|
aiTrainingWarningShown: "ai.training.warning_shown",
|
|
76803
76806
|
jsonOutUsed: "json.out_used"
|
|
@@ -77100,5 +77103,5 @@ const startLanguageServer = () => {
|
|
|
77100
77103
|
};
|
|
77101
77104
|
//#endregion
|
|
77102
77105
|
export { startLanguageServer };
|
|
77103
|
-
!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]="
|
|
77104
|
-
//# debugId=
|
|
77106
|
+
!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]="84561d6a-3814-52df-a86e-cf40018cdc87")}catch(e){}}();
|
|
77107
|
+
//# debugId=84561d6a-3814-52df-a86e-cf40018cdc87
|