react-doctor 0.9.12-dev.1971506 → 0.9.12-dev.1d3e4a6
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/{build-section-divider-dzVqU6Fr.js → build-section-divider-8MOZLIsm.js} +7 -7
- package/dist/{ci-tO6eKsPx.js → ci-BkncxruQ.js} +12 -12
- package/dist/cli.js +24 -24
- package/dist/{design-BOr8ASzl.js → design-cWsjx19m.js} +4 -4
- package/dist/{exit-gracefully-B4JO2DSi.js → exit-gracefully-B9tEGAKH.js} +6 -6
- package/dist/{handle-error-JVQU0Pxy.js → handle-error-wbMFUdUK.js} +5 -5
- package/dist/index.d.ts +32 -0
- package/dist/index.js +275 -164
- package/dist/{inspect-CBkHe9dS.js → inspect-Bz2rayph.js} +16 -16
- package/dist/{install-DG3MH36X.js → install-DdckCi3Z.js} +9 -9
- package/dist/{install-doctor-script-DaB6kssK.js → install-doctor-script-jOg4qbkK.js} +6 -13
- package/dist/{install-github-workflow-CHs4pPvZ.js → install-github-workflow-C5OkC7nA.js} +5 -5
- package/dist/{install-react-doctor-D4Z6xm2T.js → install-react-doctor-W8P-PVpX.js} +8 -8
- package/dist/{jsx-runtime-5ph9KX7N.js → jsx-runtime-0eiF0jis.js} +5 -5
- package/dist/{print-branded-header-BRA02Uik.js → print-branded-header-_cUJmAUD.js} +4 -4
- package/dist/project-analysis-worker.js +3 -3
- package/dist/{prompt-runtime-scan-url-1IvWhRJ0.js → prompt-runtime-scan-url-CV2AUqdk.js} +5 -5
- package/dist/{read-object-file-CacQMaGw.js → read-object-file-DOfcpaZX.js} +4 -4
- package/dist/{record-metric-DcBAbVVs.js → record-metric-BA5ry-7d.js} +227 -116
- package/dist/{report-error-Cj58fOLO.js → report-error-CFe3r9gh.js} +5 -5
- package/dist/{report-workflow-result-DadOSgvV.js → report-workflow-result-BoDN1Z77.js} +5 -5
- package/dist/{resolve-scope-pqK2skSv.js → resolve-scope-BVNh_icv.js} +6 -6
- package/dist/{rules-IBWoSmK_.js → rules-CyIHtrnI.js} +6 -6
- package/dist/{run-scan-app-JphzszIp.js → run-scan-app-BhUlnxaV.js} +11 -10
- package/dist/{runtime-scan-BSMwOS9F.js → runtime-scan-CUt6T5J3.js} +9 -9
- package/dist/{sanitize-runtime-url-BN8oyAb7.js → sanitize-runtime-url-CWANxE3L.js} +4 -4
- package/dist/{scan-1Hakw1J4.js → scan-DU_zcchs.js} +9 -9
- package/dist/{should-fail-scan-gate-CwBjVudY.js → should-fail-scan-gate-CDwqCAPq.js} +11 -11
- package/dist/{should-skip-prompts-CtQ-6r7T.js → should-skip-prompts-B9za5uX9.js} +4 -4
- package/dist/{should-use-tui-BLBNwhU6.js → should-use-tui-BR82qmYC.js} +4 -4
- package/dist/skills/improve-threejs/SKILL.md +102 -0
- package/dist/{telemetry-runtime-BxsPVkMH.js → telemetry-runtime-C9dZxrK_.js} +4 -4
- package/dist/{version-5WSKTaCF.js → version-yw_bHX_4.js} +4 -4
- package/dist/{why-DHTN2DPT.js → why-CdGev87Z.js} +4 -4
- package/dist/{with-run-span-Kn-I23fJ.js → with-run-span-CCVNobt7.js} +5 -5
- package/package.json +5 -4
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { Jt as isPathInsideDirectory, Nt as filterSourceFiles, wr as toCanonicalPath } from "./record-metric-
|
|
4
|
-
import {
|
|
5
|
-
import { d as detectDefaultBranch, f as runCommand, l as prompts, u as isCommandAvailable } from "./install-github-workflow-
|
|
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]="1d88d851-3f7d-5215-ac8e-aeb8454efdf1")}catch(e){}}();
|
|
3
|
+
import { Jt as isPathInsideDirectory, Nt as filterSourceFiles, wr as toCanonicalPath } from "./record-metric-BA5ry-7d.js";
|
|
4
|
+
import { M as cliLogger } from "./install-doctor-script-jOg4qbkK.js";
|
|
5
|
+
import { d as detectDefaultBranch, f as runCommand, l as prompts, u as isCommandAvailable } from "./install-github-workflow-C5OkC7nA.js";
|
|
6
6
|
import * as path$1 from "node:path";
|
|
7
7
|
//#region src/cli/utils/path-format.ts
|
|
8
8
|
const toForwardSlashes = (filePath) => filePath.replaceAll("\\", "/");
|
|
@@ -335,5 +335,5 @@ const finalizeScope = async ({ requested, diffInfo, skipPrompts, isQuiet }) => {
|
|
|
335
335
|
//#endregion
|
|
336
336
|
export { isValidBlockingLevel as a, openWorkflowPullRequest as c, warnDeprecatedDiff as i, stageWorkflowFile as l, isScopeValue as n, pickBlockingLevel as o, resolveScope as r, resolveBlockingLevel as s, finalizeScope as t, toForwardSlashes as u };
|
|
337
337
|
|
|
338
|
-
//# sourceMappingURL=resolve-scope-
|
|
339
|
-
//# debugId=
|
|
338
|
+
//# sourceMappingURL=resolve-scope-BVNh_icv.js.map
|
|
339
|
+
//# debugId=1d88d851-3f7d-5215-ac8e-aeb8454efdf1
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { Kt as highlighter, Sr as isPlainObject, St as clearConfigCache, T as METRIC, Vt as getEquivalentRuleKeys, Zt as isSameRuleKey, bn as validateConfigTypes, gt as buildRuleDocsUrl, nr as COMPILER_CLEANUP_BUCKET, rn as loadConfigWithSource, rr as COMPILER_CLEANUP_RULE_KEYS, t as recordCount } from "./record-metric-
|
|
4
|
-
import {
|
|
5
|
-
import { t as readObjectFile } from "./read-object-file-
|
|
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]="3feddfa4-c798-5030-9bdd-412426100384")}catch(e){}}();
|
|
3
|
+
import { Kt as highlighter, Sr as isPlainObject, St as clearConfigCache, T as METRIC, Vt as getEquivalentRuleKeys, Zt as isSameRuleKey, bn as validateConfigTypes, gt as buildRuleDocsUrl, nr as COMPILER_CLEANUP_BUCKET, rn as loadConfigWithSource, rr as COMPILER_CLEANUP_RULE_KEYS, t as recordCount } from "./record-metric-BA5ry-7d.js";
|
|
4
|
+
import { M as cliLogger, n as findNearestPackageDirectory } from "./install-doctor-script-jOg4qbkK.js";
|
|
5
|
+
import { t as readObjectFile } from "./read-object-file-DOfcpaZX.js";
|
|
6
6
|
import * as path$1 from "node:path";
|
|
7
7
|
import * as fs$1 from "node:fs";
|
|
8
8
|
import { REACT_DOCTOR_RULES } from "oxlint-plugin-react-doctor/core";
|
|
@@ -577,5 +577,5 @@ const rulesUnignoreTagAction = async (tag, options) => {
|
|
|
577
577
|
//#endregion
|
|
578
578
|
export { rulesCategoryAction, rulesDisableAction, rulesEnableAction, rulesExplainAction, rulesIgnoreTagAction, rulesListAction, rulesSetAction, rulesUnignoreTagAction };
|
|
579
579
|
|
|
580
|
-
//# sourceMappingURL=rules-
|
|
581
|
-
//# debugId=
|
|
580
|
+
//# sourceMappingURL=rules-CyIHtrnI.js.map
|
|
581
|
+
//# debugId=3feddfa4-c798-5030-9bdd-412426100384
|
|
@@ -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 { Bn as sync, Bt as getDiffInfo, C as CI_TRUST_COMPANIES, G as isCiEnvironment, Hn as void_, Jt as isPathInsideDirectory, Kn as succeed, Kt as highlighter, L as TUI_REPORT_COMPACT_MAX_ROWS, Lt as getBaselineDiffPlan, R as TUI_REPORT_DETAIL_WIDTH_FRACTION, Rn as runPromise, Rt as getChangedLineRanges, T as METRIC, Ut as hasPublishedFixRecipe, V as isGitHookEnvironment, ar as DIAGNOSTIC_CATEGORY_BUCKETS, at as Progress, cr as GITHUB_ACTIONS_SETUP_URL, fn as resolveScanTarget, gt as buildRuleDocsUrl, in as mapWithConcurrency, n as recordDistribution, sn as remainingDeadlineBudgetMs, st as Reporter, t as recordCount, vr as getCategoryImpact, xn as yieldToEventLoop, yt as calculateScore } from "./record-metric-
|
|
4
|
-
import {
|
|
5
|
-
import { i as isReactDoctorWorkflowInstalled } from "./install-github-workflow-
|
|
6
|
-
import { r as resolveScope, s as resolveBlockingLevel, t as finalizeScope, u as toForwardSlashes } from "./resolve-scope-
|
|
7
|
-
import { A as resolveMergeBaseRef, B as buildNoScoreMessage, C as copyToClipboard, D as deduplicateProjectScans, E as collectProjectSourceFileCounts, F as printFooter, G as formatFixRecipeLine, H as hasLintHardFailure, I as printDiagnosticsDump, K as formatLearnMoreLine, L as formatDiagnosticSite, M as pluralize, N as formatSkippedCheckLabel, O as createInvocationInspect, P as formatElapsedTime, R as hasIncompleteScoreAnalysis, S as CLI_AGENT_BINARIES, T as buildHandoffPayload, U as buildRulePriorityMap, V as buildEmptyReportMessage, W as buildSortedRuleGroups, _ as resolveCliInspectOptions, a as projectManifestChanged, b as setUpGitHubActions, c as selectProjects, d as resolveProjectChangedLineRanges, f as resolveProjectDiffIncludePaths, g as resolveWorkspaceDeadCodeOwner, h as retryMissingProjectScores, l as buildCodeFrame, n as formatSkippedProjectsMessage, o as partitionProjectScanOutcomes, p as resolveProjectSourceFilePaths, r as validateIncludeUntrackedScope, s as discoverWorkspacePackages, t as shouldFailScanGate, u as resolveProjectScan, v as filterScansForSurface, w as launchCliAgent, x as detectLaunchableAgents, y as countUniqueScannedFiles, z as filterDiagnosticsByCategories } from "./should-fail-scan-gate-
|
|
8
|
-
import { a as recordGate, f as ONBOARDING_EVENT, n as openUrl, r as isGatePending } from "./report-workflow-result-
|
|
9
|
-
import { a as useExitOnCtrlC, c as Spinner, d as useInput, f as Transform, h as Box, i as import_react, l as useStdout, m as Text, n as registerMountedTuiRenderer, o as terminalSymbols, p as render, r as useStdoutDimensions, s as isPrintableInput, t as require_jsx_runtime, u as useApp } from "./jsx-runtime-
|
|
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]="e56fb95d-437f-5327-b155-bbc1a288b833")}catch(e){}}();
|
|
3
|
+
import { Bn as sync, Bt as getDiffInfo, C as CI_TRUST_COMPANIES, G as isCiEnvironment, Hn as void_, Jt as isPathInsideDirectory, Kn as succeed, Kt as highlighter, L as TUI_REPORT_COMPACT_MAX_ROWS, Lt as getBaselineDiffPlan, R as TUI_REPORT_DETAIL_WIDTH_FRACTION, Rn as runPromise, Rt as getChangedLineRanges, T as METRIC, Ut as hasPublishedFixRecipe, V as isGitHookEnvironment, ar as DIAGNOSTIC_CATEGORY_BUCKETS, at as Progress, cr as GITHUB_ACTIONS_SETUP_URL, fn as resolveScanTarget, gt as buildRuleDocsUrl, in as mapWithConcurrency, n as recordDistribution, sn as remainingDeadlineBudgetMs, st as Reporter, t as recordCount, vr as getCategoryImpact, xn as yieldToEventLoop, yt as calculateScore } from "./record-metric-BA5ry-7d.js";
|
|
4
|
+
import { M as cliLogger, n as findNearestPackageDirectory } from "./install-doctor-script-jOg4qbkK.js";
|
|
5
|
+
import { i as isReactDoctorWorkflowInstalled } from "./install-github-workflow-C5OkC7nA.js";
|
|
6
|
+
import { r as resolveScope, s as resolveBlockingLevel, t as finalizeScope, u as toForwardSlashes } from "./resolve-scope-BVNh_icv.js";
|
|
7
|
+
import { A as resolveMergeBaseRef, B as buildNoScoreMessage, C as copyToClipboard, D as deduplicateProjectScans, E as collectProjectSourceFileCounts, F as printFooter, G as formatFixRecipeLine, H as hasLintHardFailure, I as printDiagnosticsDump, K as formatLearnMoreLine, L as formatDiagnosticSite, M as pluralize, N as formatSkippedCheckLabel, O as createInvocationInspect, P as formatElapsedTime, R as hasIncompleteScoreAnalysis, S as CLI_AGENT_BINARIES, T as buildHandoffPayload, U as buildRulePriorityMap, V as buildEmptyReportMessage, W as buildSortedRuleGroups, _ as resolveCliInspectOptions, a as projectManifestChanged, b as setUpGitHubActions, c as selectProjects, d as resolveProjectChangedLineRanges, f as resolveProjectDiffIncludePaths, g as resolveWorkspaceDeadCodeOwner, h as retryMissingProjectScores, l as buildCodeFrame, n as formatSkippedProjectsMessage, o as partitionProjectScanOutcomes, p as resolveProjectSourceFilePaths, r as validateIncludeUntrackedScope, s as discoverWorkspacePackages, t as shouldFailScanGate, u as resolveProjectScan, v as filterScansForSurface, w as launchCliAgent, x as detectLaunchableAgents, y as countUniqueScannedFiles, z as filterDiagnosticsByCategories } from "./should-fail-scan-gate-CDwqCAPq.js";
|
|
8
|
+
import { a as recordGate, f as ONBOARDING_EVENT, n as openUrl, r as isGatePending } from "./report-workflow-result-BoDN1Z77.js";
|
|
9
|
+
import { a as useExitOnCtrlC, c as Spinner, d as useInput, f as Transform, h as Box, i as import_react, l as useStdout, m as Text, n as registerMountedTuiRenderer, o as terminalSymbols, p as render, r as useStdoutDimensions, s as isPrintableInput, t as require_jsx_runtime, u as useApp } from "./jsx-runtime-0eiF0jis.js";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { performance } from "node:perf_hooks";
|
|
12
|
+
import isUnicodeSupported from "is-unicode-supported";
|
|
12
13
|
import { getSkillAgentConfig } from "agent-install";
|
|
13
14
|
//#region src/cli/utils/get-top-error-rule-keys.ts
|
|
14
15
|
const getTopErrorRuleKeys = (diagnostics, limit, rulePriority) => new Set(buildSortedRuleGroups(diagnostics.filter((diagnostic) => diagnostic.severity === "error"), rulePriority).slice(0, limit).map(([ruleKey]) => ruleKey));
|
|
@@ -2504,5 +2505,5 @@ const runScanApp = async (input) => {
|
|
|
2504
2505
|
//#endregion
|
|
2505
2506
|
export { runScanApp };
|
|
2506
2507
|
|
|
2507
|
-
//# sourceMappingURL=run-scan-app-
|
|
2508
|
-
//# debugId=
|
|
2508
|
+
//# sourceMappingURL=run-scan-app-BhUlnxaV.js.map
|
|
2509
|
+
//# debugId=e56fb95d-437f-5327-b155-bbc1a288b833
|
|
@@ -1,11 +1,11 @@
|
|
|
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 { Kt as highlighter, T as METRIC, t as recordCount, u as enableJsonMode, z as CliInputError } from "./record-metric-
|
|
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]="725ef887-7edf-5bb0-81cc-7a9e73efad9c")}catch(e){}}();
|
|
3
|
+
import { Kt as highlighter, T as METRIC, t as recordCount, u as enableJsonMode, z as CliInputError } from "./record-metric-BA5ry-7d.js";
|
|
4
4
|
import { t as activeScanAbortRegistry } from "./active-scan-abort-registry-DwG6tSPy.js";
|
|
5
|
-
import { t as reportErrorToSentry } from "./report-error-
|
|
6
|
-
import { n as resetSentryRunState, r as withRunSpan } from "./with-run-span-
|
|
7
|
-
import { _ as RUNTIME_SCAN_SNAPSHOT_TIMEOUT_MS, b as RUNTIME_SCAN_TRACING_COMPLETE_TIMEOUT_MS, f as RUNTIME_SCAN_PROBE_RELATIVE_PATH, g as RUNTIME_SCAN_SAFE_CDP_PAGE_URLS, h as RUNTIME_SCAN_PROBE_SNAPSHOT_TOKEN_PLACEHOLDER, l as RUNTIME_SCAN_MAX_SNAPSHOT_PAYLOAD_BYTES, m as RUNTIME_SCAN_PROBE_SNAPSHOT_BINDING_NAME_PLACEHOLDER, n as RUNTIME_SCAN_BROWSER_WIDTH_PX, o as RUNTIME_SCAN_MAX_COMPONENT_EVENTS, p as RUNTIME_SCAN_PROBE_SNAPSHOT_ATTRIBUTE_NAME_PLACEHOLDER, r as RUNTIME_SCAN_CONTROL_CHARACTERS_PATTERN, s as RUNTIME_SCAN_MAX_RECORDING_DURATION_MS, t as sanitizeRuntimeUrl, v as RUNTIME_SCAN_TRACE_CATEGORIES, y as RUNTIME_SCAN_TRACE_FILE_EXTENSION } from "./sanitize-runtime-url-
|
|
8
|
-
import { r as resolveTuiEnvironment, t as isTuiEnvironmentSupported } from "./should-use-tui-
|
|
5
|
+
import { t as reportErrorToSentry } from "./report-error-CFe3r9gh.js";
|
|
6
|
+
import { n as resetSentryRunState, r as withRunSpan } from "./with-run-span-CCVNobt7.js";
|
|
7
|
+
import { _ as RUNTIME_SCAN_SNAPSHOT_TIMEOUT_MS, b as RUNTIME_SCAN_TRACING_COMPLETE_TIMEOUT_MS, f as RUNTIME_SCAN_PROBE_RELATIVE_PATH, g as RUNTIME_SCAN_SAFE_CDP_PAGE_URLS, h as RUNTIME_SCAN_PROBE_SNAPSHOT_TOKEN_PLACEHOLDER, l as RUNTIME_SCAN_MAX_SNAPSHOT_PAYLOAD_BYTES, m as RUNTIME_SCAN_PROBE_SNAPSHOT_BINDING_NAME_PLACEHOLDER, n as RUNTIME_SCAN_BROWSER_WIDTH_PX, o as RUNTIME_SCAN_MAX_COMPONENT_EVENTS, p as RUNTIME_SCAN_PROBE_SNAPSHOT_ATTRIBUTE_NAME_PLACEHOLDER, r as RUNTIME_SCAN_CONTROL_CHARACTERS_PATTERN, s as RUNTIME_SCAN_MAX_RECORDING_DURATION_MS, t as sanitizeRuntimeUrl, v as RUNTIME_SCAN_TRACE_CATEGORIES, y as RUNTIME_SCAN_TRACE_FILE_EXTENSION } from "./sanitize-runtime-url-CWANxE3L.js";
|
|
8
|
+
import { r as resolveTuiEnvironment, t as isTuiEnvironmentSupported } from "./should-use-tui-BR82qmYC.js";
|
|
9
9
|
import * as path$1 from "node:path";
|
|
10
10
|
import * as fs$1 from "node:fs";
|
|
11
11
|
import { randomUUID } from "node:crypto";
|
|
@@ -719,7 +719,7 @@ const resolveRuntimeScanUrl = async (url) => {
|
|
|
719
719
|
if (url !== void 0) return url;
|
|
720
720
|
if (!isTuiEnvironmentSupported(resolveTuiEnvironment(process.stderr.isTTY === true))) throw new CliInputError("A URL is required outside an interactive terminal. Run `react-doctor scan <url>`.");
|
|
721
721
|
recordCount(METRIC.runtimeScanUrlPromptShown);
|
|
722
|
-
const { promptRuntimeScanUrl } = await import("./prompt-runtime-scan-url-
|
|
722
|
+
const { promptRuntimeScanUrl } = await import("./prompt-runtime-scan-url-CV2AUqdk.js");
|
|
723
723
|
return promptRuntimeScanUrl();
|
|
724
724
|
};
|
|
725
725
|
const runtimeScanAction = async (url, flags) => {
|
|
@@ -766,5 +766,5 @@ const runtimeScanAction = async (url, flags) => {
|
|
|
766
766
|
//#endregion
|
|
767
767
|
export { runtimeScanAction };
|
|
768
768
|
|
|
769
|
-
//# sourceMappingURL=runtime-scan-
|
|
770
|
-
//# debugId=
|
|
769
|
+
//# sourceMappingURL=runtime-scan-CUt6T5J3.js.map
|
|
770
|
+
//# debugId=725ef887-7edf-5bb0-81cc-7a9e73efad9c
|
|
@@ -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 { z as CliInputError } from "./record-metric-
|
|
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]="e67fc8b2-b516-5d60-ad56-2ca455ab3354")}catch(e){}}();
|
|
3
|
+
import { z as CliInputError } from "./record-metric-BA5ry-7d.js";
|
|
4
4
|
//#region src/cli/runtime-scan/constants.ts
|
|
5
5
|
const RUNTIME_SCAN_MAX_COMPONENT_EVENTS = 2e3;
|
|
6
6
|
const RUNTIME_SCAN_MAX_SNAPSHOT_PAYLOAD_BYTES = 5 * 1024 * 1024;
|
|
@@ -72,5 +72,5 @@ const sanitizeRuntimeUrl = (rawUrl) => {
|
|
|
72
72
|
//#endregion
|
|
73
73
|
export { RUNTIME_SCAN_SNAPSHOT_TIMEOUT_MS as _, RUNTIME_SCAN_LOCAL_DEV_PORTS as a, RUNTIME_SCAN_TRACING_COMPLETE_TIMEOUT_MS as b, RUNTIME_SCAN_MAX_SNAPSHOT_BYTES as c, RUNTIME_SCAN_MAX_TRACE_BYTES as d, RUNTIME_SCAN_PROBE_RELATIVE_PATH as f, RUNTIME_SCAN_SAFE_CDP_PAGE_URLS as g, RUNTIME_SCAN_PROBE_SNAPSHOT_TOKEN_PLACEHOLDER as h, RUNTIME_SCAN_LAYOUT_THRASH_RATIO as i, RUNTIME_SCAN_MAX_SNAPSHOT_PAYLOAD_BYTES as l, RUNTIME_SCAN_PROBE_SNAPSHOT_BINDING_NAME_PLACEHOLDER as m, RUNTIME_SCAN_BROWSER_WIDTH_PX as n, RUNTIME_SCAN_MAX_COMPONENT_EVENTS as o, RUNTIME_SCAN_PROBE_SNAPSHOT_ATTRIBUTE_NAME_PLACEHOLDER as p, RUNTIME_SCAN_CONTROL_CHARACTERS_PATTERN as r, RUNTIME_SCAN_MAX_RECORDING_DURATION_MS as s, sanitizeRuntimeUrl as t, RUNTIME_SCAN_MAX_STRING_LENGTH as u, RUNTIME_SCAN_TRACE_CATEGORIES as v, RUNTIME_SCAN_TRACE_FILE_EXTENSION as y };
|
|
74
74
|
|
|
75
|
-
//# sourceMappingURL=sanitize-runtime-url-
|
|
76
|
-
//# debugId=
|
|
75
|
+
//# sourceMappingURL=sanitize-runtime-url-CWANxE3L.js.map
|
|
76
|
+
//# debugId=e67fc8b2-b516-5d60-ad56-2ca455ab3354
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { T as METRIC, fn as resolveScanTarget, t as recordCount } from "./record-metric-
|
|
4
|
-
import { i as warnDeprecatedDiff } from "./resolve-scope-
|
|
5
|
-
import { _ as resolveCliInspectOptions, i as validateModeFlags } from "./should-fail-scan-gate-
|
|
6
|
-
import { n as warnDeprecatedFailOn, r as runProjectMigrations, t as inspectAction } from "./inspect-
|
|
7
|
-
import { n as shouldUseTui, r as resolveTuiEnvironment } from "./should-use-tui-
|
|
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]="36d1800a-05d3-57f5-b818-d4b9442c0ee9")}catch(e){}}();
|
|
3
|
+
import { T as METRIC, fn as resolveScanTarget, t as recordCount } from "./record-metric-BA5ry-7d.js";
|
|
4
|
+
import { i as warnDeprecatedDiff } from "./resolve-scope-BVNh_icv.js";
|
|
5
|
+
import { _ as resolveCliInspectOptions, i as validateModeFlags } from "./should-fail-scan-gate-CDwqCAPq.js";
|
|
6
|
+
import { n as warnDeprecatedFailOn, r as runProjectMigrations, t as inspectAction } from "./inspect-Bz2rayph.js";
|
|
7
|
+
import { n as shouldUseTui, r as resolveTuiEnvironment } from "./should-use-tui-BR82qmYC.js";
|
|
8
8
|
import path from "node:path";
|
|
9
9
|
//#region src/cli/commands/scan.ts
|
|
10
10
|
const runScanCommand = async (input) => {
|
|
@@ -22,7 +22,7 @@ const runScanCommand = async (input) => {
|
|
|
22
22
|
warnDeprecatedFailOn(input.flags, scanTarget.userConfig);
|
|
23
23
|
warnDeprecatedDiff(input.flags, scanTarget.userConfig);
|
|
24
24
|
recordCount(METRIC.cliInvoked, 1, { command: input.invocationCommand });
|
|
25
|
-
const { runScanApp } = await import("./run-scan-app-
|
|
25
|
+
const { runScanApp } = await import("./run-scan-app-BhUlnxaV.js");
|
|
26
26
|
const { shouldFail } = await runScanApp({
|
|
27
27
|
directory: input.directory,
|
|
28
28
|
scanTarget,
|
|
@@ -37,5 +37,5 @@ const runScanCommand = async (input) => {
|
|
|
37
37
|
//#endregion
|
|
38
38
|
export { runScanCommand };
|
|
39
39
|
|
|
40
|
-
//# sourceMappingURL=scan-
|
|
41
|
-
//# debugId=
|
|
40
|
+
//# sourceMappingURL=scan-DU_zcchs.js.map
|
|
41
|
+
//# debugId=36d1800a-05d3-57f5-b818-d4b9442c0ee9
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { $ as Linter, A as SCAN_RESULT_CACHE_FILENAME, An as gen, At as discoverSupportedSubprojects, B as isNonInteractiveEnvironment, Bn as sync, Cn as error, Ct as collectSourceFileCountsByDirectory, Dn as Diagnostic, Dt as createNodeReadFileLinesSync, En as warn, Et as countOptInProjectRuleSelections, Fn as provide, G as isCiEnvironment, Gt as hashFileContents, Ht as groupBy, In as provideContext, J as Config, Jt as isPathInsideDirectory, K as isCiOrCodingAgentEnvironment, Kn as succeed, Kt as highlighter, Ln as provideService, Mn as map, Mt as filterPathsOutsideDirectories, Nn as orElseSucceed, Nt as filterSourceFiles, On as decodeUnknownSync, Ot as createOxlintSpawnSlots, Pn as promise, Q as LintPartialFailures, Qt as isScanComplete, Rn as runPromise, S as BASELINE_FILES_TEMP_DIR_PREFIX, Sn as Console, T as METRIC, Tn as log, Tt as computeDiagnosticDelta, U as ACTION_INPUT_ENVIRONMENT_VARIABLES, Ut as hasPublishedFixRecipe, Vn as try_, W as detectRunnerOs, Wn as mergeAll, X as Git, Xt as isReactDoctorError, Y as Files, Zn as ParentSpan, _ as VERSION, _n as shouldUseMaintainabilityLayer, _t as buildRuleSeverityControls, an as materializeSourceTree, ar as DIAGNOSTIC_CATEGORY_BUCKETS, at as Progress, bt as canonicalizeUserRuleKey, cn as resolveGithubActionsScoreMetadata, ct as Score, d as isJsonModeActive, dn as resolveScanConcurrency, dr as JSX_DUPLICATION_SOURCE_FILE_PATTERN, dt as SupplyChain, en as listSourceFiles, et as Maintainability, fn as resolveScanTarget, fr as JSX_FILE_PATTERN, gt as buildRuleDocsUrl, hr as SHARE_BASE_URL, in as mapWithConcurrency, it as PerFileLintCacheEnabled, jt as filterDiagnosticsForSurface, l as getRunId, ln as resolveLintBatchOrdering, lr as GIT_SHOW_MAX_BUFFER_BYTES, lt as SidecarLintCacheEnabled, mn as runInspect, mr as OXLINT_NODE_REQUIREMENT, mt as atomicWriteJson, n as recordDistribution, nn as listWorkspacePackages, nt as OxlintConcurrency, on as mergeReactDoctorConfigs, ot as Project, pn as restoreLegacyThrow, pr as MILLISECONDS_PER_SECOND, qt as isMonorepoRoot, r as toSpanAttributes, rt as OxlintSpawnSlots, sn as remainingDeadlineBudgetMs, sr as ENTERPRISE_CONTACT_URL, st as Reporter, t as recordCount, tn as listSourceFilesCooperative, tr as CI_URL, tt as NodeResolver, un as resolveReactDoctorCacheDir, ur as HTML_FILE_PATTERN, v as makeNoopConsole, vn as summarizeDiagnostics, vt as buildSkippedChecks, wt as computeConfigFingerprint, xn as yieldToEventLoop, xr as isFile, xt as classifyFileContext, yr as isDirectory, yt as calculateScore, z as CliInputError, zn as runSync, zt as getDiagnosticRuleIdentity } from "./record-metric-
|
|
4
|
-
import { t as getTelemetryContext } from "./telemetry-runtime-
|
|
5
|
-
import { n as buildFooterLinkLines, t as buildSectionDivider } from "./build-section-divider-
|
|
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]="0af88013-0e63-5d8e-8292-66400d39d007")}catch(e){}}();
|
|
3
|
+
import { $ as Linter, A as SCAN_RESULT_CACHE_FILENAME, An as gen, At as discoverSupportedSubprojects, B as isNonInteractiveEnvironment, Bn as sync, Cn as error, Ct as collectSourceFileCountsByDirectory, Dn as Diagnostic, Dt as createNodeReadFileLinesSync, En as warn, Et as countOptInProjectRuleSelections, Fn as provide, G as isCiEnvironment, Gt as hashFileContents, Ht as groupBy, In as provideContext, J as Config, Jt as isPathInsideDirectory, K as isCiOrCodingAgentEnvironment, Kn as succeed, Kt as highlighter, Ln as provideService, Mn as map, Mt as filterPathsOutsideDirectories, Nn as orElseSucceed, Nt as filterSourceFiles, On as decodeUnknownSync, Ot as createOxlintSpawnSlots, Pn as promise, Q as LintPartialFailures, Qt as isScanComplete, Rn as runPromise, S as BASELINE_FILES_TEMP_DIR_PREFIX, Sn as Console, T as METRIC, Tn as log, Tt as computeDiagnosticDelta, U as ACTION_INPUT_ENVIRONMENT_VARIABLES, Ut as hasPublishedFixRecipe, Vn as try_, W as detectRunnerOs, Wn as mergeAll, X as Git, Xt as isReactDoctorError, Y as Files, Zn as ParentSpan, _ as VERSION, _n as shouldUseMaintainabilityLayer, _t as buildRuleSeverityControls, an as materializeSourceTree, ar as DIAGNOSTIC_CATEGORY_BUCKETS, at as Progress, bt as canonicalizeUserRuleKey, cn as resolveGithubActionsScoreMetadata, ct as Score, d as isJsonModeActive, dn as resolveScanConcurrency, dr as JSX_DUPLICATION_SOURCE_FILE_PATTERN, dt as SupplyChain, en as listSourceFiles, et as Maintainability, fn as resolveScanTarget, fr as JSX_FILE_PATTERN, gt as buildRuleDocsUrl, hr as SHARE_BASE_URL, in as mapWithConcurrency, it as PerFileLintCacheEnabled, jt as filterDiagnosticsForSurface, l as getRunId, ln as resolveLintBatchOrdering, lr as GIT_SHOW_MAX_BUFFER_BYTES, lt as SidecarLintCacheEnabled, mn as runInspect, mr as OXLINT_NODE_REQUIREMENT, mt as atomicWriteJson, n as recordDistribution, nn as listWorkspacePackages, nt as OxlintConcurrency, on as mergeReactDoctorConfigs, ot as Project, pn as restoreLegacyThrow, pr as MILLISECONDS_PER_SECOND, qt as isMonorepoRoot, r as toSpanAttributes, rt as OxlintSpawnSlots, sn as remainingDeadlineBudgetMs, sr as ENTERPRISE_CONTACT_URL, st as Reporter, t as recordCount, tn as listSourceFilesCooperative, tr as CI_URL, tt as NodeResolver, un as resolveReactDoctorCacheDir, ur as HTML_FILE_PATTERN, v as makeNoopConsole, vn as summarizeDiagnostics, vt as buildSkippedChecks, wt as computeConfigFingerprint, xn as yieldToEventLoop, xr as isFile, xt as classifyFileContext, yr as isDirectory, yt as calculateScore, z as CliInputError, zn as runSync, zt as getDiagnosticRuleIdentity } from "./record-metric-BA5ry-7d.js";
|
|
4
|
+
import { t as getTelemetryContext } from "./telemetry-runtime-C9dZxrK_.js";
|
|
5
|
+
import { n as buildFooterLinkLines, t as buildSectionDivider } from "./build-section-divider-8MOZLIsm.js";
|
|
6
6
|
import { t as activeScanAbortRegistry } from "./active-scan-abort-registry-DwG6tSPy.js";
|
|
7
|
-
import {
|
|
8
|
-
import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-
|
|
9
|
-
import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel, u as toForwardSlashes } from "./resolve-scope-
|
|
10
|
-
import { n as resetSentryRunState, r as withRunSpan, t as recordSentryProjectContext } from "./with-run-span-
|
|
11
|
-
import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-
|
|
7
|
+
import { C as isRecord, M as cliLogger, S as getPackageJsonPath, a as installReactDoctorScriptStep, c as spinner, k as runGit, n as findNearestPackageDirectory, o as isSpinnerSilent, s as setSpinnerSilent } from "./install-doctor-script-jOg4qbkK.js";
|
|
8
|
+
import { d as detectDefaultBranch, l as prompts, r as installReactDoctorWorkflow, u as isCommandAvailable } from "./install-github-workflow-C5OkC7nA.js";
|
|
9
|
+
import { a as isValidBlockingLevel, c as openWorkflowPullRequest, l as stageWorkflowFile, o as pickBlockingLevel, u as toForwardSlashes } from "./resolve-scope-BVNh_icv.js";
|
|
10
|
+
import { n as resetSentryRunState, r as withRunSpan, t as recordSentryProjectContext } from "./with-run-span-CCVNobt7.js";
|
|
11
|
+
import { h as detectAvailableAgents, t as reportWorkflowResult } from "./report-workflow-result-BoDN1Z77.js";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
13
|
import { spawn } from "node:child_process";
|
|
14
14
|
import * as path$1 from "node:path";
|
|
@@ -2997,5 +2997,5 @@ const shouldFailScanGate = (input) => {
|
|
|
2997
2997
|
//#endregion
|
|
2998
2998
|
export { resolveMergeBaseRef as A, buildNoScoreMessage as B, copyToClipboard as C, deduplicateProjectScans as D, collectProjectSourceFileCounts as E, printFooter as F, formatFixRecipeLine as G, hasLintHardFailure as H, printDiagnosticsDump as I, formatLearnMoreLine as K, formatDiagnosticSite as L, pluralize as M, formatSkippedCheckLabel as N, createInvocationInspect as O, formatElapsedTime as P, hasIncompleteScoreAnalysis as R, CLI_AGENT_BINARIES as S, buildHandoffPayload as T, buildRulePriorityMap as U, buildEmptyReportMessage as V, buildSortedRuleGroups as W, resolveCliInspectOptions as _, projectManifestChanged as a, setUpGitHubActions as b, selectProjects as c, resolveProjectChangedLineRanges as d, resolveProjectDiffIncludePaths as f, resolveWorkspaceDeadCodeOwner as g, retryMissingProjectScores as h, validateModeFlags as i, printHeadlessReport as j, inspect as k, buildCodeFrame as l, resolveProjectRelativeDirectory as m, formatSkippedProjectsMessage as n, partitionProjectScanOutcomes as o, resolveProjectSourceFilePaths as p, validateIncludeUntrackedScope as r, discoverWorkspacePackages as s, shouldFailScanGate as t, resolveProjectScan as u, filterScansForSurface as v, launchCliAgent as w, detectLaunchableAgents as x, countUniqueScannedFiles as y, filterDiagnosticsByCategories as z };
|
|
2999
2999
|
|
|
3000
|
-
//# sourceMappingURL=should-fail-scan-gate-
|
|
3001
|
-
//# debugId=
|
|
3000
|
+
//# sourceMappingURL=should-fail-scan-gate-CDwqCAPq.js.map
|
|
3001
|
+
//# debugId=0af88013-0e63-5d8e-8292-66400d39d007
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { B as isNonInteractiveEnvironment } from "./record-metric-
|
|
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]="8d1f8205-382d-5e88-adbc-51c603910830")}catch(e){}}();
|
|
3
|
+
import { B as isNonInteractiveEnvironment } from "./record-metric-BA5ry-7d.js";
|
|
4
4
|
//#region src/cli/utils/should-skip-prompts.ts
|
|
5
5
|
const shouldSkipPrompts = (input = {}) => Boolean(input.yes) || Boolean(input.json) || isNonInteractiveEnvironment() || !process.stdin.isTTY;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { shouldSkipPrompts as t };
|
|
8
8
|
|
|
9
|
-
//# sourceMappingURL=should-skip-prompts-
|
|
10
|
-
//# debugId=
|
|
9
|
+
//# sourceMappingURL=should-skip-prompts-B9za5uX9.js.map
|
|
10
|
+
//# debugId=8d1f8205-382d-5e88-adbc-51c603910830
|
|
@@ -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 { B as isNonInteractiveEnvironment } from "./record-metric-
|
|
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]="11b18b5e-a590-54bc-b883-b2b36ab9b0d7")}catch(e){}}();
|
|
3
|
+
import { B as isNonInteractiveEnvironment } from "./record-metric-BA5ry-7d.js";
|
|
4
4
|
//#region src/cli/utils/resolve-tui-environment.ts
|
|
5
5
|
const resolveTuiEnvironment = (outputIsTty = process.stdout.isTTY === true) => ({
|
|
6
6
|
isNonInteractiveEnvironment: isNonInteractiveEnvironment(),
|
|
@@ -21,5 +21,5 @@ const shouldUseTui = (input) => {
|
|
|
21
21
|
//#endregion
|
|
22
22
|
export { shouldUseTui as n, resolveTuiEnvironment as r, isTuiEnvironmentSupported as t };
|
|
23
23
|
|
|
24
|
-
//# sourceMappingURL=should-use-tui-
|
|
25
|
-
//# debugId=
|
|
24
|
+
//# sourceMappingURL=should-use-tui-BR82qmYC.js.map
|
|
25
|
+
//# debugId=11b18b5e-a590-54bc-b883-b2b36ab9b0d7
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: improve-threejs
|
|
3
|
+
description: Audit and fix Three.js and React Three Fiber apps for frame-loop performance, GPU memory leaks, scene-graph correctness, and visual defects like z-fighting, shadow acne, wrong color space, and broken resize handling. Uses React Doctor as the scanning engine plus a visual rubric checked against rendered output. Use when the user asks to improve, audit, scan, or clean up a Three.js, R3F, react-three-fiber, drei, or WebGL app, or types `/improve-threejs`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Improve Three.js
|
|
7
|
+
|
|
8
|
+
Audits a Three.js or React Three Fiber (R3F) codebase and fixes what hurts most: work that runs every frame, GPU resources that never get disposed, scene-graph objects rebuilt on every render, and visual defects the user can see. React Doctor supplies the machine-verified code scan; this skill supplies the frame-loop judgment and the visual inspection a general React scanner lacks.
|
|
9
|
+
|
|
10
|
+
The core principle: severity follows the render loop. Code inside `useFrame` or a `requestAnimationFrame` callback runs 60 times per second, so a minor inefficiency there outweighs a major one in a settings panel. Rank every finding by where it runs, not by the rule's default severity.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
### Step 1: Recon
|
|
15
|
+
|
|
16
|
+
Identify the stack before scanning: plain Three.js or R3F, which helper libraries are in use (drei, postprocessing, rapier), and where the render loop lives (`useFrame` hooks, `requestAnimationFrame`, the `<Canvas frameloop>` setting).
|
|
17
|
+
|
|
18
|
+
Build a hot-path map: every `useFrame` body, every RAF callback, every pointer-move handler. These files get the strictest review in Step 3.
|
|
19
|
+
|
|
20
|
+
### Step 2: Scan
|
|
21
|
+
|
|
22
|
+
Run React Doctor read-only to collect structured evidence:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx react-doctor@latest --verbose
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For a regression check after making changes, run with `--scope changed` and confirm the score did not drop.
|
|
29
|
+
|
|
30
|
+
### Step 3: Triage by frame-loop leverage
|
|
31
|
+
|
|
32
|
+
Re-rank the scanner's findings using the hot-path map, then hunt for the Three.js-specific problems the scanner cannot see. Confirm every finding at its `file:line` before reporting it.
|
|
33
|
+
|
|
34
|
+
**HIGH severity, runs every frame or leaks GPU memory:**
|
|
35
|
+
|
|
36
|
+
- **Allocation inside `useFrame`**: `new Vector3()`, `new Color()`, or fresh arrays passed to Three.js APIs each frame. Fix: hoist a scratch object to module scope or `useMemo`, then mutate it in place
|
|
37
|
+
- **`setState` inside `useFrame`**: re-renders the React tree on every frame. Fix: mutate refs directly; reserve state for discrete changes like selection or visibility
|
|
38
|
+
- **Missing disposal**: geometries, materials, textures, or render targets created imperatively and never disposed. Fix: call `dispose()` in the cleanup function, or move the object into R3F's declarative tree so it owns the lifecycle
|
|
39
|
+
- **Object reconstruction in render**: geometry or material instances created without `useMemo`, or inline `args` arrays whose identity changes each render, forcing R3F to rebuild the underlying object
|
|
40
|
+
|
|
41
|
+
**MEDIUM severity, per-render or per-interaction waste:**
|
|
42
|
+
|
|
43
|
+
- **Unstable scene-graph props**: inline `new THREE.Vector3()` or fresh material objects as props (plain arrays like `position={[x, y, z]}` are fine; R3F handles them)
|
|
44
|
+
- **Missing instancing**: hundreds of identical meshes rendered individually instead of through `<Instances>` or `InstancedMesh`
|
|
45
|
+
- **Wasted frames**: `frameloop="always"` on a scene that only changes on interaction. Fix: `frameloop="demand"` plus `invalidate()`
|
|
46
|
+
- **Uncached asset loading**: textures and models loaded outside `useLoader`, `useTexture`, or `useGLTF`, losing caching and Suspense integration
|
|
47
|
+
|
|
48
|
+
**LOW severity, hygiene:** React Doctor findings on non-canvas UI code, missing `<Preload>`, oversized textures.
|
|
49
|
+
|
|
50
|
+
### Step 4: Visual audit
|
|
51
|
+
|
|
52
|
+
Inspect what the scene actually renders. Every visual finding needs evidence: a screenshot, a frame capture, or a reproduced observation, never a guess from reading source. When a dev server and browser are available, load the app, capture the first stable frame, then capture again after moving the camera and interacting. When no browser is available, check the code-level causes listed below and label each finding as inferred from source.
|
|
53
|
+
|
|
54
|
+
Apply the mini rubric. A row fails only when the evidence shows the failure condition:
|
|
55
|
+
|
|
56
|
+
| Area | Check | Fail when |
|
|
57
|
+
| ---------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| Render sanity | The scene reaches a stable frame after load | Black canvas, WebGL context errors, or content that never appears |
|
|
59
|
+
| Geometry | Move the camera along seams, edges, and boundaries | Gaps, missing faces, visible backfaces, or two surfaces flickering at the same depth (z-fighting) |
|
|
60
|
+
| Transparency and depth | Cross depth-order boundaries with overlapping or transmissive surfaces | Wrong sort order, halos, opaque surfaces that should transmit, or flicker at grazing angles |
|
|
61
|
+
| Textures | View mapped surfaces close, far, and at grazing angles | Missing textures, stretching, seams, moiré, shimmer, or washed-out colors from a wrong color space |
|
|
62
|
+
| Materials and lighting | Change light and view direction on lit surfaces | Surfaces that ignore light direction, or reflective metals with no environment to reflect |
|
|
63
|
+
| Shadows | Move casters, receivers, and the light through their range | Acne, detached or floating shadows, flicker at rest, or shadows that outlive their caster |
|
|
64
|
+
| Camera | Follow the primary subject through movement and transitions | Subject leaves frame, camera clips into geometry, or foreground blocks the play area |
|
|
65
|
+
| Scale and contact | Compare object scale and resting contact against surroundings | Objects float above, sink into, or intersect their support surface, or sit at implausible scale |
|
|
66
|
+
| Image stability | Pan the camera slowly at supported resolutions | Silhouettes, thin geometry, or highlights that crawl, sparkle, or ghost |
|
|
67
|
+
| Resize and DPR | Change viewport size, zoom, and device pixel ratio | Distortion, blur, stretched output, or content leaving the viewport |
|
|
68
|
+
|
|
69
|
+
Each rubric row has a small set of usual code-level causes. Check these first when a row fails:
|
|
70
|
+
|
|
71
|
+
- **Washed-out or too-dark colors**: `renderer.outputColorSpace` not set to `SRGBColorSpace`, color textures missing `texture.colorSpace = SRGBColorSpace`, or a data texture (normal, roughness) wrongly marked sRGB
|
|
72
|
+
- **Z-fighting**: coplanar geometry needing `polygonOffset` or a position nudge, or a near plane set far too small for the scene scale
|
|
73
|
+
- **Shadow acne or floating shadows**: `shadow.bias` and `shadow.normalBias` untuned, or a shadow camera frustum far larger than the scene
|
|
74
|
+
- **Blurry or stretched canvas**: renderer size not synced to canvas CSS size, `setPixelRatio` never called, or a resize handler that forgets `camera.updateProjectionMatrix()`
|
|
75
|
+
- **Black metals**: `metalness: 1` with no `scene.environment` set
|
|
76
|
+
- **Transparency sorting glitches**: large transparent meshes needing `depthWrite: false`, manual `renderOrder`, or a split into smaller meshes
|
|
77
|
+
- **Shimmer and crawl**: missing texture anisotropy, antialiasing disabled, or thin geometry needing thicker forms
|
|
78
|
+
|
|
79
|
+
### Step 5: Fix
|
|
80
|
+
|
|
81
|
+
Fix in severity order: HIGH performance findings and failed visual rows first. When a finding maps to a React Doctor rule, fetch the canonical recipe instead of improvising:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
https://www.react.doctor/prompts/rules/<plugin>/<rule>.md
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For Three.js-specific findings, apply the fix named in the triage list or the cause list above.
|
|
88
|
+
|
|
89
|
+
### Step 6: Validate
|
|
90
|
+
|
|
91
|
+
Run `npx react-doctor@latest --verbose --scope changed` and confirm the score did not regress. Re-check every visual rubric row that failed, using the same viewpoint and interaction as the original evidence, and confirm it now passes. Then verify behavior: the scene renders, animations play, and interactions respond. If browser dev tools are available, watch the memory profile while orbiting an idle scene; a rising heap during idle means a disposal leak survived.
|
|
92
|
+
|
|
93
|
+
## Checks the scanner always misses
|
|
94
|
+
|
|
95
|
+
Review these by hand on every audit:
|
|
96
|
+
|
|
97
|
+
- `dispose()` coverage for every imperatively created GPU resource
|
|
98
|
+
- Allocations and `setState` inside `useFrame` and RAF callbacks
|
|
99
|
+
- Event listeners and `ResizeObserver`s on the canvas or window without cleanup
|
|
100
|
+
- Raycasting against the full scene on every pointer move instead of a filtered target list
|
|
101
|
+
- Shadows or postprocessing enabled globally when one part of the scene needs them
|
|
102
|
+
- Color space configuration on the renderer and every color texture
|
|
@@ -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 layerObservability, Cr as messageFromUnknown, Jn as makeUnsafe, Rn as runPromise, Un as buildWithScope, Xn as void_, Xt as isReactDoctorError, Yt as isProjectDiscoveryError, _ as VERSION, br as isErrnoException, i as isTelemetryEnabled, kn as make, qn as close, z as CliInputError, zn as runSync } from "./record-metric-
|
|
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]="c19cefdf-bbc2-58dd-affd-050e66ca9200")}catch(e){}}();
|
|
3
|
+
import { $t as layerObservability, Cr as messageFromUnknown, Jn as makeUnsafe, Rn as runPromise, Un as buildWithScope, Xn as void_, Xt as isReactDoctorError, Yt as isProjectDiscoveryError, _ as VERSION, br as isErrnoException, i as isTelemetryEnabled, kn as make, qn as close, z as CliInputError, zn as runSync } from "./record-metric-BA5ry-7d.js";
|
|
4
4
|
//#region src/cli/utils/is-environment-error.ts
|
|
5
5
|
const ENVIRONMENT_ERROR_CODES = new Set([
|
|
6
6
|
"EACCES",
|
|
@@ -199,5 +199,5 @@ const shutdownTelemetry = async () => {
|
|
|
199
199
|
//#endregion
|
|
200
200
|
export { isEnvironmentError as a, formatEnvironmentError as i, shutdownTelemetry as n, isExpectedUserError as r, getTelemetryContext as t };
|
|
201
201
|
|
|
202
|
-
//# sourceMappingURL=telemetry-runtime-
|
|
203
|
-
//# debugId=
|
|
202
|
+
//# sourceMappingURL=telemetry-runtime-C9dZxrK_.js.map
|
|
203
|
+
//# debugId=c19cefdf-bbc2-58dd-affd-050e66ca9200
|
|
@@ -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 METRIC, _ as VERSION, t as recordCount } from "./record-metric-
|
|
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]="7a148021-5cee-543a-b507-026fcbc863c7")}catch(e){}}();
|
|
3
|
+
import { T as METRIC, _ as VERSION, t as recordCount } from "./record-metric-BA5ry-7d.js";
|
|
4
4
|
//#region src/cli/commands/version.ts
|
|
5
5
|
/**
|
|
6
6
|
* oclif-style version line. 12-factor CLI Apps (#3, "What version am I
|
|
@@ -17,5 +17,5 @@ const versionAction = () => {
|
|
|
17
17
|
//#endregion
|
|
18
18
|
export { versionAction };
|
|
19
19
|
|
|
20
|
-
//# sourceMappingURL=version-
|
|
21
|
-
//# debugId=
|
|
20
|
+
//# sourceMappingURL=version-yw_bHX_4.js.map
|
|
21
|
+
//# debugId=7a148021-5cee-543a-b507-026fcbc863c7
|
|
@@ -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]="3d4347f7-a963-542b-9084-eef6d11bde9e")}catch(e){}}();
|
|
3
|
+
import { t as inspectAction } from "./inspect-Bz2rayph.js";
|
|
4
4
|
//#region src/cli/commands/why.ts
|
|
5
5
|
/**
|
|
6
6
|
* `why <file:line>` — explains why a rule fired (or why a suppression didn't
|
|
@@ -17,5 +17,5 @@ const whyAction = async (location, options) => {
|
|
|
17
17
|
//#endregion
|
|
18
18
|
export { whyAction };
|
|
19
19
|
|
|
20
|
-
//# sourceMappingURL=why-
|
|
21
|
-
//# debugId=
|
|
20
|
+
//# sourceMappingURL=why-CdGev87Z.js.map
|
|
21
|
+
//# debugId=3d4347f7-a963-542b-9084-eef6d11bde9e
|
|
@@ -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 { D as NANOSECONDS_PER_MILLISECOND, In as provideContext, Xn as void_, Yn as fail, c as setSentryProjectInfo, jn as makeSpan, o as buildSentryScope, r as toSpanAttributes, s as buildSentryProjectContext, zn as runSync } from "./record-metric-
|
|
4
|
-
import { t as getTelemetryContext } from "./telemetry-runtime-
|
|
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]="26a0c8a5-47f3-5072-a5a2-98fb13897b6c")}catch(e){}}();
|
|
3
|
+
import { D as NANOSECONDS_PER_MILLISECOND, In as provideContext, Xn as void_, Yn as fail, c as setSentryProjectInfo, jn as makeSpan, o as buildSentryScope, r as toSpanAttributes, s as buildSentryProjectContext, zn as runSync } from "./record-metric-BA5ry-7d.js";
|
|
4
|
+
import { t as getTelemetryContext } from "./telemetry-runtime-C9dZxrK_.js";
|
|
5
5
|
import { i as setActiveRunTrace, r as recordRunTraceId } from "./active-run-trace-dlIZeEvb.js";
|
|
6
6
|
//#region src/cli/utils/with-run-span.ts
|
|
7
7
|
/**
|
|
@@ -106,5 +106,5 @@ const recordSentryProjectContext = (projectInfo, rootSpan, options = {}) => {
|
|
|
106
106
|
//#endregion
|
|
107
107
|
export { resetSentryRunState as n, withRunSpan as r, recordSentryProjectContext as t };
|
|
108
108
|
|
|
109
|
-
//# sourceMappingURL=with-run-span-
|
|
110
|
-
//# debugId=
|
|
109
|
+
//# sourceMappingURL=with-run-span-CCVNobt7.js.map
|
|
110
|
+
//# debugId=26a0c8a5-47f3-5072-a5a2-98fb13897b6c
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.9.12-dev.
|
|
3
|
+
"version": "0.9.12-dev.1d3e4a6",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -57,17 +57,18 @@
|
|
|
57
57
|
"conf": "^15.1.0",
|
|
58
58
|
"confbox": "^0.2.4",
|
|
59
59
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
60
|
+
"is-unicode-supported": "^2.1.0",
|
|
60
61
|
"jiti": "^2.7.0",
|
|
61
62
|
"magicast": "^0.5.3",
|
|
62
|
-
"oxc-parser": "^0.
|
|
63
|
+
"oxc-parser": "^0.146.0",
|
|
63
64
|
"oxc-resolver": "^11.24.2",
|
|
64
|
-
"oxlint": ">=1.
|
|
65
|
+
"oxlint": ">=1.79.0 <1.80.0",
|
|
65
66
|
"playwright-core": "^1.62.1",
|
|
66
67
|
"prompts": "^2.4.2",
|
|
67
68
|
"typescript": ">=5.0.4 <6",
|
|
68
69
|
"yaml": "^2.9.0",
|
|
69
70
|
"yoga-layout": "~3.2.1",
|
|
70
|
-
"oxlint-plugin-react-doctor": "0.9.12-dev.
|
|
71
|
+
"oxlint-plugin-react-doctor": "0.9.12-dev.1d3e4a6"
|
|
71
72
|
},
|
|
72
73
|
"devDependencies": {
|
|
73
74
|
"@types/babel__code-frame": "^7.27.0",
|