react-doctor 0.5.8-dev.ba2af1b → 0.5.8-dev.bd0f465
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 +51 -17
- package/dist/lsp.js +4 -3
- package/package.json +4 -4
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]="fabe3e34-b40f-514e-a5af-fa68a36365ae")}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";
|
|
@@ -45059,7 +45059,8 @@ const METRIC = {
|
|
|
45059
45059
|
lspScanCompleted: "lsp.scan.completed",
|
|
45060
45060
|
lspScanDuration: "lsp.scan.duration",
|
|
45061
45061
|
lspScanDiagnostics: "lsp.scan.diagnostics",
|
|
45062
|
-
aiTrainingWarningShown: "ai.training.warning_shown"
|
|
45062
|
+
aiTrainingWarningShown: "ai.training.warning_shown",
|
|
45063
|
+
jsonOutUsed: "json.out_used"
|
|
45063
45064
|
};
|
|
45064
45065
|
//#endregion
|
|
45065
45066
|
//#region src/cli/utils/noop-console.ts
|
|
@@ -45102,7 +45103,7 @@ const makeNoopConsole = () => ({
|
|
|
45102
45103
|
});
|
|
45103
45104
|
//#endregion
|
|
45104
45105
|
//#region src/cli/utils/version.ts
|
|
45105
|
-
const VERSION = "0.5.8-dev.
|
|
45106
|
+
const VERSION = "0.5.8-dev.bd0f465";
|
|
45106
45107
|
//#endregion
|
|
45107
45108
|
//#region src/cli/utils/json-mode.ts
|
|
45108
45109
|
let context = null;
|
|
@@ -45140,12 +45141,13 @@ const installSilentConsole = () => {
|
|
|
45140
45141
|
"trace"
|
|
45141
45142
|
]) target[key] = source[key];
|
|
45142
45143
|
};
|
|
45143
|
-
const enableJsonMode = ({ compact, directory }) => {
|
|
45144
|
+
const enableJsonMode = ({ compact, directory, outputFile }) => {
|
|
45144
45145
|
context = {
|
|
45145
45146
|
compact,
|
|
45146
45147
|
directory,
|
|
45147
45148
|
startTime: performance$1.now(),
|
|
45148
|
-
mode: "full"
|
|
45149
|
+
mode: "full",
|
|
45150
|
+
outputFile: outputFile ?? null
|
|
45149
45151
|
};
|
|
45150
45152
|
installSilentConsole();
|
|
45151
45153
|
};
|
|
@@ -45158,7 +45160,11 @@ const setJsonReportMode = (mode) => {
|
|
|
45158
45160
|
};
|
|
45159
45161
|
const writeJsonReport = (report) => {
|
|
45160
45162
|
const serialized = context?.compact ? JSON.stringify(report) : JSON.stringify(report, null, 2);
|
|
45161
|
-
|
|
45163
|
+
if (context?.outputFile) {
|
|
45164
|
+
const resolvedPath = Path.resolve(context.outputFile);
|
|
45165
|
+
NFS.mkdirSync(Path.dirname(resolvedPath), { recursive: true });
|
|
45166
|
+
NFS.writeFileSync(resolvedPath, `${serialized}\n`);
|
|
45167
|
+
} else process.stdout.write(`${serialized}\n`);
|
|
45162
45168
|
};
|
|
45163
45169
|
const writeJsonErrorReport = (error, sentryEventId) => {
|
|
45164
45170
|
if (!context) return;
|
|
@@ -45466,13 +45472,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
45466
45472
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
45467
45473
|
* standard `SENTRY_RELEASE` override.
|
|
45468
45474
|
*/
|
|
45469
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.5.8-dev.
|
|
45475
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.5.8-dev.bd0f465`;
|
|
45470
45476
|
/**
|
|
45471
45477
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
45472
45478
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
45473
45479
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
45474
45480
|
*/
|
|
45475
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.5.8-dev.
|
|
45481
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.5.8-dev.bd0f465") ? "development" : "production");
|
|
45476
45482
|
/**
|
|
45477
45483
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
45478
45484
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -53252,6 +53258,26 @@ const CLI_AGENT_AUTO_FLAGS = {
|
|
|
53252
53258
|
codex: ["--yolo"],
|
|
53253
53259
|
cursor: ["--force"]
|
|
53254
53260
|
};
|
|
53261
|
+
const resolveCursorBundledNode = () => {
|
|
53262
|
+
if (!isWindows) return null;
|
|
53263
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
53264
|
+
if (!localAppData) return null;
|
|
53265
|
+
const cursorAgentRoot = Path.join(localAppData, "cursor-agent", "versions");
|
|
53266
|
+
try {
|
|
53267
|
+
const versions = NFS.readdirSync(cursorAgentRoot);
|
|
53268
|
+
if (versions.length === 0) return null;
|
|
53269
|
+
const sortedVersions = versions.sort((a, b) => b.localeCompare(a, void 0, { numeric: true }));
|
|
53270
|
+
for (const version of sortedVersions) try {
|
|
53271
|
+
const bundledNodePath = Path.join(cursorAgentRoot, version, "node.exe");
|
|
53272
|
+
const entryScriptPath = Path.join(cursorAgentRoot, version, "index.js");
|
|
53273
|
+
if (NFS.statSync(bundledNodePath).isFile() && NFS.statSync(entryScriptPath).isFile()) return {
|
|
53274
|
+
command: bundledNodePath,
|
|
53275
|
+
args: [entryScriptPath]
|
|
53276
|
+
};
|
|
53277
|
+
} catch {}
|
|
53278
|
+
} catch {}
|
|
53279
|
+
return null;
|
|
53280
|
+
};
|
|
53255
53281
|
const resolveWindowsCmdEntryScript = (command) => {
|
|
53256
53282
|
if (!isWindows) return null;
|
|
53257
53283
|
const pathDirectories = (process.env.PATH ?? "").split(Path.delimiter).filter(Boolean);
|
|
@@ -53271,11 +53297,10 @@ const resolveWindowsCmdEntryScript = (command) => {
|
|
|
53271
53297
|
}
|
|
53272
53298
|
return null;
|
|
53273
53299
|
};
|
|
53274
|
-
const spawnAgent = (command, args, cwd
|
|
53300
|
+
const spawnAgent = (command, args, cwd) => new Promise((resolve, reject) => {
|
|
53275
53301
|
const child = spawn(command, [...args], {
|
|
53276
53302
|
cwd,
|
|
53277
|
-
stdio: "inherit"
|
|
53278
|
-
shell
|
|
53303
|
+
stdio: "inherit"
|
|
53279
53304
|
});
|
|
53280
53305
|
child.on("error", reject);
|
|
53281
53306
|
child.on("close", (code) => resolve(code ?? 0));
|
|
@@ -53284,6 +53309,10 @@ const launchCliAgent = async (agentId, prompt, cwd) => {
|
|
|
53284
53309
|
const binary = CLI_AGENT_BINARIES[agentId];
|
|
53285
53310
|
const agentArgs = [...CLI_AGENT_AUTO_FLAGS[agentId], prompt];
|
|
53286
53311
|
if (isWindows) {
|
|
53312
|
+
if (agentId === "cursor") {
|
|
53313
|
+
const cursorResolution = resolveCursorBundledNode();
|
|
53314
|
+
if (cursorResolution) return spawnAgent(cursorResolution.command, [...cursorResolution.args, ...agentArgs], cwd);
|
|
53315
|
+
}
|
|
53287
53316
|
const entryScript = resolveWindowsCmdEntryScript(binary);
|
|
53288
53317
|
if (entryScript) return spawnAgent(process.execPath, [entryScript, ...agentArgs], cwd);
|
|
53289
53318
|
}
|
|
@@ -54396,10 +54425,14 @@ const inspectAction = async (directory, flags) => {
|
|
|
54396
54425
|
const isQuiet = isScoreOnly || isJsonMode;
|
|
54397
54426
|
const requestedDirectory = Path.resolve(directory);
|
|
54398
54427
|
const startTime = performance$1.now();
|
|
54399
|
-
if (isJsonMode)
|
|
54400
|
-
|
|
54401
|
-
|
|
54402
|
-
|
|
54428
|
+
if (isJsonMode) {
|
|
54429
|
+
enableJsonMode({
|
|
54430
|
+
compact: Boolean(flags.jsonCompact),
|
|
54431
|
+
directory: requestedDirectory,
|
|
54432
|
+
outputFile: flags.jsonOut
|
|
54433
|
+
});
|
|
54434
|
+
if (flags.jsonOut) recordCount(METRIC.jsonOutUsed, 1);
|
|
54435
|
+
}
|
|
54403
54436
|
recordCount(METRIC.cliInvoked, 1, { command: "inspect" });
|
|
54404
54437
|
try {
|
|
54405
54438
|
validateModeFlags(flags);
|
|
@@ -55479,6 +55512,7 @@ const ROOT_FLAG_SPEC = {
|
|
|
55479
55512
|
"--category",
|
|
55480
55513
|
"--changed-files-from",
|
|
55481
55514
|
"--blocking",
|
|
55515
|
+
"--json-out",
|
|
55482
55516
|
"--output-dir",
|
|
55483
55517
|
"--fail-on",
|
|
55484
55518
|
"--project",
|
|
@@ -55669,7 +55703,7 @@ ${highlighter.dim("Learn more:")}
|
|
|
55669
55703
|
${highlighter.info(CANONICAL_GITHUB_URL)}
|
|
55670
55704
|
`;
|
|
55671
55705
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
55672
|
-
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("--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("-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 to scan/report: full (default), files, changed (only new issues vs base), or lines (only changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").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").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);
|
|
55706
|
+
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("--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 to scan/report: full (default), files, changed (only new issues vs base), or lines (only changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").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").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);
|
|
55673
55707
|
program.action(inspectAction);
|
|
55674
55708
|
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));
|
|
55675
55709
|
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);
|
|
@@ -55712,4 +55746,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
55712
55746
|
export {};
|
|
55713
55747
|
|
|
55714
55748
|
//# sourceMappingURL=cli.js.map
|
|
55715
|
-
//# debugId=
|
|
55749
|
+
//# debugId=fabe3e34-b40f-514e-a5af-fa68a36365ae
|
package/dist/lsp.js
CHANGED
|
@@ -43047,7 +43047,8 @@ const METRIC = {
|
|
|
43047
43047
|
lspScanCompleted: "lsp.scan.completed",
|
|
43048
43048
|
lspScanDuration: "lsp.scan.duration",
|
|
43049
43049
|
lspScanDiagnostics: "lsp.scan.diagnostics",
|
|
43050
|
-
aiTrainingWarningShown: "ai.training.warning_shown"
|
|
43050
|
+
aiTrainingWarningShown: "ai.training.warning_shown",
|
|
43051
|
+
jsonOutUsed: "json.out_used"
|
|
43051
43052
|
};
|
|
43052
43053
|
//#endregion
|
|
43053
43054
|
//#region src/cli/utils/to-category-key.ts
|
|
@@ -43364,5 +43365,5 @@ const startLanguageServer = () => {
|
|
|
43364
43365
|
};
|
|
43365
43366
|
//#endregion
|
|
43366
43367
|
export { startLanguageServer };
|
|
43367
|
-
!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]="
|
|
43368
|
-
//# debugId=
|
|
43368
|
+
!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]="c5b6c740-461d-5f65-a993-9e6d35ad9113")}catch(e){}}();
|
|
43369
|
+
//# debugId=c5b6c740-461d-5f65-a993-9e6d35ad9113
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.5.8-dev.
|
|
3
|
+
"version": "0.5.8-dev.bd0f465",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
"magicast": "^0.5.3",
|
|
61
61
|
"oxlint": ">=1.66.0 <1.67.0",
|
|
62
62
|
"prompts": "^2.4.2",
|
|
63
|
-
"typescript": ">=5.0.4 <
|
|
63
|
+
"typescript": ">=5.0.4 <6",
|
|
64
64
|
"vscode-languageserver": "^9.0.1",
|
|
65
65
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
66
66
|
"vscode-uri": "^3.1.0",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
67
|
+
"oxlint-plugin-react-doctor": "0.5.8-dev.bd0f465",
|
|
68
|
+
"deslop-js": "0.5.8"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/babel__code-frame": "^7.27.0",
|