react-doctor 0.5.8-dev.9f28454 → 0.5.8-dev.ea00b1b
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/LICENSE +1 -8
- package/dist/cli.js +169 -147
- package/dist/index.js +50 -96
- package/dist/lsp.js +51 -36
- package/package.json +6 -6
package/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
MIT License
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 Million Software, Inc.
|
|
4
4
|
|
|
@@ -12,13 +12,6 @@ furnished to do so, subject to the following conditions:
|
|
|
12
12
|
The above copyright notice and this permission notice shall be included in all
|
|
13
13
|
copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
|
-
The Software, its source code, and any derivative works thereof may not be
|
|
16
|
-
used, in whole or in part, as training data, fine-tuning data, evaluation
|
|
17
|
-
data, or as input to any automated pipeline for the purpose of training or
|
|
18
|
-
improving any machine learning model or AI system, without prior written
|
|
19
|
-
permission from the copyright holder. To request permission, contact
|
|
20
|
-
founders@million.dev.
|
|
21
|
-
|
|
22
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
16
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
17
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7e6ea254-9fcd-5076-8bd6-01ad63633c24")}catch(e){}}();
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import * as NodeChildProcess from "node:child_process";
|
|
5
5
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
@@ -26,7 +26,7 @@ import tty from "node:tty";
|
|
|
26
26
|
import { codeFrameColumns } from "@babel/code-frame";
|
|
27
27
|
import Conf from "conf";
|
|
28
28
|
import basePrompts from "prompts";
|
|
29
|
-
import { SKILL_MANIFEST_FILE, detectInstalledSkillAgents, getSkillAgentConfig, getSkillAgentTypes, installSkillsFromSource } from "agent-install";
|
|
29
|
+
import { SKILL_MANIFEST_FILE, detectInstalledSkillAgents, getSkillAgentConfig, getSkillAgentTypes, installSkillsFromSource, isSkillAgentType } from "agent-install";
|
|
30
30
|
import { generateCode, loadFile, writeFile } from "magicast";
|
|
31
31
|
import { getConfigFromVariableDeclaration, getDefaultExportOptions } from "magicast/helpers";
|
|
32
32
|
//#region \0rolldown/runtime.js
|
|
@@ -36862,6 +36862,7 @@ const DOCS_URL = "https://react.doctor/docs";
|
|
|
36862
36862
|
const DOCS_RULES_BASE_URL = `${DOCS_URL}/rules`;
|
|
36863
36863
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
36864
36864
|
const GITHUB_VIEWER_PERMISSION_TIMEOUT_MS = 2e3;
|
|
36865
|
+
const SPAWN_ARGS_MAX_LENGTH_CHARS = 24e3;
|
|
36865
36866
|
const PER_WORKER_MEM_BUDGET_BYTES = 1024 * 1024 * 1024;
|
|
36866
36867
|
const DEFAULT_BRANCH_CANDIDATES = ["main", "master"];
|
|
36867
36868
|
const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
|
|
@@ -37679,7 +37680,10 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
|
|
|
37679
37680
|
NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.set(nativeRuleKey, aliases);
|
|
37680
37681
|
}
|
|
37681
37682
|
const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
|
|
37682
|
-
const canonicalizeRuleKey = (ruleKey) =>
|
|
37683
|
+
const canonicalizeRuleKey = (ruleKey) => {
|
|
37684
|
+
const nativeRuleKey = LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey];
|
|
37685
|
+
return typeof nativeRuleKey === "string" ? nativeRuleKey : ruleKey;
|
|
37686
|
+
};
|
|
37683
37687
|
const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
|
|
37684
37688
|
const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
|
|
37685
37689
|
const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
|
|
@@ -38765,6 +38769,12 @@ const BOOLEAN_FIELD_NAMES = [
|
|
|
38765
38769
|
"adoptExistingLintConfig"
|
|
38766
38770
|
];
|
|
38767
38771
|
const STRING_FIELD_NAMES = ["rootDir"];
|
|
38772
|
+
const STRING_ARRAY_FIELD_NAMES = [
|
|
38773
|
+
"projects",
|
|
38774
|
+
"textComponents",
|
|
38775
|
+
"rawTextWrapperComponents",
|
|
38776
|
+
"serverAuthFunctionNames"
|
|
38777
|
+
];
|
|
38768
38778
|
const SURFACE_CONTROL_FIELD_NAMES = [
|
|
38769
38779
|
"includeTags",
|
|
38770
38780
|
"excludeTags",
|
|
@@ -38866,6 +38876,7 @@ const validateConfigTypes = (config) => {
|
|
|
38866
38876
|
const validated = { ...config };
|
|
38867
38877
|
for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
|
|
38868
38878
|
for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
|
|
38879
|
+
for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
|
|
38869
38880
|
applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
|
|
38870
38881
|
for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
|
|
38871
38882
|
applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
|
|
@@ -41094,43 +41105,46 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
41094
41105
|
* reason: GitInvocationFailed })` so the rest of the codebase
|
|
41095
41106
|
* sees a single failure channel.
|
|
41096
41107
|
*/
|
|
41097
|
-
const runCommand = (input) =>
|
|
41098
|
-
const
|
|
41099
|
-
cwd: input.directory,
|
|
41100
|
-
env: input.env,
|
|
41101
|
-
extendEnv: true
|
|
41102
|
-
}));
|
|
41103
|
-
const maxStdoutBytes = input.maxStdoutBytes;
|
|
41104
|
-
const stdoutByteCount = yield* make$13(0);
|
|
41105
|
-
const [stdout, stderr, status] = yield* all([
|
|
41106
|
-
mkString(decodeText(maxStdoutBytes === void 0 ? handle.stdout : handle.stdout.pipe(tap((chunk) => updateAndGet(stdoutByteCount, (total) => total + chunk.length).pipe(flatMap$2((total) => total > maxStdoutBytes ? fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
41107
|
-
args: [...input.args],
|
|
41108
|
-
directory: input.directory,
|
|
41109
|
-
cause: /* @__PURE__ */ new Error(`git stdout exceeded ${maxStdoutBytes} bytes`)
|
|
41110
|
-
}) })) : void_)))))),
|
|
41111
|
-
mkString(decodeText(handle.stderr)),
|
|
41112
|
-
handle.exitCode
|
|
41113
|
-
], { concurrency: 3 });
|
|
41114
|
-
return {
|
|
41115
|
-
status,
|
|
41116
|
-
stdout,
|
|
41117
|
-
stderr
|
|
41118
|
-
};
|
|
41119
|
-
})).pipe(catchTag$1("PlatformError", (cause) => {
|
|
41120
|
-
if (input.command !== "git") return succeed$2({
|
|
41108
|
+
const runCommand = (input) => {
|
|
41109
|
+
const foldSpawnFailure = (cause) => input.command !== "git" ? succeed$2({
|
|
41121
41110
|
status: 127,
|
|
41122
41111
|
stdout: "",
|
|
41123
41112
|
stderr: String(cause)
|
|
41124
|
-
})
|
|
41125
|
-
return new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
41113
|
+
}) : fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
41126
41114
|
args: [...input.args],
|
|
41127
41115
|
directory: input.directory,
|
|
41128
41116
|
cause
|
|
41129
|
-
}) });
|
|
41130
|
-
|
|
41131
|
-
|
|
41132
|
-
|
|
41133
|
-
|
|
41117
|
+
}) }));
|
|
41118
|
+
return scoped(gen(function* () {
|
|
41119
|
+
if (!isDirectory(input.directory)) return yield* foldSpawnFailure(`spawn ENOTDIR (cwd is not a directory: ${input.directory})`);
|
|
41120
|
+
const argvLengthChars = input.command.length + 1 + input.args.reduce((total, arg) => total + arg.length + 1, 0);
|
|
41121
|
+
if (argvLengthChars > 24e3) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${SPAWN_ARGS_MAX_LENGTH_CHARS})`);
|
|
41122
|
+
const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
|
|
41123
|
+
cwd: input.directory,
|
|
41124
|
+
env: input.env,
|
|
41125
|
+
extendEnv: true
|
|
41126
|
+
}));
|
|
41127
|
+
const maxStdoutBytes = input.maxStdoutBytes;
|
|
41128
|
+
const stdoutByteCount = yield* make$13(0);
|
|
41129
|
+
const [stdout, stderr, status] = yield* all([
|
|
41130
|
+
mkString(decodeText(maxStdoutBytes === void 0 ? handle.stdout : handle.stdout.pipe(tap((chunk) => updateAndGet(stdoutByteCount, (total) => total + chunk.length).pipe(flatMap$2((total) => total > maxStdoutBytes ? fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
41131
|
+
args: [...input.args],
|
|
41132
|
+
directory: input.directory,
|
|
41133
|
+
cause: /* @__PURE__ */ new Error(`git stdout exceeded ${maxStdoutBytes} bytes`)
|
|
41134
|
+
}) })) : void_)))))),
|
|
41135
|
+
mkString(decodeText(handle.stderr)),
|
|
41136
|
+
handle.exitCode
|
|
41137
|
+
], { concurrency: 3 });
|
|
41138
|
+
return {
|
|
41139
|
+
status,
|
|
41140
|
+
stdout,
|
|
41141
|
+
stderr
|
|
41142
|
+
};
|
|
41143
|
+
})).pipe(catchTag$1("PlatformError", foldSpawnFailure), withSpan("git.exec", { attributes: {
|
|
41144
|
+
"git.command": input.command,
|
|
41145
|
+
"git.subcommand": input.args[0] ?? ""
|
|
41146
|
+
} }));
|
|
41147
|
+
};
|
|
41134
41148
|
const runGit = (directory, args) => runCommand({
|
|
41135
41149
|
command: "git",
|
|
41136
41150
|
args,
|
|
@@ -41163,7 +41177,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
41163
41177
|
"rev-parse",
|
|
41164
41178
|
"--verify",
|
|
41165
41179
|
branch
|
|
41166
|
-
]).pipe(map$3((result) => result.status === 0));
|
|
41180
|
+
]).pipe(map$3((result) => result.status === 0), catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(false) : fail$4(error)));
|
|
41167
41181
|
const headSha = (directory) => runGit(directory, ["rev-parse", "HEAD"]).pipe(map$3((result) => result.status === 0 ? trimOrNull(result.stdout) : null));
|
|
41168
41182
|
const mergeBase = (input) => isSafeGitRevision(input.ref) ? runGit(input.directory, [
|
|
41169
41183
|
"merge-base",
|
|
@@ -41377,7 +41391,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
41377
41391
|
]);
|
|
41378
41392
|
if (result.status !== 0) return null;
|
|
41379
41393
|
return parseChangedLineRanges(result.stdout);
|
|
41380
|
-
}).pipe(withSpan("Git.changedLineRanges"))
|
|
41394
|
+
}).pipe(catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(null) : fail$4(error)), withSpan("Git.changedLineRanges"))
|
|
41381
41395
|
});
|
|
41382
41396
|
})).pipe(provide$2(layer$3.pipe(provide$2(mergeAll$1(layer$2, layer$1)))));
|
|
41383
41397
|
/**
|
|
@@ -44702,25 +44716,7 @@ const CI_PROVIDER_BY_ENVIRONMENT_VARIABLE = [
|
|
|
44702
44716
|
["TEAMCITY_VERSION", "teamcity"],
|
|
44703
44717
|
["BITBUCKET_BUILD_NUMBER", "bitbucket"],
|
|
44704
44718
|
["TRAVIS", "travis"],
|
|
44705
|
-
["DRONE", "drone"]
|
|
44706
|
-
["SEMAPHORE", "semaphore"],
|
|
44707
|
-
["APPVEYOR", "appveyor"],
|
|
44708
|
-
["HARNESS_BUILD_ID", "harness"],
|
|
44709
|
-
["BUDDY", "buddy"],
|
|
44710
|
-
["CF_BUILD_ID", "codefresh"],
|
|
44711
|
-
["NETLIFY", "netlify"],
|
|
44712
|
-
["RAILWAY_SERVICE_ID", "railway"],
|
|
44713
|
-
["VERCEL", "vercel"],
|
|
44714
|
-
["CM_BUILD_ID", "codemagic"],
|
|
44715
|
-
["PROW_JOB_ID", "prow"],
|
|
44716
|
-
["AGOLA_GIT_REF", "agola"],
|
|
44717
|
-
["CIRRUS_CI", "cirrus-ci"],
|
|
44718
|
-
["BLACKSMITH_STICKYDISK_TOKEN", "blacksmith"],
|
|
44719
|
-
["WARPBUILD_RUNNER_VERIFICATION_TOKEN", "warpbuild"],
|
|
44720
|
-
["NSC_CACHE_PATH", "namespace"],
|
|
44721
|
-
["UBICLOUD_CACHE_URL", "ubicloud"],
|
|
44722
|
-
["RENDER", "render"],
|
|
44723
|
-
["FLY_APP_NAME", "fly-io"]
|
|
44719
|
+
["DRONE", "drone"]
|
|
44724
44720
|
];
|
|
44725
44721
|
const GITHUB_ACTION_MARKER_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_GITHUB_ACTION";
|
|
44726
44722
|
const ACTION_INPUT_ENVIRONMENT_VARIABLES = {
|
|
@@ -44738,10 +44734,7 @@ const CODING_AGENT_BY_ENVIRONMENT_VARIABLE = [
|
|
|
44738
44734
|
["CODEX_SANDBOX_NETWORK_DISABLED", "codex"],
|
|
44739
44735
|
["OPENCODE", "opencode"],
|
|
44740
44736
|
["GOOSE_TERMINAL", "goose"],
|
|
44741
|
-
["AMP_THREAD_ID", "amp"]
|
|
44742
|
-
["CLINE_ACTIVE", "cline"],
|
|
44743
|
-
["AUGMENT_AGENT", "augment"],
|
|
44744
|
-
["TRAE_AI_SHELL_ID", "trae-ai"]
|
|
44737
|
+
["AMP_THREAD_ID", "amp"]
|
|
44745
44738
|
];
|
|
44746
44739
|
const GENERIC_CODING_AGENT_ENVIRONMENT_VARIABLES = ["AGENT_SESSION_ID", "AGENT_THREAD_ID"];
|
|
44747
44740
|
const CODING_AGENT_ENVIRONMENT_VALUE_VARIABLES = ["AGENT"];
|
|
@@ -44860,6 +44853,7 @@ const NANOSECONDS_PER_SECOND = 1000000000n;
|
|
|
44860
44853
|
const METRIC = {
|
|
44861
44854
|
cliInvoked: "cli.invoked",
|
|
44862
44855
|
cliError: "cli.error",
|
|
44856
|
+
cliEnvironmentError: "cli.env_error",
|
|
44863
44857
|
projectDetected: "project.detected",
|
|
44864
44858
|
projectPathSelected: "project.path_selected",
|
|
44865
44859
|
projectConfigSelected: "project.config_selected",
|
|
@@ -44932,7 +44926,7 @@ const makeNoopConsole = () => ({
|
|
|
44932
44926
|
});
|
|
44933
44927
|
//#endregion
|
|
44934
44928
|
//#region src/cli/utils/version.ts
|
|
44935
|
-
const VERSION = "0.5.8-dev.
|
|
44929
|
+
const VERSION = "0.5.8-dev.ea00b1b";
|
|
44936
44930
|
//#endregion
|
|
44937
44931
|
//#region src/cli/utils/json-mode.ts
|
|
44938
44932
|
let context = null;
|
|
@@ -45296,13 +45290,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
45296
45290
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
45297
45291
|
* standard `SENTRY_RELEASE` override.
|
|
45298
45292
|
*/
|
|
45299
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.5.8-dev.
|
|
45293
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.5.8-dev.ea00b1b`;
|
|
45300
45294
|
/**
|
|
45301
45295
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
45302
45296
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
45303
45297
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
45304
45298
|
*/
|
|
45305
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.5.8-dev.
|
|
45299
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.5.8-dev.ea00b1b") ? "development" : "production");
|
|
45306
45300
|
/**
|
|
45307
45301
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
45308
45302
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -49711,6 +49705,7 @@ const CI_PITCH_EVENT = "ci-pitch";
|
|
|
49711
49705
|
const ACTION_UPGRADE_EVENT = "action-upgrade-v2";
|
|
49712
49706
|
const SETUP_HINT_EVENT = "setup-hint";
|
|
49713
49707
|
const HANDOFF_TARGET_PREFERENCE_ID = "handoff-target";
|
|
49708
|
+
const INSTALL_AGENTS_PREFERENCE_ID = "install-agents";
|
|
49714
49709
|
const foldLegacyDecisions = (projects, legacy, eventId) => {
|
|
49715
49710
|
for (const [hash, record] of Object.entries(legacy ?? {})) {
|
|
49716
49711
|
const existing = projects[hash] ?? { rootDirectory: record.rootDirectory ?? "" };
|
|
@@ -50374,7 +50369,7 @@ const readPackageJson = (projectRoot) => {
|
|
|
50374
50369
|
return null;
|
|
50375
50370
|
}
|
|
50376
50371
|
};
|
|
50377
|
-
const writeJsonFile
|
|
50372
|
+
const writeJsonFile = (filePath, value) => {
|
|
50378
50373
|
NFS.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
50379
50374
|
};
|
|
50380
50375
|
const packageHasDependency = (projectRoot, dependencyName) => {
|
|
@@ -51113,6 +51108,35 @@ const materializeStagedFiles = async (directory, stagedFiles, tempDirectory) =>
|
|
|
51113
51108
|
};
|
|
51114
51109
|
};
|
|
51115
51110
|
//#endregion
|
|
51111
|
+
//#region src/cli/utils/is-environment-error.ts
|
|
51112
|
+
const isNodeSystemError = (error) => error instanceof Error && typeof error.code === "string";
|
|
51113
|
+
const ENVIRONMENT_ERROR_CODES = new Set([
|
|
51114
|
+
"ENOSPC",
|
|
51115
|
+
"EIO",
|
|
51116
|
+
"EROFS",
|
|
51117
|
+
"EACCES",
|
|
51118
|
+
"EPERM",
|
|
51119
|
+
"ENOTDIR"
|
|
51120
|
+
]);
|
|
51121
|
+
const isEnvironmentError = (error) => {
|
|
51122
|
+
if (!isNodeSystemError(error)) return false;
|
|
51123
|
+
if (error.code === "ENOENT") return error.syscall?.startsWith("spawn") ?? false;
|
|
51124
|
+
return error.code !== void 0 && ENVIRONMENT_ERROR_CODES.has(error.code);
|
|
51125
|
+
};
|
|
51126
|
+
const formatEnvironmentError = (error) => {
|
|
51127
|
+
if (!isNodeSystemError(error)) return error instanceof Error ? error.message : String(error);
|
|
51128
|
+
switch (error.code) {
|
|
51129
|
+
case "ENOSPC": return "No space left on device. Free up disk space and try again.";
|
|
51130
|
+
case "EIO": return "I/O error: the filesystem or disk may be failing. Check your system logs.";
|
|
51131
|
+
case "EROFS": return "Read-only filesystem: cannot write to this location.";
|
|
51132
|
+
case "EACCES":
|
|
51133
|
+
case "EPERM": return error.path ? `Permission denied accessing ${error.path}. Check file permissions and try again.` : "Permission denied. Check file permissions and try again.";
|
|
51134
|
+
case "ENOTDIR": return error.path ? `A file exists at ${error.path} or one of its parent paths where a directory was expected.` : "A file exists where a directory was expected.";
|
|
51135
|
+
case "ENOENT": return "Required command not found. Ensure the tool (e.g. git) is installed and on your PATH.";
|
|
51136
|
+
default: return error.message;
|
|
51137
|
+
}
|
|
51138
|
+
};
|
|
51139
|
+
//#endregion
|
|
51116
51140
|
//#region src/cli/utils/handle-error.ts
|
|
51117
51141
|
const OTLP_ENDPOINT_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_ENDPOINT";
|
|
51118
51142
|
const OTLP_AUTH_HEADER_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_AUTH_HEADER";
|
|
@@ -51195,15 +51219,19 @@ const handleError = (error, options = {}) => {
|
|
|
51195
51219
|
process.exitCode = 1;
|
|
51196
51220
|
};
|
|
51197
51221
|
/**
|
|
51198
|
-
* Renderer for expected, user-actionable failures — a bad `--diff` value
|
|
51199
|
-
* a base branch that isn't fetched
|
|
51200
|
-
*
|
|
51201
|
-
*
|
|
51222
|
+
* Renderer for expected, user-actionable failures — a bad `--diff` value,
|
|
51223
|
+
* a base branch that isn't fetched, or environment errors like disk-full or
|
|
51224
|
+
* permission-denied. Prints just the (already human-readable) message — no
|
|
51225
|
+
* "Something went wrong", prefilled issue, Discord link, or Sentry reference
|
|
51226
|
+
* — because there is no bug to report.
|
|
51202
51227
|
*/
|
|
51203
51228
|
const handleUserError = (error, options = {}) => {
|
|
51229
|
+
const isEnvError = isEnvironmentError(error);
|
|
51230
|
+
if (isEnvError) recordCount(METRIC.cliEnvironmentError, 1, { code: error.code ?? "unknown" });
|
|
51231
|
+
const message = isEnvError ? formatEnvironmentError(error) : formatErrorForReport(error);
|
|
51204
51232
|
runSync(gen(function* () {
|
|
51205
51233
|
yield* error$1("");
|
|
51206
|
-
yield* error$1(highlighter.error(
|
|
51234
|
+
yield* error$1(highlighter.error(message));
|
|
51207
51235
|
yield* error$1("");
|
|
51208
51236
|
}));
|
|
51209
51237
|
if (options.shouldExit !== false) process.exit(1);
|
|
@@ -51218,7 +51246,7 @@ const handleUserError = (error, options = {}) => {
|
|
|
51218
51246
|
* `handleUserError` (a plain message — no "Something went wrong", prefilled
|
|
51219
51247
|
* issue, Discord link, or Sentry reference), since there is no bug to report.
|
|
51220
51248
|
*
|
|
51221
|
-
*
|
|
51249
|
+
* Four distinct shapes reach the CLI's catch blocks:
|
|
51222
51250
|
*
|
|
51223
51251
|
* - **Project-discovery failures** (`NoReactDependencyError`,
|
|
51224
51252
|
* `ProjectNotFoundError`, `PackageJsonNotFoundError`, `NotADirectoryError`,
|
|
@@ -51231,12 +51259,19 @@ const handleUserError = (error, options = {}) => {
|
|
|
51231
51259
|
* `--project` name.
|
|
51232
51260
|
* - **Bad `--diff` input** (`GitBaseBranchInvalid` / `GitBaseBranchMissing`)
|
|
51233
51261
|
* stays the tagged `ReactDoctorError`, so dispatch on the reason `_tag`.
|
|
51262
|
+
* - **Environment failures** (`ENOSPC`, `EIO`, `EROFS`, `EACCES`, `EPERM`,
|
|
51263
|
+
* `ENOTDIR`, plus a `spawn`-scoped `ENOENT` for a missing binary) — disk
|
|
51264
|
+
* full / failing / read-only, permission denied, or a path blocked by a
|
|
51265
|
+
* file. React Doctor cannot fix the user's environment; exit cleanly with an
|
|
51266
|
+
* actionable message instead of crashing. See `is-environment-error.ts` for
|
|
51267
|
+
* why the set stays narrow (codes that usually mean our bug keep reaching
|
|
51268
|
+
* Sentry).
|
|
51234
51269
|
*
|
|
51235
51270
|
* This composes the existing core narrowers rather than introducing a new
|
|
51236
51271
|
* error-shape helper (AGENTS.md): it encodes CLI-layer reporting policy, not
|
|
51237
51272
|
* knowledge of the `ReactDoctorError` shape.
|
|
51238
51273
|
*/
|
|
51239
|
-
const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
|
|
51274
|
+
const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isEnvironmentError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
|
|
51240
51275
|
//#endregion
|
|
51241
51276
|
//#region src/cli/utils/build-handoff-payload.ts
|
|
51242
51277
|
const buildHandoffPayload = (input) => {
|
|
@@ -51317,6 +51352,20 @@ const detectAvailableAgents = async () => {
|
|
|
51317
51352
|
const detected = new Set([...detectPathAvailableAgents(), ...await detectInstalledSkillAgents()]);
|
|
51318
51353
|
return getSkillAgentTypes().filter((agent) => agent !== "universal" && detected.has(agent));
|
|
51319
51354
|
};
|
|
51355
|
+
const DEFAULT_INSTALL_AGENTS = [
|
|
51356
|
+
"claude-code",
|
|
51357
|
+
"cursor",
|
|
51358
|
+
"codex",
|
|
51359
|
+
"opencode"
|
|
51360
|
+
];
|
|
51361
|
+
const computeDefaultSelectedAgents = (detectedAgents, rememberedAgents) => {
|
|
51362
|
+
const detected = new Set(detectedAgents);
|
|
51363
|
+
const remembered = rememberedAgents.filter((agent) => detected.has(agent));
|
|
51364
|
+
if (remembered.length > 0) return remembered;
|
|
51365
|
+
const defaults = DEFAULT_INSTALL_AGENTS.filter((agent) => detected.has(agent));
|
|
51366
|
+
if (defaults.length > 0) return defaults;
|
|
51367
|
+
return detectedAgents.length === 1 ? [...detectedAgents] : [];
|
|
51368
|
+
};
|
|
51320
51369
|
//#endregion
|
|
51321
51370
|
//#region src/cli/utils/install-doctor-script.ts
|
|
51322
51371
|
const DOCTOR_SCRIPT_NAME = "doctor";
|
|
@@ -51398,7 +51447,7 @@ const installDoctorScript = (options) => {
|
|
|
51398
51447
|
};
|
|
51399
51448
|
})();
|
|
51400
51449
|
const scriptStatus = scriptTarget.status;
|
|
51401
|
-
if (scriptStatus === "created") writeJsonFile
|
|
51450
|
+
if (scriptStatus === "created") writeJsonFile(packageJsonPath, {
|
|
51402
51451
|
...packageJson,
|
|
51403
51452
|
scripts: {
|
|
51404
51453
|
...isRecord$1(scripts) ? scripts : {},
|
|
@@ -51969,6 +52018,19 @@ const setUpGitHubActions = async (options) => {
|
|
|
51969
52018
|
return didCreateWorkflow;
|
|
51970
52019
|
};
|
|
51971
52020
|
//#endregion
|
|
52021
|
+
//#region src/cli/utils/install-agents-preference.ts
|
|
52022
|
+
const INSTALL_AGENTS_PREFERENCE = {
|
|
52023
|
+
id: INSTALL_AGENTS_PREFERENCE_ID,
|
|
52024
|
+
scope: "global"
|
|
52025
|
+
};
|
|
52026
|
+
const PREFERENCE_SEPARATOR = ",";
|
|
52027
|
+
const readInstallAgents = (options = {}) => {
|
|
52028
|
+
const stored = readPreference(INSTALL_AGENTS_PREFERENCE, {}, options);
|
|
52029
|
+
if (stored === null) return [];
|
|
52030
|
+
return stored.split(PREFERENCE_SEPARATOR).map((entry) => entry.trim()).filter((entry) => isSkillAgentType(entry));
|
|
52031
|
+
};
|
|
52032
|
+
const rememberInstallAgents = (agents, options = {}) => writePreference(INSTALL_AGENTS_PREFERENCE, agents.join(PREFERENCE_SEPARATOR), {}, options);
|
|
52033
|
+
//#endregion
|
|
51972
52034
|
//#region src/cli/utils/install-agent-hooks.ts
|
|
51973
52035
|
const CLAUDE_AGENT = "claude-code";
|
|
51974
52036
|
const CURSOR_AGENT = "cursor";
|
|
@@ -51979,20 +52041,34 @@ const CURSOR_HOOKS_RELATIVE_PATH = ".cursor/hooks.json";
|
|
|
51979
52041
|
const CURSOR_HOOK_RELATIVE_PATH = ".cursor/hooks/react-doctor.sh";
|
|
51980
52042
|
const CURSOR_HOOK_MATCHER = "Write|Edit|MultiEdit|ApplyPatch";
|
|
51981
52043
|
const CURSOR_HOOKS_SCHEMA_VERSION = 1;
|
|
51982
|
-
const JSON_INDENT_SPACES$1 = 2;
|
|
51983
52044
|
const isSupportedAgent = (agent) => agent === CLAUDE_AGENT || agent === CURSOR_AGENT;
|
|
51984
52045
|
const readJsonFile = (filePath, fallback) => {
|
|
51985
52046
|
if (!NFS.existsSync(filePath)) return fallback;
|
|
51986
52047
|
const content = NFS.readFileSync(filePath, "utf8").trim();
|
|
51987
52048
|
if (content.length === 0) return fallback;
|
|
51988
|
-
|
|
52049
|
+
try {
|
|
52050
|
+
return JSON.parse(content);
|
|
52051
|
+
} catch (error) {
|
|
52052
|
+
if (error instanceof SyntaxError) throw new CliInputError(`Could not parse ${filePath}: the file contains invalid JSON. Fix the syntax errors in this file and re-run the install command.`);
|
|
52053
|
+
throw error;
|
|
52054
|
+
}
|
|
51989
52055
|
};
|
|
51990
|
-
const
|
|
51991
|
-
|
|
51992
|
-
|
|
52056
|
+
const ensureDirectoryExists = (directoryPath) => {
|
|
52057
|
+
try {
|
|
52058
|
+
NFS.mkdirSync(directoryPath, { recursive: true });
|
|
52059
|
+
} catch (error) {
|
|
52060
|
+
const code = error.code;
|
|
52061
|
+
if (code === "EACCES" || code === "EPERM") throw new CliInputError(`Could not create directory ${directoryPath}: permission denied. Ensure you have write permissions for this location and re-run the install command.`);
|
|
52062
|
+
if (code === "ENOTDIR" || code === "EEXIST") throw new CliInputError(`Could not create directory ${directoryPath}: a file exists at this path or one of its parent paths. Remove the conflicting file and re-run the install command.`);
|
|
52063
|
+
throw error;
|
|
52064
|
+
}
|
|
52065
|
+
};
|
|
52066
|
+
const writeJsonFileWithDirectoryCheck = (filePath, value) => {
|
|
52067
|
+
ensureDirectoryExists(Path.dirname(filePath));
|
|
52068
|
+
writeJsonFile(filePath, value);
|
|
51993
52069
|
};
|
|
51994
52070
|
const writeHookScript = (filePath) => {
|
|
51995
|
-
|
|
52071
|
+
ensureDirectoryExists(Path.dirname(filePath));
|
|
51996
52072
|
NFS.writeFileSync(filePath, buildAgentHookScript());
|
|
51997
52073
|
NFS.chmodSync(filePath, 493);
|
|
51998
52074
|
};
|
|
@@ -52008,7 +52084,7 @@ const installClaudeHook = (projectRoot) => {
|
|
|
52008
52084
|
command: CLAUDE_HOOK_COMMAND
|
|
52009
52085
|
}] });
|
|
52010
52086
|
hooks.PostToolBatch = postToolBatchHooks;
|
|
52011
|
-
|
|
52087
|
+
writeJsonFileWithDirectoryCheck(settingsPath, {
|
|
52012
52088
|
...settings,
|
|
52013
52089
|
hooks
|
|
52014
52090
|
});
|
|
@@ -52028,7 +52104,7 @@ const installCursorHook = (projectRoot) => {
|
|
|
52028
52104
|
timeout: 120
|
|
52029
52105
|
});
|
|
52030
52106
|
hooks.postToolUse = postToolUseHooks;
|
|
52031
|
-
|
|
52107
|
+
writeJsonFileWithDirectoryCheck(configPath, {
|
|
52032
52108
|
...config,
|
|
52033
52109
|
version: config.version ?? CURSOR_HOOKS_SCHEMA_VERSION,
|
|
52034
52110
|
hooks
|
|
@@ -52264,7 +52340,7 @@ const installPackageJsonHook = (options, strategy) => {
|
|
|
52264
52340
|
parent = cloned;
|
|
52265
52341
|
}
|
|
52266
52342
|
parent[leafKey] = strategy.leafShape === "array" ? appendArrayCommand(parent[leafKey]) : appendStringCommand(parent[leafKey]);
|
|
52267
|
-
writeJsonFile
|
|
52343
|
+
writeJsonFile(packageJsonPath, nextPackageJson);
|
|
52268
52344
|
removeLegacyManagedRunner(options.projectRoot);
|
|
52269
52345
|
return {
|
|
52270
52346
|
hookPath: packageJsonPath,
|
|
@@ -52847,6 +52923,9 @@ const runInstallReactDoctor = async (options = {}) => {
|
|
|
52847
52923
|
const shouldUpgradeWorkflow = canUpgradeWorkflow && (Boolean(options.yes) || upgradePromptOutcome === "yes");
|
|
52848
52924
|
if (upgradePromptOutcome === "no" && !options.dryRun) recordActionUpgradeDecision(projectRoot, "declined");
|
|
52849
52925
|
if ((ciPromptOutcome === "yes" || ciPromptOutcome === "no") && !options.dryRun) recordCiPromptDecision(projectRoot, ciPromptOutcome === "yes" ? "accepted" : "declined");
|
|
52926
|
+
const rememberedAgents = options.lastSelectedAgents ?? readInstallAgents();
|
|
52927
|
+
const defaultSelectedAgents = computeDefaultSelectedAgents(detectedAgents, rememberedAgents);
|
|
52928
|
+
const usedRememberedAgents = rememberedAgents.some((agent) => detectedAgents.includes(agent));
|
|
52850
52929
|
const selectedAgents = skipPrompts ? detectedAgents : (await prompt({
|
|
52851
52930
|
type: "multiselect",
|
|
52852
52931
|
name: "agents",
|
|
@@ -52854,12 +52933,13 @@ const runInstallReactDoctor = async (options = {}) => {
|
|
|
52854
52933
|
choices: detectedAgents.map((agent) => ({
|
|
52855
52934
|
title: getSkillAgentConfig(agent).displayName,
|
|
52856
52935
|
value: agent,
|
|
52857
|
-
selected:
|
|
52936
|
+
selected: defaultSelectedAgents.includes(agent)
|
|
52858
52937
|
})),
|
|
52859
52938
|
instructions: false,
|
|
52860
52939
|
min: 1
|
|
52861
52940
|
}, promptOptions)).agents ?? [];
|
|
52862
52941
|
if (selectedAgents.length === 0) return;
|
|
52942
|
+
if (!skipPrompts && !options.dryRun) rememberInstallAgents(selectedAgents);
|
|
52863
52943
|
let dependencyResult;
|
|
52864
52944
|
if (!options.dryRun) {
|
|
52865
52945
|
await installReactDoctorSkillStep(sourceDir, selectedAgents, projectRoot);
|
|
@@ -52918,6 +52998,8 @@ const runInstallReactDoctor = async (options = {}) => {
|
|
|
52918
52998
|
}
|
|
52919
52999
|
recordCount(METRIC.installCompleted, 1, {
|
|
52920
53000
|
agentsCount: selectedAgents.length,
|
|
53001
|
+
agentsDetected: detectedAgents.length,
|
|
53002
|
+
usedRememberedAgents,
|
|
52921
53003
|
gitHook: shouldInstallGitHook,
|
|
52922
53004
|
agentHooks: shouldInstallAgentHooks,
|
|
52923
53005
|
workflow: didInstallWorkflow,
|
|
@@ -53697,7 +53779,7 @@ const warnDeprecatedDiff = (flags, userConfig) => {
|
|
|
53697
53779
|
};
|
|
53698
53780
|
const warnDiffUnavailable = (requested, isQuiet) => {
|
|
53699
53781
|
if (isQuiet) return;
|
|
53700
|
-
if (typeof requested.base === "string") cliLogger.warn(`Could not compute diff against "${requested.base}" (
|
|
53782
|
+
if (typeof requested.base === "string") cliLogger.warn(`Could not compute diff against "${requested.base}" (git unavailable, ref not found, or merge-base failed). Running full scan.`);
|
|
53701
53783
|
else cliLogger.warn("No feature branch or uncommitted changes detected. Running full scan.");
|
|
53702
53784
|
cliLogger.break();
|
|
53703
53785
|
};
|
|
@@ -54001,69 +54083,6 @@ const warnDeprecatedFailOn = (flags, userConfig) => {
|
|
|
54001
54083
|
cliLogger.warn(`${source} is deprecated; rename it to ${replacement}.`);
|
|
54002
54084
|
};
|
|
54003
54085
|
//#endregion
|
|
54004
|
-
//#region src/cli/utils/detect-ai-training-environment.ts
|
|
54005
|
-
const AI_TRAINING_ENV_VARS = [
|
|
54006
|
-
["HF_DATASETS_CACHE", "huggingface"],
|
|
54007
|
-
["HF_HOME", "huggingface"],
|
|
54008
|
-
["HUGGINGFACE_HUB_CACHE", "huggingface"],
|
|
54009
|
-
["CUDA_VISIBLE_DEVICES", "cuda"],
|
|
54010
|
-
["NVIDIA_VISIBLE_DEVICES", "nvidia"],
|
|
54011
|
-
["WANDB_RUN_ID", "wandb"],
|
|
54012
|
-
["MLFLOW_RUN_ID", "mlflow"],
|
|
54013
|
-
["MLFLOW_TRACKING_URI", "mlflow"],
|
|
54014
|
-
["COMET_EXPERIMENT_KEY", "comet"],
|
|
54015
|
-
["NEPTUNE_RUN_ID", "neptune"],
|
|
54016
|
-
["RAY_WORKER_PROCESS", "ray"],
|
|
54017
|
-
["RAY_ADDRESS", "ray"],
|
|
54018
|
-
["MUJOCO_GL", "mujoco"],
|
|
54019
|
-
["MUJOCO_PATH", "mujoco"],
|
|
54020
|
-
["GYM_DISABLE_ENV_CHECKER", "gymnasium"],
|
|
54021
|
-
["SAGEMAKER_BASE_DIR", "sagemaker"],
|
|
54022
|
-
["AZURE_ML_MODEL_DIR", "azure-ml"],
|
|
54023
|
-
["VERTEX_AI_LOG_LEVEL", "vertex-ai"],
|
|
54024
|
-
["DAYTONA_WS_ID", "daytona"],
|
|
54025
|
-
["DAYTONA_WS_NAME", "daytona"],
|
|
54026
|
-
["E2B_SANDBOX_ID", "e2b"],
|
|
54027
|
-
["MODAL_FUNCTION_ID", "modal"],
|
|
54028
|
-
["MODAL_TASK_ID", "modal"],
|
|
54029
|
-
["RUNPOD_POD_ID", "runpod"],
|
|
54030
|
-
["HARBOR_URL", "harbor"],
|
|
54031
|
-
["HARBOR_HOSTNAME", "harbor"],
|
|
54032
|
-
["SWE_BENCH_TASK", "swe-bench"],
|
|
54033
|
-
["SWEBENCH_TASK", "swe-bench"],
|
|
54034
|
-
["SWE_AGENT_MODEL", "swe-agent"],
|
|
54035
|
-
["KAGGLE_KERNEL_RUN_TYPE", "kaggle"],
|
|
54036
|
-
["COLAB_BACKEND_VERSION", "google-colab"],
|
|
54037
|
-
["DATABRICKS_RUNTIME_VERSION", "databricks"],
|
|
54038
|
-
["SM_TRAINING_ENV", "sagemaker"],
|
|
54039
|
-
["TRAINING_JOB_ARN", "sagemaker"],
|
|
54040
|
-
["AZUREML_RUN_ID", "azure-ml"],
|
|
54041
|
-
["CLOUD_ML_PROJECT_ID", "vertex-ai"],
|
|
54042
|
-
["WANDB_SWEEP_ID", "wandb"],
|
|
54043
|
-
["DVC_STAGE", "dvc"],
|
|
54044
|
-
["CLEARML_TASK_ID", "clearml"],
|
|
54045
|
-
["FLYTE_INTERNAL_EXECUTION_ID", "flyte"],
|
|
54046
|
-
["DET_MASTER", "determined-ai"],
|
|
54047
|
-
["LIGHTNING_USER_ID", "lightning-ai"],
|
|
54048
|
-
["ARGO_WORKFLOW_NAME", "argo-workflows"],
|
|
54049
|
-
["KFP_POD_NAME", "kubeflow-pipelines"],
|
|
54050
|
-
["SPACE_ID", "huggingface-spaces"],
|
|
54051
|
-
["REPLICATE_USERNAME", "replicate"],
|
|
54052
|
-
["VAST_CONTAINERLABEL", "vast-ai"],
|
|
54053
|
-
["TPU_NAME", "google-tpu"],
|
|
54054
|
-
["ROCR_VISIBLE_DEVICES", "rocm"]
|
|
54055
|
-
];
|
|
54056
|
-
const detectAiTrainingEnvironment = () => {
|
|
54057
|
-
for (const [envVar, label] of AI_TRAINING_ENV_VARS) if (process.env[envVar] !== void 0) return label;
|
|
54058
|
-
return null;
|
|
54059
|
-
};
|
|
54060
|
-
//#endregion
|
|
54061
|
-
//#region src/cli/utils/warn-ai-training-environment.ts
|
|
54062
|
-
const warnIfAiTrainingEnvironment = () => {
|
|
54063
|
-
if (detectAiTrainingEnvironment() === null) return;
|
|
54064
|
-
cliLogger.warn("react-doctor detected use in an AI or ML pipeline. This use requires written permission under the react-doctor license — contact founders@million.dev to request access.");
|
|
54065
|
-
};
|
|
54066
|
-
//#endregion
|
|
54067
54086
|
//#region src/cli/utils/validate-mode-flags.ts
|
|
54068
54087
|
const usedDiffAlias = (flags) => flags.diff !== void 0 && flags.diff !== false && flags.diff !== "false" && flags.diff !== "";
|
|
54069
54088
|
const usedScope = (flags) => typeof flags.scope === "string" && flags.scope.length > 0;
|
|
@@ -54164,7 +54183,6 @@ const inspectAction = async (directory, flags) => {
|
|
|
54164
54183
|
setJsonReportDirectory(resolvedDirectory);
|
|
54165
54184
|
warnDeprecatedFailOn(flags, userConfig);
|
|
54166
54185
|
warnDeprecatedDiff(flags, userConfig);
|
|
54167
|
-
warnIfAiTrainingEnvironment();
|
|
54168
54186
|
if (scanTarget.didRedirectViaRootDir && !isQuiet) {
|
|
54169
54187
|
cliLogger.dim(`Redirected to ${highlighter.info(toRelativePath(resolvedDirectory, requestedDirectory))} via react-doctor config "rootDir".`);
|
|
54170
54188
|
cliLogger.break();
|
|
@@ -54452,6 +54470,10 @@ const installAction = async (options, command) => {
|
|
|
54452
54470
|
projectRoot: options.cwd ?? process.cwd()
|
|
54453
54471
|
});
|
|
54454
54472
|
} catch (error) {
|
|
54473
|
+
if (isExpectedUserError(error)) {
|
|
54474
|
+
handleUserError(error);
|
|
54475
|
+
return;
|
|
54476
|
+
}
|
|
54455
54477
|
handleError(error, { sentryEventId: await reportErrorToSentry(error) });
|
|
54456
54478
|
}
|
|
54457
54479
|
};
|
|
@@ -55459,4 +55481,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
55459
55481
|
export {};
|
|
55460
55482
|
|
|
55461
55483
|
//# sourceMappingURL=cli.js.map
|
|
55462
|
-
//# debugId=
|
|
55484
|
+
//# debugId=7e6ea254-9fcd-5076-8bd6-01ad63633c24
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
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]="dccb6d63-63d4-5e91-af21-2756a08fe93a")}catch(e){}}();
|
|
3
3
|
import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as NFS from "node:fs";
|
|
@@ -33694,6 +33694,7 @@ const MILLISECONDS_PER_SECOND = 1e3;
|
|
|
33694
33694
|
const SCORE_API_URL = "https://www.react.doctor/api/score";
|
|
33695
33695
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
33696
33696
|
const GITHUB_VIEWER_PERMISSION_TIMEOUT_MS = 2e3;
|
|
33697
|
+
const SPAWN_ARGS_MAX_LENGTH_CHARS = 24e3;
|
|
33697
33698
|
const PER_WORKER_MEM_BUDGET_BYTES = 1024 * 1024 * 1024;
|
|
33698
33699
|
const DEFAULT_BRANCH_CANDIDATES = ["main", "master"];
|
|
33699
33700
|
const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
|
|
@@ -34487,7 +34488,10 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
|
|
|
34487
34488
|
NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.set(nativeRuleKey, aliases);
|
|
34488
34489
|
}
|
|
34489
34490
|
const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
|
|
34490
|
-
const canonicalizeRuleKey = (ruleKey) =>
|
|
34491
|
+
const canonicalizeRuleKey = (ruleKey) => {
|
|
34492
|
+
const nativeRuleKey = LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey];
|
|
34493
|
+
return typeof nativeRuleKey === "string" ? nativeRuleKey : ruleKey;
|
|
34494
|
+
};
|
|
34491
34495
|
const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
|
|
34492
34496
|
const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
|
|
34493
34497
|
const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
|
|
@@ -35577,6 +35581,12 @@ const BOOLEAN_FIELD_NAMES = [
|
|
|
35577
35581
|
"adoptExistingLintConfig"
|
|
35578
35582
|
];
|
|
35579
35583
|
const STRING_FIELD_NAMES = ["rootDir"];
|
|
35584
|
+
const STRING_ARRAY_FIELD_NAMES = [
|
|
35585
|
+
"projects",
|
|
35586
|
+
"textComponents",
|
|
35587
|
+
"rawTextWrapperComponents",
|
|
35588
|
+
"serverAuthFunctionNames"
|
|
35589
|
+
];
|
|
35580
35590
|
const SURFACE_CONTROL_FIELD_NAMES = [
|
|
35581
35591
|
"includeTags",
|
|
35582
35592
|
"excludeTags",
|
|
@@ -35678,6 +35688,7 @@ const validateConfigTypes = (config) => {
|
|
|
35678
35688
|
const validated = { ...config };
|
|
35679
35689
|
for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
|
|
35680
35690
|
for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
|
|
35691
|
+
for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
|
|
35681
35692
|
applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
|
|
35682
35693
|
for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
|
|
35683
35694
|
applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
|
|
@@ -37862,43 +37873,46 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37862
37873
|
* reason: GitInvocationFailed })` so the rest of the codebase
|
|
37863
37874
|
* sees a single failure channel.
|
|
37864
37875
|
*/
|
|
37865
|
-
const runCommand = (input) =>
|
|
37866
|
-
const
|
|
37867
|
-
cwd: input.directory,
|
|
37868
|
-
env: input.env,
|
|
37869
|
-
extendEnv: true
|
|
37870
|
-
}));
|
|
37871
|
-
const maxStdoutBytes = input.maxStdoutBytes;
|
|
37872
|
-
const stdoutByteCount = yield* make$13(0);
|
|
37873
|
-
const [stdout, stderr, status] = yield* all([
|
|
37874
|
-
mkString(decodeText(maxStdoutBytes === void 0 ? handle.stdout : handle.stdout.pipe(tap((chunk) => updateAndGet(stdoutByteCount, (total) => total + chunk.length).pipe(flatMap$2((total) => total > maxStdoutBytes ? fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37875
|
-
args: [...input.args],
|
|
37876
|
-
directory: input.directory,
|
|
37877
|
-
cause: /* @__PURE__ */ new Error(`git stdout exceeded ${maxStdoutBytes} bytes`)
|
|
37878
|
-
}) })) : void_)))))),
|
|
37879
|
-
mkString(decodeText(handle.stderr)),
|
|
37880
|
-
handle.exitCode
|
|
37881
|
-
], { concurrency: 3 });
|
|
37882
|
-
return {
|
|
37883
|
-
status,
|
|
37884
|
-
stdout,
|
|
37885
|
-
stderr
|
|
37886
|
-
};
|
|
37887
|
-
})).pipe(catchTag$1("PlatformError", (cause) => {
|
|
37888
|
-
if (input.command !== "git") return succeed$2({
|
|
37876
|
+
const runCommand = (input) => {
|
|
37877
|
+
const foldSpawnFailure = (cause) => input.command !== "git" ? succeed$2({
|
|
37889
37878
|
status: 127,
|
|
37890
37879
|
stdout: "",
|
|
37891
37880
|
stderr: String(cause)
|
|
37892
|
-
})
|
|
37893
|
-
return new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37881
|
+
}) : fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37894
37882
|
args: [...input.args],
|
|
37895
37883
|
directory: input.directory,
|
|
37896
37884
|
cause
|
|
37897
|
-
}) });
|
|
37898
|
-
|
|
37899
|
-
|
|
37900
|
-
|
|
37901
|
-
|
|
37885
|
+
}) }));
|
|
37886
|
+
return scoped(gen(function* () {
|
|
37887
|
+
if (!isDirectory(input.directory)) return yield* foldSpawnFailure(`spawn ENOTDIR (cwd is not a directory: ${input.directory})`);
|
|
37888
|
+
const argvLengthChars = input.command.length + 1 + input.args.reduce((total, arg) => total + arg.length + 1, 0);
|
|
37889
|
+
if (argvLengthChars > 24e3) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${SPAWN_ARGS_MAX_LENGTH_CHARS})`);
|
|
37890
|
+
const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
|
|
37891
|
+
cwd: input.directory,
|
|
37892
|
+
env: input.env,
|
|
37893
|
+
extendEnv: true
|
|
37894
|
+
}));
|
|
37895
|
+
const maxStdoutBytes = input.maxStdoutBytes;
|
|
37896
|
+
const stdoutByteCount = yield* make$13(0);
|
|
37897
|
+
const [stdout, stderr, status] = yield* all([
|
|
37898
|
+
mkString(decodeText(maxStdoutBytes === void 0 ? handle.stdout : handle.stdout.pipe(tap((chunk) => updateAndGet(stdoutByteCount, (total) => total + chunk.length).pipe(flatMap$2((total) => total > maxStdoutBytes ? fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37899
|
+
args: [...input.args],
|
|
37900
|
+
directory: input.directory,
|
|
37901
|
+
cause: /* @__PURE__ */ new Error(`git stdout exceeded ${maxStdoutBytes} bytes`)
|
|
37902
|
+
}) })) : void_)))))),
|
|
37903
|
+
mkString(decodeText(handle.stderr)),
|
|
37904
|
+
handle.exitCode
|
|
37905
|
+
], { concurrency: 3 });
|
|
37906
|
+
return {
|
|
37907
|
+
status,
|
|
37908
|
+
stdout,
|
|
37909
|
+
stderr
|
|
37910
|
+
};
|
|
37911
|
+
})).pipe(catchTag$1("PlatformError", foldSpawnFailure), withSpan("git.exec", { attributes: {
|
|
37912
|
+
"git.command": input.command,
|
|
37913
|
+
"git.subcommand": input.args[0] ?? ""
|
|
37914
|
+
} }));
|
|
37915
|
+
};
|
|
37902
37916
|
const runGit = (directory, args) => runCommand({
|
|
37903
37917
|
command: "git",
|
|
37904
37918
|
args,
|
|
@@ -37931,7 +37945,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37931
37945
|
"rev-parse",
|
|
37932
37946
|
"--verify",
|
|
37933
37947
|
branch
|
|
37934
|
-
]).pipe(map$3((result) => result.status === 0));
|
|
37948
|
+
]).pipe(map$3((result) => result.status === 0), catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(false) : fail$4(error)));
|
|
37935
37949
|
const headSha = (directory) => runGit(directory, ["rev-parse", "HEAD"]).pipe(map$3((result) => result.status === 0 ? trimOrNull(result.stdout) : null));
|
|
37936
37950
|
const mergeBase = (input) => isSafeGitRevision(input.ref) ? runGit(input.directory, [
|
|
37937
37951
|
"merge-base",
|
|
@@ -38145,7 +38159,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
38145
38159
|
]);
|
|
38146
38160
|
if (result.status !== 0) return null;
|
|
38147
38161
|
return parseChangedLineRanges(result.stdout);
|
|
38148
|
-
}).pipe(withSpan("Git.changedLineRanges"))
|
|
38162
|
+
}).pipe(catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(null) : fail$4(error)), withSpan("Git.changedLineRanges"))
|
|
38149
38163
|
});
|
|
38150
38164
|
})).pipe(provide$2(layer$2.pipe(provide$2(mergeAll$1(layer$1, layer)))));
|
|
38151
38165
|
/**
|
|
@@ -41342,64 +41356,6 @@ const mergeReactDoctorConfigs = (baseConfig, overrideConfig) => {
|
|
|
41342
41356
|
};
|
|
41343
41357
|
//#endregion
|
|
41344
41358
|
//#region ../api/dist/index.js
|
|
41345
|
-
const AI_TRAINING_ENV_VARS = [
|
|
41346
|
-
"HF_DATASETS_CACHE",
|
|
41347
|
-
"HF_HOME",
|
|
41348
|
-
"HUGGINGFACE_HUB_CACHE",
|
|
41349
|
-
"CUDA_VISIBLE_DEVICES",
|
|
41350
|
-
"NVIDIA_VISIBLE_DEVICES",
|
|
41351
|
-
"WANDB_RUN_ID",
|
|
41352
|
-
"WANDB_SWEEP_ID",
|
|
41353
|
-
"MLFLOW_RUN_ID",
|
|
41354
|
-
"MLFLOW_TRACKING_URI",
|
|
41355
|
-
"COMET_EXPERIMENT_KEY",
|
|
41356
|
-
"NEPTUNE_RUN_ID",
|
|
41357
|
-
"CLEARML_TASK_ID",
|
|
41358
|
-
"RAY_WORKER_PROCESS",
|
|
41359
|
-
"RAY_ADDRESS",
|
|
41360
|
-
"MUJOCO_GL",
|
|
41361
|
-
"MUJOCO_PATH",
|
|
41362
|
-
"GYM_DISABLE_ENV_CHECKER",
|
|
41363
|
-
"SM_TRAINING_ENV",
|
|
41364
|
-
"TRAINING_JOB_ARN",
|
|
41365
|
-
"SAGEMAKER_BASE_DIR",
|
|
41366
|
-
"AZUREML_RUN_ID",
|
|
41367
|
-
"AZURE_ML_MODEL_DIR",
|
|
41368
|
-
"CLOUD_ML_PROJECT_ID",
|
|
41369
|
-
"VERTEX_AI_LOG_LEVEL",
|
|
41370
|
-
"KAGGLE_KERNEL_RUN_TYPE",
|
|
41371
|
-
"COLAB_BACKEND_VERSION",
|
|
41372
|
-
"DATABRICKS_RUNTIME_VERSION",
|
|
41373
|
-
"FLYTE_INTERNAL_EXECUTION_ID",
|
|
41374
|
-
"DET_MASTER",
|
|
41375
|
-
"LIGHTNING_USER_ID",
|
|
41376
|
-
"ARGO_WORKFLOW_NAME",
|
|
41377
|
-
"KFP_POD_NAME",
|
|
41378
|
-
"DVC_STAGE",
|
|
41379
|
-
"DAYTONA_WS_ID",
|
|
41380
|
-
"DAYTONA_WS_NAME",
|
|
41381
|
-
"E2B_SANDBOX_ID",
|
|
41382
|
-
"MODAL_FUNCTION_ID",
|
|
41383
|
-
"MODAL_TASK_ID",
|
|
41384
|
-
"RUNPOD_POD_ID",
|
|
41385
|
-
"SPACE_ID",
|
|
41386
|
-
"REPLICATE_USERNAME",
|
|
41387
|
-
"VAST_CONTAINERLABEL",
|
|
41388
|
-
"TPU_NAME",
|
|
41389
|
-
"ROCR_VISIBLE_DEVICES",
|
|
41390
|
-
"HARBOR_URL",
|
|
41391
|
-
"HARBOR_HOSTNAME",
|
|
41392
|
-
"SWE_BENCH_TASK",
|
|
41393
|
-
"SWEBENCH_TASK",
|
|
41394
|
-
"SWE_AGENT_MODEL"
|
|
41395
|
-
];
|
|
41396
|
-
let didWarnAiTraining = false;
|
|
41397
|
-
const warnIfAiTrainingEnvironment = () => {
|
|
41398
|
-
if (didWarnAiTraining) return;
|
|
41399
|
-
if (AI_TRAINING_ENV_VARS.find((envVar) => process.env[envVar] !== void 0) === void 0) return;
|
|
41400
|
-
didWarnAiTraining = true;
|
|
41401
|
-
console.warn("[react-doctor] Use in an AI or ML pipeline requires written permission under the react-doctor license. Contact founders@million.dev to request access.");
|
|
41402
|
-
};
|
|
41403
41359
|
const buildDiagnoseLayer = (config, configOverrideTarget) => {
|
|
41404
41360
|
const configLayer = configOverrideTarget === void 0 ? Config.layerNode : Config.layerOf({
|
|
41405
41361
|
config,
|
|
@@ -41437,7 +41393,6 @@ const outputToDiagnoseResult = (output, elapsedMilliseconds) => {
|
|
|
41437
41393
|
};
|
|
41438
41394
|
};
|
|
41439
41395
|
const diagnoseDirectory = async (directory, options) => {
|
|
41440
|
-
warnIfAiTrainingEnvironment();
|
|
41441
41396
|
const startTime = globalThis.performance.now();
|
|
41442
41397
|
const scanTarget = await resolveScanTarget(directory);
|
|
41443
41398
|
return outputToDiagnoseResult(await runPromise(restoreLegacyThrow(buildInspectProgram(scanTarget, options).pipe(provide(buildDiagnoseLayer(scanTarget.userConfig)), provide(layerOtlp)))), globalThis.performance.now() - startTime);
|
|
@@ -41484,7 +41439,6 @@ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig) => {
|
|
|
41484
41439
|
}
|
|
41485
41440
|
};
|
|
41486
41441
|
const diagnoseProjectBatch = async (input) => {
|
|
41487
|
-
warnIfAiTrainingEnvironment();
|
|
41488
41442
|
const startTime = globalThis.performance.now();
|
|
41489
41443
|
const { projects, concurrency, config: batchConfig, ...baseOptions } = input;
|
|
41490
41444
|
const projectResults = await mapWithConcurrency(projects, concurrency ?? 4, (projectDefinition) => diagnoseProject(projectDefinition, baseOptions, batchConfig));
|
|
@@ -41529,4 +41483,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
41529
41483
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
41530
41484
|
|
|
41531
41485
|
//# sourceMappingURL=index.js.map
|
|
41532
|
-
//# debugId=
|
|
41486
|
+
//# debugId=dccb6d63-63d4-5e91-af21-2756a08fe93a
|
package/dist/lsp.js
CHANGED
|
@@ -33730,6 +33730,7 @@ const MILLISECONDS_PER_SECOND = 1e3;
|
|
|
33730
33730
|
const SCORE_API_URL = "https://www.react.doctor/api/score";
|
|
33731
33731
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
33732
33732
|
const GITHUB_VIEWER_PERMISSION_TIMEOUT_MS = 2e3;
|
|
33733
|
+
const SPAWN_ARGS_MAX_LENGTH_CHARS = 24e3;
|
|
33733
33734
|
const PER_WORKER_MEM_BUDGET_BYTES = 1024 * 1024 * 1024;
|
|
33734
33735
|
const DEFAULT_BRANCH_CANDIDATES = ["main", "master"];
|
|
33735
33736
|
const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
|
|
@@ -34546,7 +34547,10 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
|
|
|
34546
34547
|
NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.set(nativeRuleKey, aliases);
|
|
34547
34548
|
}
|
|
34548
34549
|
const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
|
|
34549
|
-
const canonicalizeRuleKey = (ruleKey) =>
|
|
34550
|
+
const canonicalizeRuleKey = (ruleKey) => {
|
|
34551
|
+
const nativeRuleKey = LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey];
|
|
34552
|
+
return typeof nativeRuleKey === "string" ? nativeRuleKey : ruleKey;
|
|
34553
|
+
};
|
|
34550
34554
|
const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
|
|
34551
34555
|
const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
|
|
34552
34556
|
const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
|
|
@@ -35610,6 +35614,12 @@ const BOOLEAN_FIELD_NAMES = [
|
|
|
35610
35614
|
"adoptExistingLintConfig"
|
|
35611
35615
|
];
|
|
35612
35616
|
const STRING_FIELD_NAMES = ["rootDir"];
|
|
35617
|
+
const STRING_ARRAY_FIELD_NAMES = [
|
|
35618
|
+
"projects",
|
|
35619
|
+
"textComponents",
|
|
35620
|
+
"rawTextWrapperComponents",
|
|
35621
|
+
"serverAuthFunctionNames"
|
|
35622
|
+
];
|
|
35613
35623
|
const SURFACE_CONTROL_FIELD_NAMES = [
|
|
35614
35624
|
"includeTags",
|
|
35615
35625
|
"excludeTags",
|
|
@@ -35711,6 +35721,7 @@ const validateConfigTypes = (config) => {
|
|
|
35711
35721
|
const validated = { ...config };
|
|
35712
35722
|
for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
|
|
35713
35723
|
for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
|
|
35724
|
+
for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
|
|
35714
35725
|
applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
|
|
35715
35726
|
for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
|
|
35716
35727
|
applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
|
|
@@ -37847,43 +37858,46 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37847
37858
|
* reason: GitInvocationFailed })` so the rest of the codebase
|
|
37848
37859
|
* sees a single failure channel.
|
|
37849
37860
|
*/
|
|
37850
|
-
const runCommand = (input) =>
|
|
37851
|
-
const
|
|
37852
|
-
cwd: input.directory,
|
|
37853
|
-
env: input.env,
|
|
37854
|
-
extendEnv: true
|
|
37855
|
-
}));
|
|
37856
|
-
const maxStdoutBytes = input.maxStdoutBytes;
|
|
37857
|
-
const stdoutByteCount = yield* make$13(0);
|
|
37858
|
-
const [stdout, stderr, status] = yield* all([
|
|
37859
|
-
mkString(decodeText(maxStdoutBytes === void 0 ? handle.stdout : handle.stdout.pipe(tap((chunk) => updateAndGet(stdoutByteCount, (total) => total + chunk.length).pipe(flatMap$2((total) => total > maxStdoutBytes ? fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37860
|
-
args: [...input.args],
|
|
37861
|
-
directory: input.directory,
|
|
37862
|
-
cause: /* @__PURE__ */ new Error(`git stdout exceeded ${maxStdoutBytes} bytes`)
|
|
37863
|
-
}) })) : void_)))))),
|
|
37864
|
-
mkString(decodeText(handle.stderr)),
|
|
37865
|
-
handle.exitCode
|
|
37866
|
-
], { concurrency: 3 });
|
|
37867
|
-
return {
|
|
37868
|
-
status,
|
|
37869
|
-
stdout,
|
|
37870
|
-
stderr
|
|
37871
|
-
};
|
|
37872
|
-
})).pipe(catchTag$1("PlatformError", (cause) => {
|
|
37873
|
-
if (input.command !== "git") return succeed$2({
|
|
37861
|
+
const runCommand = (input) => {
|
|
37862
|
+
const foldSpawnFailure = (cause) => input.command !== "git" ? succeed$2({
|
|
37874
37863
|
status: 127,
|
|
37875
37864
|
stdout: "",
|
|
37876
37865
|
stderr: String(cause)
|
|
37877
|
-
})
|
|
37878
|
-
return new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37866
|
+
}) : fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37879
37867
|
args: [...input.args],
|
|
37880
37868
|
directory: input.directory,
|
|
37881
37869
|
cause
|
|
37882
|
-
}) });
|
|
37883
|
-
|
|
37884
|
-
|
|
37885
|
-
|
|
37886
|
-
|
|
37870
|
+
}) }));
|
|
37871
|
+
return scoped(gen(function* () {
|
|
37872
|
+
if (!isDirectory(input.directory)) return yield* foldSpawnFailure(`spawn ENOTDIR (cwd is not a directory: ${input.directory})`);
|
|
37873
|
+
const argvLengthChars = input.command.length + 1 + input.args.reduce((total, arg) => total + arg.length + 1, 0);
|
|
37874
|
+
if (argvLengthChars > 24e3) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${SPAWN_ARGS_MAX_LENGTH_CHARS})`);
|
|
37875
|
+
const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
|
|
37876
|
+
cwd: input.directory,
|
|
37877
|
+
env: input.env,
|
|
37878
|
+
extendEnv: true
|
|
37879
|
+
}));
|
|
37880
|
+
const maxStdoutBytes = input.maxStdoutBytes;
|
|
37881
|
+
const stdoutByteCount = yield* make$13(0);
|
|
37882
|
+
const [stdout, stderr, status] = yield* all([
|
|
37883
|
+
mkString(decodeText(maxStdoutBytes === void 0 ? handle.stdout : handle.stdout.pipe(tap((chunk) => updateAndGet(stdoutByteCount, (total) => total + chunk.length).pipe(flatMap$2((total) => total > maxStdoutBytes ? fail$4(new ReactDoctorError({ reason: new GitInvocationFailed({
|
|
37884
|
+
args: [...input.args],
|
|
37885
|
+
directory: input.directory,
|
|
37886
|
+
cause: /* @__PURE__ */ new Error(`git stdout exceeded ${maxStdoutBytes} bytes`)
|
|
37887
|
+
}) })) : void_)))))),
|
|
37888
|
+
mkString(decodeText(handle.stderr)),
|
|
37889
|
+
handle.exitCode
|
|
37890
|
+
], { concurrency: 3 });
|
|
37891
|
+
return {
|
|
37892
|
+
status,
|
|
37893
|
+
stdout,
|
|
37894
|
+
stderr
|
|
37895
|
+
};
|
|
37896
|
+
})).pipe(catchTag$1("PlatformError", foldSpawnFailure), withSpan("git.exec", { attributes: {
|
|
37897
|
+
"git.command": input.command,
|
|
37898
|
+
"git.subcommand": input.args[0] ?? ""
|
|
37899
|
+
} }));
|
|
37900
|
+
};
|
|
37887
37901
|
const runGit = (directory, args) => runCommand({
|
|
37888
37902
|
command: "git",
|
|
37889
37903
|
args,
|
|
@@ -37916,7 +37930,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37916
37930
|
"rev-parse",
|
|
37917
37931
|
"--verify",
|
|
37918
37932
|
branch
|
|
37919
|
-
]).pipe(map$3((result) => result.status === 0));
|
|
37933
|
+
]).pipe(map$3((result) => result.status === 0), catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(false) : fail$4(error)));
|
|
37920
37934
|
const headSha = (directory) => runGit(directory, ["rev-parse", "HEAD"]).pipe(map$3((result) => result.status === 0 ? trimOrNull(result.stdout) : null));
|
|
37921
37935
|
const mergeBase = (input) => isSafeGitRevision(input.ref) ? runGit(input.directory, [
|
|
37922
37936
|
"merge-base",
|
|
@@ -38130,7 +38144,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
38130
38144
|
]);
|
|
38131
38145
|
if (result.status !== 0) return null;
|
|
38132
38146
|
return parseChangedLineRanges(result.stdout);
|
|
38133
|
-
}).pipe(withSpan("Git.changedLineRanges"))
|
|
38147
|
+
}).pipe(catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(null) : fail$4(error)), withSpan("Git.changedLineRanges"))
|
|
38134
38148
|
});
|
|
38135
38149
|
})).pipe(provide$2(layer$2.pipe(provide$2(mergeAll$1(layer$1, layer)))));
|
|
38136
38150
|
/**
|
|
@@ -42903,6 +42917,7 @@ const SENTRY_FLUSH_TIMEOUT_MS = 2e3;
|
|
|
42903
42917
|
const METRIC = {
|
|
42904
42918
|
cliInvoked: "cli.invoked",
|
|
42905
42919
|
cliError: "cli.error",
|
|
42920
|
+
cliEnvironmentError: "cli.env_error",
|
|
42906
42921
|
projectDetected: "project.detected",
|
|
42907
42922
|
projectPathSelected: "project.path_selected",
|
|
42908
42923
|
projectConfigSelected: "project.config_selected",
|
|
@@ -43249,5 +43264,5 @@ const startLanguageServer = () => {
|
|
|
43249
43264
|
};
|
|
43250
43265
|
//#endregion
|
|
43251
43266
|
export { startLanguageServer };
|
|
43252
|
-
!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]="
|
|
43253
|
-
//# debugId=
|
|
43267
|
+
!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]="d12f3c5d-14fd-59ba-9d8a-7e3f589c88ad")}catch(e){}}();
|
|
43268
|
+
//# debugId=d12f3c5d-14fd-59ba-9d8a-7e3f589c88ad
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.5.8-dev.
|
|
3
|
+
"version": "0.5.8-dev.ea00b1b",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"bugs": {
|
|
21
21
|
"url": "https://github.com/millionco/react-doctor/issues"
|
|
22
22
|
},
|
|
23
|
-
"license": "
|
|
23
|
+
"license": "MIT",
|
|
24
24
|
"author": "Million Software, Inc",
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"vscode-languageserver": "^9.0.1",
|
|
64
64
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
65
65
|
"vscode-uri": "^3.1.0",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
66
|
+
"deslop-js": "0.5.8",
|
|
67
|
+
"oxlint-plugin-react-doctor": "0.5.8-dev.ea00b1b"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@types/babel__code-frame": "^7.27.0",
|
|
@@ -73,8 +73,8 @@
|
|
|
73
73
|
"commander": "^14.0.3",
|
|
74
74
|
"ora": "^9.4.0",
|
|
75
75
|
"@react-doctor/api": "0.5.8",
|
|
76
|
-
"@react-doctor/
|
|
77
|
-
"@react-doctor/
|
|
76
|
+
"@react-doctor/language-server": "0.5.8",
|
|
77
|
+
"@react-doctor/core": "0.5.8"
|
|
78
78
|
},
|
|
79
79
|
"engines": {
|
|
80
80
|
"node": "^20.19.0 || >=22.13.0"
|