react-doctor 0.9.12 → 0.9.13-dev.fd23edc
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/README.md +34 -1
- package/bin/react-doctor.js +1 -9
- package/dist/active-run-trace-dlIZeEvb.js +18 -0
- package/dist/active-scan-abort-registry-DwG6tSPy.js +28 -0
- package/dist/{build-section-divider-BsQvH-7I.js → build-section-divider-CUtO-gXD.js} +10 -25
- package/dist/{ci-B4x4RjKD.js → ci-DjilJaw4.js} +13 -12
- package/dist/cli.js +121 -41
- package/dist/{design-A48PNCf_.js → design-CXLKbARh.js} +4 -4
- package/dist/{devtools-DPRVRu3S.js → devtools-CC2PAZ85.js} +4 -4
- package/dist/{exit-gracefully-Bk531kS-.js → exit-gracefully-DTLgxZZ5.js} +15 -9
- package/dist/get-east-asian-width-Bv2TD3Xj.js +444 -0
- package/dist/{report-error-Pb2uO8EG.js → handle-error-BqaqFvmc.js} +18 -68
- package/dist/index.d.ts +53 -42
- package/dist/index.js +55119 -54689
- package/dist/{inspect-CwH84aSA.js → inspect-BIfnzKGq.js} +44 -33
- package/dist/{install-doctor-script-DLayXS7q.js → install-doctor-script-B1U08lUD.js} +7 -449
- package/dist/{install-github-workflow-Goz-KFqb.js → install-github-workflow-CkOl0wCn.js} +10 -6
- package/dist/{install-sFN_w425.js → install-nhJ65X-y.js} +9 -8
- package/dist/{install-react-doctor-Bq7dfEBI.js → install-react-doctor-Dm35Egex.js} +47 -45
- package/dist/{run-scan-app-DXBMW54J.js → jsx-runtime-C1t3eR6p.js} +281 -2759
- package/dist/path-format-DnHpmJwG.js +9 -0
- package/dist/{print-branded-header-D_J8Qdsj.js → print-branded-header-qOJiGkuW.js} +4 -4
- package/dist/project-analysis-worker.d.ts +1 -0
- package/dist/project-analysis-worker.js +51901 -0
- package/dist/prompt-runtime-scan-url-m88LMtMP.js +240 -0
- package/dist/{read-object-file-Hk79zI91.js → read-object-file-Cv41FpZo.js} +4 -4
- package/dist/{record-metric-CsQXJewH.js → record-metric-u8youmM2.js} +3257 -6019
- package/dist/report-error-CkFgxJTQ.js +64 -0
- package/dist/{report-workflow-result-6n_wSqzA.js → report-workflow-result-Wh1SQuOu.js} +5 -5
- package/dist/{resolve-scope-DP6rYlNO.js → resolve-scope-CHCpJtks.js} +8 -10
- package/dist/{rules-BnIZ4Fq_.js → rules-C30QFptP.js} +6 -6
- package/dist/run-scan-app-yTBDucJ3.js +2511 -0
- package/dist/runtime-scan/browser-probe.iife.js +855 -0
- package/dist/runtime-scan-VH25Yf8H.js +770 -0
- package/dist/sanitize-runtime-url-crVHbQlW.js +76 -0
- package/dist/scan-CNSRWEtJ.js +47 -0
- package/dist/semver-DFtnEmN-.js +3219 -0
- package/dist/{should-fail-scan-gate-DzZuTxim.js → should-fail-scan-gate-Cw6KeoRT.js} +160 -184
- package/dist/{should-skip-prompts-D1GWG2qN.js → should-skip-prompts-B5zkkkKR.js} +4 -4
- package/dist/should-use-tui-S9255AG_.js +25 -0
- package/dist/skills/improve-threejs/SKILL.md +102 -0
- package/dist/skills/performance/SKILL.md +113 -0
- package/dist/skills/react-doctor/SKILL.md +6 -0
- package/dist/{unref-stdin-0a_0uwC6.js → telemetry-runtime-B2rpGWMl.js} +57 -33
- package/dist/unref-stdin-SK3WfwxS.js +12 -0
- package/dist/{version-Bo5QDp7F.js → version-KQbGQSGN.js} +4 -4
- package/dist/{why-BFYbtnm8.js → why-B-l2qTCV.js} +4 -4
- package/dist/with-run-span-Dk1M8cnH.js +110 -0
- package/package.json +9 -10
- package/dist/chunk-q7NCDQ7-.js +0 -28
- package/dist/lsp.js +0 -81145
- package/dist/scan-CnnXz78m.js +0 -53
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
Your agent writes bad React, this catches it.
|
|
11
11
|
|
|
12
|
-
React Doctor deterministically scans your codebase and finds issues across state
|
|
12
|
+
React Doctor deterministically scans your codebase and finds issues across state and effects, performance, architecture, security, accessibility, and maintainability. It highlights overly complex React functions and repeated JSX trees that are good candidates for composition.
|
|
13
13
|
|
|
14
14
|
Works across React frameworks and React-enabled sites - Next.js, Vite, Astro, TanStack, React Native, Expo, you name it.
|
|
15
15
|
|
|
@@ -25,6 +25,12 @@ Run this at your project root to get an audit.
|
|
|
25
25
|
npx react-doctor@latest
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
Pass file paths to scan only the files that another CI step selected.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx react-doctor@latest src/a.tsx src/b.tsx
|
|
32
|
+
```
|
|
33
|
+
|
|
28
34
|
https://github.com/user-attachments/assets/07cc88d9-9589-44c3-aa73-5d603cb1c570
|
|
29
35
|
|
|
30
36
|
### 2. Install for agents
|
|
@@ -55,6 +61,33 @@ You can configure which rules to run and how to run them in `doctor.config.ts`.
|
|
|
55
61
|
|
|
56
62
|
[Learn more →](https://react.doctor/docs/configuration/config-files)
|
|
57
63
|
|
|
64
|
+
## Runtime performance traces
|
|
65
|
+
|
|
66
|
+
Record a Chrome DevTools performance trace while you interact with a running React app:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx react-doctor@latest scan http://localhost:3000
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
React Doctor opens system Chrome in a temporary isolated profile, records until you press Enter
|
|
73
|
+
(up to five minutes), and flashes purple outlines with component names as React renders. It then
|
|
74
|
+
returns a readable summary plus the path to a compressed DevTools trace. Use `--format json` or
|
|
75
|
+
`--format jsonl` for coding agents. In an interactive terminal, you can run `react-doctor scan`
|
|
76
|
+
without a URL and choose a detected localhost app or enter another URL; coding agents and CI must
|
|
77
|
+
pass the URL explicitly.
|
|
78
|
+
|
|
79
|
+
An already-open normal browser is left alone. To reuse an authenticated session, start a dedicated
|
|
80
|
+
Chrome profile with remote debugging, sign in, close its non-blank tabs, and pass its endpoint:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npx react-doctor@latest scan https://app.example.com --cdp http://127.0.0.1:9222
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Chrome performance tracing is browser-wide, so React Doctor rejects attached profiles with open
|
|
87
|
+
pages. It closes blank startup tabs before tracing and closes its scan tab afterward; the attached
|
|
88
|
+
browser stays open. The trace is stored locally and is never uploaded, but it can contain page
|
|
89
|
+
URLs, source paths, and React profiling details. Treat it as sensitive application data.
|
|
90
|
+
|
|
58
91
|
## Telemetry
|
|
59
92
|
|
|
60
93
|
The CLI reports crashes, basic run traces, and anonymous usage counters to [Sentry](https://sentry.io/) to help us fix bugs and prioritize work.
|
package/bin/react-doctor.js
CHANGED
|
@@ -10,12 +10,4 @@ if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
// commander / prompts / ora layer, which would touch process.stdin before the
|
|
15
|
-
// LSP connection attaches and break the stdio transport.
|
|
16
|
-
if (process.argv[2] === "experimental-lsp") {
|
|
17
|
-
const { startLanguageServer } = await import("../dist/lsp.js");
|
|
18
|
-
startLanguageServer();
|
|
19
|
-
} else {
|
|
20
|
-
await import("../dist/cli.js");
|
|
21
|
-
}
|
|
13
|
+
await import("../dist/cli.js");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/cli/utils/active-run-trace.ts
|
|
2
|
+
|
|
3
|
+
!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]="38d6312b-a431-5dea-8088-ac88f4110ce8")}catch(e){}}();
|
|
4
|
+
let activeRunTrace = null;
|
|
5
|
+
const setActiveRunTrace = (trace) => {
|
|
6
|
+
activeRunTrace = trace;
|
|
7
|
+
};
|
|
8
|
+
const getActiveRunTrace = () => activeRunTrace;
|
|
9
|
+
let lastRunTraceId = null;
|
|
10
|
+
const recordRunTraceId = (traceId) => {
|
|
11
|
+
lastRunTraceId = traceId;
|
|
12
|
+
};
|
|
13
|
+
const getLastRunTraceId = () => lastRunTraceId;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { setActiveRunTrace as i, getLastRunTraceId as n, recordRunTraceId as r, getActiveRunTrace as t };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=active-run-trace-dlIZeEvb.js.map
|
|
18
|
+
//# debugId=38d6312b-a431-5dea-8088-ac88f4110ce8
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/cli/utils/active-scan-abort-registry.ts
|
|
2
|
+
|
|
3
|
+
!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]="464e40c7-b98a-555d-a847-5ddb886227d3")}catch(e){}}();
|
|
4
|
+
const activeScanAbortControllers = /* @__PURE__ */ new Set();
|
|
5
|
+
const activeScanCleanups = /* @__PURE__ */ new Set();
|
|
6
|
+
const activeScanAbortRegistry = {
|
|
7
|
+
register: (controller) => {
|
|
8
|
+
activeScanAbortControllers.add(controller);
|
|
9
|
+
return () => activeScanAbortControllers.delete(controller);
|
|
10
|
+
},
|
|
11
|
+
registerCleanup: (cleanup) => {
|
|
12
|
+
activeScanCleanups.add(cleanup);
|
|
13
|
+
return () => activeScanCleanups.delete(cleanup);
|
|
14
|
+
},
|
|
15
|
+
abortAll: async () => {
|
|
16
|
+
const controllers = [...activeScanAbortControllers];
|
|
17
|
+
const cleanups = [...activeScanCleanups];
|
|
18
|
+
activeScanAbortControllers.clear();
|
|
19
|
+
activeScanCleanups.clear();
|
|
20
|
+
for (const controller of controllers) controller.abort();
|
|
21
|
+
await Promise.allSettled(cleanups.map((cleanup) => cleanup()));
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { activeScanAbortRegistry as t };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=active-scan-abort-registry-DwG6tSPy.js.map
|
|
28
|
+
//# debugId=464e40c7-b98a-555d-a847-5ddb886227d3
|
|
@@ -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]="
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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]="f28abf16-b5f6-5ee6-80c5-3907f87623f4")}catch(e){}}();
|
|
3
|
+
import { Kt as highlighter, N as SENTRY_FLUSH_TIMEOUT_MS, a as isEnvFlagEnabled, er as CANONICAL_GITHUB_URL, ft as anonymizeInPlace, hn as scrubSensitivePaths, i as isTelemetryEnabled, o as buildSentryScope, or as DOCS_URL, pt as anonymizeText } from "./record-metric-u8youmM2.js";
|
|
4
|
+
import { r as isExpectedUserError } from "./telemetry-runtime-B2rpGWMl.js";
|
|
5
5
|
import * as Sentry from "@sentry/node";
|
|
6
6
|
//#region src/cli/utils/scrub-sentry-event.ts
|
|
7
7
|
/**
|
|
@@ -55,9 +55,8 @@ const scrubSentryEvent = (event) => {
|
|
|
55
55
|
/**
|
|
56
56
|
* Shared Sentry configuration resolution — release, environment, and tracing
|
|
57
57
|
* sample rate — derived from `VERSION` and the standard `SENTRY_*` env
|
|
58
|
-
* overrides. Lives apart from `instrument.ts`
|
|
59
|
-
*
|
|
60
|
-
* release/environment values without the LSP pulling in CLI run-context code.
|
|
58
|
+
* overrides. Lives apart from `instrument.ts` so this resolution remains
|
|
59
|
+
* independently testable.
|
|
61
60
|
*/
|
|
62
61
|
/**
|
|
63
62
|
* A version is a "dev" build when it's the unbuilt placeholder (`0.0.0`) or
|
|
@@ -71,13 +70,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
71
70
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
72
71
|
* standard `SENTRY_RELEASE` override.
|
|
73
72
|
*/
|
|
74
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.
|
|
73
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.13-dev.fd23edc`;
|
|
75
74
|
/**
|
|
76
75
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
77
76
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
78
77
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
79
78
|
*/
|
|
80
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.
|
|
79
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.13-dev.fd23edc") ? "development" : "production");
|
|
81
80
|
//#endregion
|
|
82
81
|
//#region src/instrument.ts
|
|
83
82
|
let isInitialized = false;
|
|
@@ -138,20 +137,6 @@ const initializeSentry = () => {
|
|
|
138
137
|
} catch {}
|
|
139
138
|
};
|
|
140
139
|
//#endregion
|
|
141
|
-
//#region src/cli/utils/active-scan-abort-registry.ts
|
|
142
|
-
const activeScanAbortControllers = /* @__PURE__ */ new Set();
|
|
143
|
-
const activeScanAbortRegistry = {
|
|
144
|
-
register: (controller) => {
|
|
145
|
-
activeScanAbortControllers.add(controller);
|
|
146
|
-
return () => activeScanAbortControllers.delete(controller);
|
|
147
|
-
},
|
|
148
|
-
abortAll: () => {
|
|
149
|
-
const controllers = [...activeScanAbortControllers];
|
|
150
|
-
activeScanAbortControllers.clear();
|
|
151
|
-
for (const controller of controllers) controller.abort();
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
//#endregion
|
|
155
140
|
//#region src/cli/utils/resolve-measure-width.ts
|
|
156
141
|
const resolveClampedWidth = (input) => {
|
|
157
142
|
const terminalColumns = process.stdout.columns;
|
|
@@ -225,7 +210,7 @@ const buildFooterLinkLines = ({ shareUrl }) => [
|
|
|
225
210
|
const DIVIDER_INDENT = " ";
|
|
226
211
|
const buildSectionDivider = () => highlighter.dim(`${DIVIDER_INDENT}${"─".repeat(resolveMeasureWidth(2))}`);
|
|
227
212
|
//#endregion
|
|
228
|
-
export { initializeSentry as
|
|
213
|
+
export { initializeSentry as i, buildFooterLinkLines as n, flushSentry as r, buildSectionDivider as t };
|
|
229
214
|
|
|
230
|
-
//# sourceMappingURL=build-section-divider-
|
|
231
|
-
//# debugId=
|
|
215
|
+
//# sourceMappingURL=build-section-divider-CUtO-gXD.js.map
|
|
216
|
+
//# debugId=f28abf16-b5f6-5ee6-80c5-3907f87623f4
|
|
@@ -1,14 +1,15 @@
|
|
|
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]="
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { a as
|
|
10
|
-
import {
|
|
11
|
-
import { t as
|
|
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]="0f7a77a6-3dc2-5bb5-8f07-66b722efa99c")}catch(e){}}();
|
|
3
|
+
import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
|
|
4
|
+
import { Kt as highlighter, T as METRIC, cr as GITHUB_ACTIONS_SETUP_URL, t as recordCount, tr as CI_URL, zn as runSync } from "./record-metric-u8youmM2.js";
|
|
5
|
+
import { r as isExpectedUserError } from "./telemetry-runtime-B2rpGWMl.js";
|
|
6
|
+
import { n as handleUserError, t as handleError } from "./handle-error-BqaqFvmc.js";
|
|
7
|
+
import { t as reportErrorToSentry } from "./report-error-CkFgxJTQ.js";
|
|
8
|
+
import { M as cliLogger, c as spinner, n as findNearestPackageDirectory } from "./install-doctor-script-B1U08lUD.js";
|
|
9
|
+
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-CkOl0wCn.js";
|
|
10
|
+
import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, n as isScopeValue } from "./resolve-scope-CHCpJtks.js";
|
|
11
|
+
import { t as shouldSkipPrompts } from "./should-skip-prompts-B5zkkkKR.js";
|
|
12
|
+
import { t as printBrandedHeader } from "./print-branded-header-qOJiGkuW.js";
|
|
12
13
|
import * as path$1 from "node:path";
|
|
13
14
|
import * as fs$1 from "node:fs";
|
|
14
15
|
//#region src/cli/utils/ci/ci-provider.ts
|
|
@@ -7497,5 +7498,5 @@ const ciConfigAction = (options) => runCiCommand("config", runCiConfig, options)
|
|
|
7497
7498
|
//#endregion
|
|
7498
7499
|
export { ciConfigAction, ciInstallAction, ciUpgradeAction };
|
|
7499
7500
|
|
|
7500
|
-
//# sourceMappingURL=ci-
|
|
7501
|
-
//# debugId=
|
|
7501
|
+
//# sourceMappingURL=ci-DjilJaw4.js.map
|
|
7502
|
+
//# debugId=0f7a77a6-3dc2-5bb5-8f07-66b722efa99c
|
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { t as exitGracefully } from "./exit-gracefully-
|
|
8
|
-
import { n as
|
|
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]="2db05473-003e-52a5-853a-90e4f4f5ac96")}catch(e){}}();
|
|
3
|
+
import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
|
|
4
|
+
import { H as isDebugFlagEnabled, Jt as isPathInsideDirectory, Kt as highlighter, Nt as filterSourceFiles, _ as VERSION, d as isJsonModeActive, er as CANONICAL_GITHUB_URL, gn as setColorEnabled, h as writeJsonErrorReport, i as isTelemetryEnabled, tr as CI_URL, xr as isFile, yr as isDirectory, z as CliInputError } from "./record-metric-u8youmM2.js";
|
|
5
|
+
import { n as shutdownTelemetry, r as isExpectedUserError } from "./telemetry-runtime-B2rpGWMl.js";
|
|
6
|
+
import { i as initializeSentry, r as flushSentry } from "./build-section-divider-CUtO-gXD.js";
|
|
7
|
+
import { t as exitGracefully } from "./exit-gracefully-DTLgxZZ5.js";
|
|
8
|
+
import { n as handleUserError, t as handleError } from "./handle-error-BqaqFvmc.js";
|
|
9
|
+
import { n as getLastRunTraceId } from "./active-run-trace-dlIZeEvb.js";
|
|
10
|
+
import { t as reportErrorToSentry } from "./report-error-CkFgxJTQ.js";
|
|
11
|
+
import { t as toForwardSlashes } from "./path-format-DnHpmJwG.js";
|
|
12
|
+
import { t as unrefStdin } from "./unref-stdin-SK3WfwxS.js";
|
|
9
13
|
import { execFileSync } from "node:child_process";
|
|
14
|
+
import * as path$1 from "node:path";
|
|
10
15
|
//#region ../../node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/error.js
|
|
11
16
|
var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
12
17
|
/**
|
|
@@ -1023,7 +1028,7 @@ var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
1023
1028
|
var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1024
1029
|
const EventEmitter = __require("node:events").EventEmitter;
|
|
1025
1030
|
const childProcess = __require("node:child_process");
|
|
1026
|
-
const path = __require("node:path");
|
|
1031
|
+
const path$2 = __require("node:path");
|
|
1027
1032
|
const fs = __require("node:fs");
|
|
1028
1033
|
const process$1 = __require("node:process");
|
|
1029
1034
|
const { Argument, humanReadableArgName } = require_argument();
|
|
@@ -1943,9 +1948,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1943
1948
|
".cjs"
|
|
1944
1949
|
];
|
|
1945
1950
|
function findFile(baseDir, baseName) {
|
|
1946
|
-
const localBin = path.resolve(baseDir, baseName);
|
|
1951
|
+
const localBin = path$2.resolve(baseDir, baseName);
|
|
1947
1952
|
if (fs.existsSync(localBin)) return localBin;
|
|
1948
|
-
if (sourceExt.includes(path.extname(baseName))) return void 0;
|
|
1953
|
+
if (sourceExt.includes(path$2.extname(baseName))) return void 0;
|
|
1949
1954
|
const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
|
|
1950
1955
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1951
1956
|
}
|
|
@@ -1960,17 +1965,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1960
1965
|
} catch {
|
|
1961
1966
|
resolvedScriptPath = this._scriptPath;
|
|
1962
1967
|
}
|
|
1963
|
-
executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
|
|
1968
|
+
executableDir = path$2.resolve(path$2.dirname(resolvedScriptPath), executableDir);
|
|
1964
1969
|
}
|
|
1965
1970
|
if (executableDir) {
|
|
1966
1971
|
let localFile = findFile(executableDir, executableFile);
|
|
1967
1972
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1968
|
-
const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
|
|
1973
|
+
const legacyName = path$2.basename(this._scriptPath, path$2.extname(this._scriptPath));
|
|
1969
1974
|
if (legacyName !== this._name) localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
1970
1975
|
}
|
|
1971
1976
|
executableFile = localFile || executableFile;
|
|
1972
1977
|
}
|
|
1973
|
-
launchWithNode = sourceExt.includes(path.extname(executableFile));
|
|
1978
|
+
launchWithNode = sourceExt.includes(path$2.extname(executableFile));
|
|
1974
1979
|
let proc;
|
|
1975
1980
|
if (process$1.platform !== "win32") if (launchWithNode) {
|
|
1976
1981
|
args.unshift(executableFile);
|
|
@@ -2738,7 +2743,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2738
2743
|
* @return {Command}
|
|
2739
2744
|
*/
|
|
2740
2745
|
nameFromFilename(filename) {
|
|
2741
|
-
this._name = path.basename(filename, path.extname(filename));
|
|
2746
|
+
this._name = path$2.basename(filename, path$2.extname(filename));
|
|
2742
2747
|
return this;
|
|
2743
2748
|
}
|
|
2744
2749
|
/**
|
|
@@ -3170,6 +3175,31 @@ const assertNoRemovedFlags = (argv) => {
|
|
|
3170
3175
|
}
|
|
3171
3176
|
};
|
|
3172
3177
|
//#endregion
|
|
3178
|
+
//#region src/cli/utils/resolve-positional-scan-input.ts
|
|
3179
|
+
const resolvePositionalScanInput = (positionalPaths, currentDirectory = process.cwd()) => {
|
|
3180
|
+
const absoluteCurrentDirectory = path$1.resolve(currentDirectory);
|
|
3181
|
+
if (positionalPaths.length === 0) return {
|
|
3182
|
+
directory: absoluteCurrentDirectory,
|
|
3183
|
+
filePaths: void 0
|
|
3184
|
+
};
|
|
3185
|
+
const onlyAbsolutePath = path$1.resolve(absoluteCurrentDirectory, positionalPaths[0]);
|
|
3186
|
+
if (positionalPaths.length === 1 && (isDirectory(onlyAbsolutePath) || !isFile(onlyAbsolutePath) && filterSourceFiles([positionalPaths[0]]).length === 0)) return {
|
|
3187
|
+
directory: positionalPaths[0],
|
|
3188
|
+
filePaths: void 0
|
|
3189
|
+
};
|
|
3190
|
+
const uniqueFilePaths = /* @__PURE__ */ new Set();
|
|
3191
|
+
for (const positionalPath of positionalPaths) {
|
|
3192
|
+
const absolutePath = path$1.resolve(absoluteCurrentDirectory, positionalPath);
|
|
3193
|
+
if (isDirectory(absolutePath)) throw new CliInputError(`Cannot combine the directory "${positionalPath}" with file path arguments. Pass one directory or only file paths.`);
|
|
3194
|
+
if (!isPathInsideDirectory(absolutePath, absoluteCurrentDirectory)) throw new CliInputError(`The file path "${positionalPath}" is outside the current directory. Run React Doctor from a common project root.`);
|
|
3195
|
+
uniqueFilePaths.add(toForwardSlashes(path$1.relative(absoluteCurrentDirectory, absolutePath)));
|
|
3196
|
+
}
|
|
3197
|
+
return {
|
|
3198
|
+
directory: absoluteCurrentDirectory,
|
|
3199
|
+
filePaths: [...uniqueFilePaths]
|
|
3200
|
+
};
|
|
3201
|
+
};
|
|
3202
|
+
//#endregion
|
|
3173
3203
|
//#region src/cli/utils/strip-unknown-cli-flags.ts
|
|
3174
3204
|
const ROOT_FLAG_SPEC = {
|
|
3175
3205
|
longOptionsWithoutValues: new Set([
|
|
@@ -3291,6 +3321,24 @@ const COMMAND_FLAG_SPECS = new Map([
|
|
|
3291
3321
|
shortOptionsWithoutValues: new Set(["-h", "-y"]),
|
|
3292
3322
|
shortOptionsWithRequiredValues: new Set(["-c"])
|
|
3293
3323
|
}],
|
|
3324
|
+
["scan", {
|
|
3325
|
+
longOptionsWithoutValues: new Set([
|
|
3326
|
+
"--color",
|
|
3327
|
+
"--debug",
|
|
3328
|
+
"--help",
|
|
3329
|
+
"--no-color",
|
|
3330
|
+
"--no-score",
|
|
3331
|
+
"--no-telemetry"
|
|
3332
|
+
]),
|
|
3333
|
+
longOptionsWithRequiredValues: new Set([
|
|
3334
|
+
"--cdp",
|
|
3335
|
+
"--format",
|
|
3336
|
+
"--trace-out"
|
|
3337
|
+
]),
|
|
3338
|
+
longOptionsWithOptionalValues: /* @__PURE__ */ new Set(),
|
|
3339
|
+
shortOptionsWithoutValues: new Set(["-h"]),
|
|
3340
|
+
shortOptionsWithRequiredValues: new Set(["-f"])
|
|
3341
|
+
}],
|
|
3294
3342
|
["why", {
|
|
3295
3343
|
longOptionsWithoutValues: new Set([
|
|
3296
3344
|
"--color",
|
|
@@ -3408,6 +3456,8 @@ ${highlighter.dim("Examples:")}
|
|
|
3408
3456
|
${formatExampleLines([
|
|
3409
3457
|
["react-doctor", "scan the current project"],
|
|
3410
3458
|
["react-doctor ./apps/web", "scan a specific directory"],
|
|
3459
|
+
["react-doctor src/a.tsx src/b.tsx", "scan only selected files"],
|
|
3460
|
+
["react-doctor scan http://localhost:3000", "profile one interaction in a running React app"],
|
|
3411
3461
|
["react-doctor --scope changed --base main", "scan only new issues vs. main"],
|
|
3412
3462
|
["react-doctor --project modules/a,modules/b", "score each module separately (names or paths)"],
|
|
3413
3463
|
["react-doctor --staged", "scan staged files (pre-commit hook)"],
|
|
@@ -3456,10 +3506,36 @@ ${formatExampleLines([
|
|
|
3456
3506
|
|
|
3457
3507
|
${highlighter.dim("Scope:")}
|
|
3458
3508
|
Runs every rule tagged ${highlighter.info("design")}; all design rules stay opt-in during a general health scan.
|
|
3459
|
-
|
|
3509
|
+
Whole-project maintainability, supply-chain, external lint-config, custom-plugin, and health-score passes are skipped.
|
|
3460
3510
|
Standard scan flags such as ${highlighter.info("--scope")}, ${highlighter.info("--project")}, ${highlighter.info("--verbose")}, and ${highlighter.info("--json")} still work.
|
|
3461
3511
|
`;
|
|
3462
|
-
const
|
|
3512
|
+
const renderRuntimeScanHelpEpilog = () => `
|
|
3513
|
+
${highlighter.dim("Examples:")}
|
|
3514
|
+
${formatExampleLines([
|
|
3515
|
+
["react-doctor scan", "choose a detected local app or enter its URL"],
|
|
3516
|
+
["react-doctor scan http://localhost:3000", "scan one interaction in isolated Chrome"],
|
|
3517
|
+
["react-doctor scan http://localhost:3000 --format json", "print a structured report for an agent"],
|
|
3518
|
+
["react-doctor scan http://localhost:3000 --trace-out ./trace.json.gz", "choose where the private trace is saved"],
|
|
3519
|
+
["react-doctor scan https://app.example.com --cdp http://127.0.0.1:9222", "reuse a dedicated debug-enabled Chrome profile"]
|
|
3520
|
+
])}
|
|
3521
|
+
|
|
3522
|
+
${highlighter.dim("How scanning works:")}
|
|
3523
|
+
1. Start the app. Prefer a production build for representative timings.
|
|
3524
|
+
2. Run this command. If you omit the URL, React Doctor suggests running localhost apps.
|
|
3525
|
+
3. Reproduce one slow interaction within five minutes. Purple labels show component renders.
|
|
3526
|
+
4. Return here and press Enter. React Doctor prints the report and trace path.
|
|
3527
|
+
|
|
3528
|
+
${highlighter.dim("Authenticated apps:")}
|
|
3529
|
+
The default temporary profile starts signed out. Start a separate Chrome profile with remote
|
|
3530
|
+
debugging, sign in there, close its non-blank tabs, then pass ${highlighter.info("--cdp <url>")}.
|
|
3531
|
+
React Doctor closes blank startup tabs and its scan tab. The attached browser stays open.
|
|
3532
|
+
|
|
3533
|
+
${highlighter.dim("Output and privacy:")}
|
|
3534
|
+
${highlighter.info("text")} summarizes the evidence for people. ${highlighter.info("json")} returns one report; ${highlighter.info("jsonl")} returns one record per line.
|
|
3535
|
+
Chrome tracing is browser-wide, so ${highlighter.info("--cdp")} rejects profiles with open pages. The compressed
|
|
3536
|
+
${highlighter.info(".json.gz")} trace stays local and can contain page URLs, source paths, and profiling data.
|
|
3537
|
+
`;
|
|
3538
|
+
const MAX_DURATION_OPTION_DESCRIPTION = "scan time budget for the whole run, shared across workspace projects: past it, queued projects, remaining lint batches, and maintainability analysis are skipped and partial results are reported (skipped files and projects are listed in the JSON report)";
|
|
3463
3539
|
const renderCiHelpEpilog = () => `
|
|
3464
3540
|
${highlighter.dim("Examples:")}
|
|
3465
3541
|
${formatExampleLines([
|
|
@@ -3479,82 +3555,85 @@ ${highlighter.dim("Learn more:")}
|
|
|
3479
3555
|
${highlighter.info(CI_URL)}
|
|
3480
3556
|
`;
|
|
3481
3557
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
3482
|
-
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[
|
|
3483
|
-
program.action(async (
|
|
3484
|
-
const { runScanCommand } = await import("./scan-
|
|
3558
|
+
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);
|
|
3559
|
+
program.action(async (positionalPaths = [], flags) => {
|
|
3560
|
+
const { runScanCommand } = await import("./scan-CNSRWEtJ.js");
|
|
3485
3561
|
return runScanCommand({
|
|
3486
|
-
|
|
3562
|
+
...resolvePositionalScanInput(positionalPaths),
|
|
3487
3563
|
flags,
|
|
3488
3564
|
invocationCommand: "inspect"
|
|
3489
3565
|
});
|
|
3490
3566
|
});
|
|
3491
3567
|
program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action(async (directory, _options, command) => {
|
|
3492
|
-
const { designAction } = await import("./design-
|
|
3568
|
+
const { designAction } = await import("./design-CXLKbARh.js");
|
|
3493
3569
|
return designAction(directory ?? ".", command.optsWithGlobals());
|
|
3494
3570
|
});
|
|
3571
|
+
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) => {
|
|
3572
|
+
const { runtimeScanAction } = await import("./runtime-scan-VH25Yf8H.js");
|
|
3573
|
+
return runtimeScanAction(url, options);
|
|
3574
|
+
});
|
|
3495
3575
|
program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async (location, options) => {
|
|
3496
|
-
const { whyAction } = await import("./why-
|
|
3576
|
+
const { whyAction } = await import("./why-B-l2qTCV.js");
|
|
3497
3577
|
return whyAction(location, options);
|
|
3498
3578
|
});
|
|
3499
|
-
program.command("install").alias("setup").description("Install the react-doctor skill into your coding agents and optional git hook").option("-y, --yes", "skip prompts, install for all detected agents").option("--dry-run", "show what would be installed without writing files").option("--agent-hooks", "install
|
|
3500
|
-
const { installAction } = await import("./install-
|
|
3579
|
+
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) => {
|
|
3580
|
+
const { installAction } = await import("./install-nhJ65X-y.js");
|
|
3501
3581
|
return installAction(options, command);
|
|
3502
3582
|
});
|
|
3503
3583
|
const providerOption = ["--provider <name>", "ci provider: github-actions or gitlab-ci (auto-detected by default)"];
|
|
3504
3584
|
const prOption = ["--pr", "open a pull request with the change instead of writing it to the working tree"];
|
|
3505
3585
|
const ci = program.command("ci").description("Set up, upgrade, and configure React Doctor in your CI");
|
|
3506
3586
|
ci.command("install").description("Add a CI workflow that scans every pull request").option(...providerOption).option(...prOption).option("--blocking <level>", "gate level: none (advisory, default), warning, or error").option("--scope <value>", "what a pull-request scan reports: changed (default), files, lines, full").option("--comment", "post a summary comment on each pull request").option("--no-comment", "don't post a summary comment").option("--review-comments", "add inline review comments on changed lines").option("--no-review-comments", "don't add inline review comments").option("--commit-status", "report a commit status with the health score").option("--no-commit-status", "don't report a commit status").option("-y, --yes", "skip prompts; use the defaults").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderCiHelpEpilog).action(async (_options, command) => {
|
|
3507
|
-
const { ciInstallAction } = await import("./ci-
|
|
3587
|
+
const { ciInstallAction } = await import("./ci-DjilJaw4.js");
|
|
3508
3588
|
return ciInstallAction(command.optsWithGlobals());
|
|
3509
3589
|
});
|
|
3510
3590
|
ci.command("config").description("Change the gate, scan scope, and pull-request reporting").option(...providerOption).option("--blocking <level>", "gate level: none (advisory), warning, or error").option("--scope <value>", "what a pull-request scan reports: changed, files, lines, or full").option("--comment", "post a summary comment on each pull request").option("--no-comment", "don't post a summary comment").option("--review-comments", "add inline review comments on changed lines").option("--no-review-comments", "don't add inline review comments").option("--commit-status", "report a commit status with the health score").option("--no-commit-status", "don't report a commit status").option("-y, --yes", "skip prompts; print the current settings").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async (_options, command) => {
|
|
3511
|
-
const { ciConfigAction } = await import("./ci-
|
|
3591
|
+
const { ciConfigAction } = await import("./ci-DjilJaw4.js");
|
|
3512
3592
|
return ciConfigAction(command.optsWithGlobals());
|
|
3513
3593
|
});
|
|
3514
3594
|
ci.command("upgrade").description("Upgrade the CI workflow to the action's current major").option(...providerOption).option(...prOption).option("-y, --yes", "skip prompts").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async (_options, command) => {
|
|
3515
|
-
const { ciUpgradeAction } = await import("./ci-
|
|
3595
|
+
const { ciUpgradeAction } = await import("./ci-DjilJaw4.js");
|
|
3516
3596
|
return ciUpgradeAction(command.optsWithGlobals());
|
|
3517
3597
|
});
|
|
3518
3598
|
program.command("version").description("show the version with Node and platform info").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action(async () => {
|
|
3519
|
-
const { versionAction } = await import("./version-
|
|
3599
|
+
const { versionAction } = await import("./version-KQbGQSGN.js");
|
|
3520
3600
|
return versionAction();
|
|
3521
3601
|
});
|
|
3522
3602
|
const rules = program.command("rules").description("List, explain, and configure which React Doctor rules run");
|
|
3523
3603
|
rules.command("list").description("List rules and the severity they run at under your config").option("--category <name>", "only show rules in a category (e.g. Performance)").option("--tag <name>", "only show rules with a tag (e.g. design, test-noise)").option("--framework <name>", "only show rules for a framework (e.g. global, nextjs)").option("--configured", "only show rules your config has changed from the default").option("--json", "output a structured JSON array").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (_options, command) => {
|
|
3524
|
-
const { rulesListAction } = await import("./rules-
|
|
3604
|
+
const { rulesListAction } = await import("./rules-C30QFptP.js");
|
|
3525
3605
|
return rulesListAction(command.optsWithGlobals());
|
|
3526
3606
|
});
|
|
3527
3607
|
rules.command("explain <rule>").description("Explain why a rule matters, its current severity, and how to configure it").option("--json", "output a structured JSON object").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, _options, command) => {
|
|
3528
|
-
const { rulesExplainAction } = await import("./rules-
|
|
3608
|
+
const { rulesExplainAction } = await import("./rules-C30QFptP.js");
|
|
3529
3609
|
return rulesExplainAction(rule, command.optsWithGlobals());
|
|
3530
3610
|
});
|
|
3531
3611
|
rules.command("set <rule> <severity>").description("Set a rule's severity: off, warn, or error").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, severity, _options, command) => {
|
|
3532
|
-
const { rulesSetAction } = await import("./rules-
|
|
3612
|
+
const { rulesSetAction } = await import("./rules-C30QFptP.js");
|
|
3533
3613
|
return rulesSetAction(rule, severity, command.optsWithGlobals());
|
|
3534
3614
|
});
|
|
3535
3615
|
rules.command("enable <rule>").description("Enable a rule at its recommended severity (or pass --severity)").option("--severity <level>", "severity to enable at: warn or error").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, _options, command) => {
|
|
3536
|
-
const { rulesEnableAction } = await import("./rules-
|
|
3616
|
+
const { rulesEnableAction } = await import("./rules-C30QFptP.js");
|
|
3537
3617
|
return rulesEnableAction(rule, command.optsWithGlobals());
|
|
3538
3618
|
});
|
|
3539
3619
|
rules.command("disable <rule>").description("Disable a rule so it never runs").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (rule, _options, command) => {
|
|
3540
|
-
const { rulesDisableAction } = await import("./rules-
|
|
3620
|
+
const { rulesDisableAction } = await import("./rules-C30QFptP.js");
|
|
3541
3621
|
return rulesDisableAction(rule, command.optsWithGlobals());
|
|
3542
3622
|
});
|
|
3543
3623
|
rules.command("category <category> <severity>").description("Set the severity for a whole category (off, warn, error)").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (category, severity, _options, command) => {
|
|
3544
|
-
const { rulesCategoryAction } = await import("./rules-
|
|
3624
|
+
const { rulesCategoryAction } = await import("./rules-C30QFptP.js");
|
|
3545
3625
|
return rulesCategoryAction(category, severity, command.optsWithGlobals());
|
|
3546
3626
|
});
|
|
3547
3627
|
rules.command("ignore-tag <tag>").description("Skip a whole rule family by tag before linting (e.g. design)").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (tag, _options, command) => {
|
|
3548
|
-
const { rulesIgnoreTagAction } = await import("./rules-
|
|
3628
|
+
const { rulesIgnoreTagAction } = await import("./rules-C30QFptP.js");
|
|
3549
3629
|
return rulesIgnoreTagAction(tag, command.optsWithGlobals());
|
|
3550
3630
|
});
|
|
3551
3631
|
rules.command("unignore-tag <tag>").description("Stop ignoring a tag previously skipped via ignore-tag").option("-c, --cwd <cwd>", "working directory", process.cwd()).action(async (tag, _options, command) => {
|
|
3552
|
-
const { rulesUnignoreTagAction } = await import("./rules-
|
|
3632
|
+
const { rulesUnignoreTagAction } = await import("./rules-C30QFptP.js");
|
|
3553
3633
|
return rulesUnignoreTagAction(tag, command.optsWithGlobals());
|
|
3554
3634
|
});
|
|
3555
|
-
program.command("experimental-
|
|
3556
|
-
|
|
3557
|
-
const { runScanCommand } = await import("./scan-CnnXz78m.js");
|
|
3635
|
+
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) => {
|
|
3636
|
+
const { runScanCommand } = await import("./scan-CNSRWEtJ.js");
|
|
3558
3637
|
return runScanCommand({
|
|
3559
3638
|
directory,
|
|
3560
3639
|
flags: command.optsWithGlobals(),
|
|
@@ -3584,7 +3663,8 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
3584
3663
|
process.exit(1);
|
|
3585
3664
|
}
|
|
3586
3665
|
if (isUserError) {
|
|
3587
|
-
handleUserError(error);
|
|
3666
|
+
handleUserError(error, { shouldExit: false });
|
|
3667
|
+
await Promise.all([flushSentry(), shutdownTelemetry()]);
|
|
3588
3668
|
return;
|
|
3589
3669
|
}
|
|
3590
3670
|
handleError(error, { sentryEventId });
|
|
@@ -3593,4 +3673,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
3593
3673
|
export {};
|
|
3594
3674
|
|
|
3595
3675
|
//# sourceMappingURL=cli.js.map
|
|
3596
|
-
//# debugId=
|
|
3676
|
+
//# debugId=2db05473-003e-52a5-853a-90e4f4f5ac96
|
|
@@ -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]="
|
|
3
|
-
import { t as inspectAction } from "./inspect-
|
|
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]="b3cfbfd0-a1ae-5a5e-9f1c-e26d272fd0f2")}catch(e){}}();
|
|
3
|
+
import { t as inspectAction } from "./inspect-BIfnzKGq.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-
|
|
14
|
-
//# debugId=
|
|
13
|
+
//# sourceMappingURL=design-CXLKbARh.js.map
|
|
14
|
+
//# debugId=b3cfbfd0-a1ae-5a5e-9f1c-e26d272fd0f2
|
|
@@ -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]="
|
|
3
|
-
import {
|
|
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]="f1b960af-e618-536f-ba25-06c7416b43b4")}catch(e){}}();
|
|
3
|
+
import { i as __toESM, r as __require, t as __commonJSMin } from "./chunk-ChKA3wi6.js";
|
|
4
4
|
//#region ../../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/constants.js
|
|
5
5
|
var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6
6
|
const BINARY_TYPES = [
|
|
@@ -16999,5 +16999,5 @@ if (await isDevToolsReachable()) {
|
|
|
16999
16999
|
//#endregion
|
|
17000
17000
|
export {};
|
|
17001
17001
|
|
|
17002
|
-
//# sourceMappingURL=devtools-
|
|
17003
|
-
//# debugId=
|
|
17002
|
+
//# sourceMappingURL=devtools-CC2PAZ85.js.map
|
|
17003
|
+
//# debugId=f1b960af-e618-536f-ba25-06c7416b43b4
|