react-doctor 0.5.8-dev.70ae19f → 0.5.8-dev.734c564

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 CHANGED
@@ -1,4 +1,4 @@
1
- MIT License (with Additional Restrictions)
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]="34e4ad65-2650-5e3e-afd8-191931eb2a47")}catch(e){}}();
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]="89eea142-f3f2-5f35-a6b0-e9e10055d0cb")}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
@@ -37679,7 +37679,10 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
37679
37679
  NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.set(nativeRuleKey, aliases);
37680
37680
  }
37681
37681
  const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
37682
- const canonicalizeRuleKey = (ruleKey) => LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey] ?? ruleKey;
37682
+ const canonicalizeRuleKey = (ruleKey) => {
37683
+ const nativeRuleKey = LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey];
37684
+ return typeof nativeRuleKey === "string" ? nativeRuleKey : ruleKey;
37685
+ };
37683
37686
  const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
37684
37687
  const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
37685
37688
  const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
@@ -38765,6 +38768,12 @@ const BOOLEAN_FIELD_NAMES = [
38765
38768
  "adoptExistingLintConfig"
38766
38769
  ];
38767
38770
  const STRING_FIELD_NAMES = ["rootDir"];
38771
+ const STRING_ARRAY_FIELD_NAMES = [
38772
+ "projects",
38773
+ "textComponents",
38774
+ "rawTextWrapperComponents",
38775
+ "serverAuthFunctionNames"
38776
+ ];
38768
38777
  const SURFACE_CONTROL_FIELD_NAMES = [
38769
38778
  "includeTags",
38770
38779
  "excludeTags",
@@ -38866,6 +38875,7 @@ const validateConfigTypes = (config) => {
38866
38875
  const validated = { ...config };
38867
38876
  for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
38868
38877
  for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
38878
+ for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
38869
38879
  applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
38870
38880
  for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
38871
38881
  applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
@@ -41163,7 +41173,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
41163
41173
  "rev-parse",
41164
41174
  "--verify",
41165
41175
  branch
41166
- ]).pipe(map$3((result) => result.status === 0));
41176
+ ]).pipe(map$3((result) => result.status === 0), catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(false) : fail$4(error)));
41167
41177
  const headSha = (directory) => runGit(directory, ["rev-parse", "HEAD"]).pipe(map$3((result) => result.status === 0 ? trimOrNull(result.stdout) : null));
41168
41178
  const mergeBase = (input) => isSafeGitRevision(input.ref) ? runGit(input.directory, [
41169
41179
  "merge-base",
@@ -44702,25 +44712,7 @@ const CI_PROVIDER_BY_ENVIRONMENT_VARIABLE = [
44702
44712
  ["TEAMCITY_VERSION", "teamcity"],
44703
44713
  ["BITBUCKET_BUILD_NUMBER", "bitbucket"],
44704
44714
  ["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"]
44715
+ ["DRONE", "drone"]
44724
44716
  ];
44725
44717
  const GITHUB_ACTION_MARKER_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_GITHUB_ACTION";
44726
44718
  const ACTION_INPUT_ENVIRONMENT_VARIABLES = {
@@ -44738,10 +44730,7 @@ const CODING_AGENT_BY_ENVIRONMENT_VARIABLE = [
44738
44730
  ["CODEX_SANDBOX_NETWORK_DISABLED", "codex"],
44739
44731
  ["OPENCODE", "opencode"],
44740
44732
  ["GOOSE_TERMINAL", "goose"],
44741
- ["AMP_THREAD_ID", "amp"],
44742
- ["CLINE_ACTIVE", "cline"],
44743
- ["AUGMENT_AGENT", "augment"],
44744
- ["TRAE_AI_SHELL_ID", "trae-ai"]
44733
+ ["AMP_THREAD_ID", "amp"]
44745
44734
  ];
44746
44735
  const GENERIC_CODING_AGENT_ENVIRONMENT_VARIABLES = ["AGENT_SESSION_ID", "AGENT_THREAD_ID"];
44747
44736
  const CODING_AGENT_ENVIRONMENT_VALUE_VARIABLES = ["AGENT"];
@@ -44860,6 +44849,7 @@ const NANOSECONDS_PER_SECOND = 1000000000n;
44860
44849
  const METRIC = {
44861
44850
  cliInvoked: "cli.invoked",
44862
44851
  cliError: "cli.error",
44852
+ cliEnvironmentError: "cli.env_error",
44863
44853
  projectDetected: "project.detected",
44864
44854
  projectPathSelected: "project.path_selected",
44865
44855
  projectConfigSelected: "project.config_selected",
@@ -44932,7 +44922,7 @@ const makeNoopConsole = () => ({
44932
44922
  });
44933
44923
  //#endregion
44934
44924
  //#region src/cli/utils/version.ts
44935
- const VERSION = "0.5.8-dev.70ae19f";
44925
+ const VERSION = "0.5.8-dev.734c564";
44936
44926
  //#endregion
44937
44927
  //#region src/cli/utils/json-mode.ts
44938
44928
  let context = null;
@@ -45296,13 +45286,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
45296
45286
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
45297
45287
  * standard `SENTRY_RELEASE` override.
45298
45288
  */
45299
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.5.8-dev.70ae19f`;
45289
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.5.8-dev.734c564`;
45300
45290
  /**
45301
45291
  * Deployment environment shown in Sentry's environment filter. Defaults to
45302
45292
  * `production` for tagged releases and `development` for dev/unbuilt versions,
45303
45293
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
45304
45294
  */
45305
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.5.8-dev.70ae19f") ? "development" : "production");
45295
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.5.8-dev.734c564") ? "development" : "production");
45306
45296
  /**
45307
45297
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
45308
45298
  * (set to `0` to disable tracing) and falls back to
@@ -49711,6 +49701,7 @@ const CI_PITCH_EVENT = "ci-pitch";
49711
49701
  const ACTION_UPGRADE_EVENT = "action-upgrade-v2";
49712
49702
  const SETUP_HINT_EVENT = "setup-hint";
49713
49703
  const HANDOFF_TARGET_PREFERENCE_ID = "handoff-target";
49704
+ const INSTALL_AGENTS_PREFERENCE_ID = "install-agents";
49714
49705
  const foldLegacyDecisions = (projects, legacy, eventId) => {
49715
49706
  for (const [hash, record] of Object.entries(legacy ?? {})) {
49716
49707
  const existing = projects[hash] ?? { rootDirectory: record.rootDirectory ?? "" };
@@ -50374,7 +50365,7 @@ const readPackageJson = (projectRoot) => {
50374
50365
  return null;
50375
50366
  }
50376
50367
  };
50377
- const writeJsonFile$1 = (filePath, value) => {
50368
+ const writeJsonFile = (filePath, value) => {
50378
50369
  NFS.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
50379
50370
  };
50380
50371
  const packageHasDependency = (projectRoot, dependencyName) => {
@@ -51113,6 +51104,35 @@ const materializeStagedFiles = async (directory, stagedFiles, tempDirectory) =>
51113
51104
  };
51114
51105
  };
51115
51106
  //#endregion
51107
+ //#region src/cli/utils/is-environment-error.ts
51108
+ const isNodeSystemError = (error) => error instanceof Error && typeof error.code === "string";
51109
+ const ENVIRONMENT_ERROR_CODES = new Set([
51110
+ "ENOSPC",
51111
+ "EIO",
51112
+ "EROFS",
51113
+ "EACCES",
51114
+ "EPERM",
51115
+ "ENOTDIR"
51116
+ ]);
51117
+ const isEnvironmentError = (error) => {
51118
+ if (!isNodeSystemError(error)) return false;
51119
+ if (error.code === "ENOENT") return error.syscall?.startsWith("spawn") ?? false;
51120
+ return error.code !== void 0 && ENVIRONMENT_ERROR_CODES.has(error.code);
51121
+ };
51122
+ const formatEnvironmentError = (error) => {
51123
+ if (!isNodeSystemError(error)) return error instanceof Error ? error.message : String(error);
51124
+ switch (error.code) {
51125
+ case "ENOSPC": return "No space left on device. Free up disk space and try again.";
51126
+ case "EIO": return "I/O error: the filesystem or disk may be failing. Check your system logs.";
51127
+ case "EROFS": return "Read-only filesystem: cannot write to this location.";
51128
+ case "EACCES":
51129
+ case "EPERM": return error.path ? `Permission denied accessing ${error.path}. Check file permissions and try again.` : "Permission denied. Check file permissions and try again.";
51130
+ 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.";
51131
+ case "ENOENT": return "Required command not found. Ensure the tool (e.g. git) is installed and on your PATH.";
51132
+ default: return error.message;
51133
+ }
51134
+ };
51135
+ //#endregion
51116
51136
  //#region src/cli/utils/handle-error.ts
51117
51137
  const OTLP_ENDPOINT_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_ENDPOINT";
51118
51138
  const OTLP_AUTH_HEADER_ENVIRONMENT_VARIABLE = "REACT_DOCTOR_OTLP_AUTH_HEADER";
@@ -51195,15 +51215,19 @@ const handleError = (error, options = {}) => {
51195
51215
  process.exitCode = 1;
51196
51216
  };
51197
51217
  /**
51198
- * Renderer for expected, user-actionable failures — a bad `--diff` value or
51199
- * a base branch that isn't fetched. Prints just the (already human-readable)
51200
- * message no "Something went wrong", prefilled issue, Discord link, or
51201
- * Sentry reference because there is no bug to report.
51218
+ * Renderer for expected, user-actionable failures — a bad `--diff` value,
51219
+ * a base branch that isn't fetched, or environment errors like disk-full or
51220
+ * permission-denied. Prints just the (already human-readable) message no
51221
+ * "Something went wrong", prefilled issue, Discord link, or Sentry reference
51222
+ * — because there is no bug to report.
51202
51223
  */
51203
51224
  const handleUserError = (error, options = {}) => {
51225
+ const isEnvError = isEnvironmentError(error);
51226
+ if (isEnvError) recordCount(METRIC.cliEnvironmentError, 1, { code: error.code ?? "unknown" });
51227
+ const message = isEnvError ? formatEnvironmentError(error) : formatErrorForReport(error);
51204
51228
  runSync(gen(function* () {
51205
51229
  yield* error$1("");
51206
- yield* error$1(highlighter.error(formatErrorForReport(error)));
51230
+ yield* error$1(highlighter.error(message));
51207
51231
  yield* error$1("");
51208
51232
  }));
51209
51233
  if (options.shouldExit !== false) process.exit(1);
@@ -51218,7 +51242,7 @@ const handleUserError = (error, options = {}) => {
51218
51242
  * `handleUserError` (a plain message — no "Something went wrong", prefilled
51219
51243
  * issue, Discord link, or Sentry reference), since there is no bug to report.
51220
51244
  *
51221
- * Three distinct shapes reach the CLI's catch blocks:
51245
+ * Four distinct shapes reach the CLI's catch blocks:
51222
51246
  *
51223
51247
  * - **Project-discovery failures** (`NoReactDependencyError`,
51224
51248
  * `ProjectNotFoundError`, `PackageJsonNotFoundError`, `NotADirectoryError`,
@@ -51231,12 +51255,19 @@ const handleUserError = (error, options = {}) => {
51231
51255
  * `--project` name.
51232
51256
  * - **Bad `--diff` input** (`GitBaseBranchInvalid` / `GitBaseBranchMissing`)
51233
51257
  * stays the tagged `ReactDoctorError`, so dispatch on the reason `_tag`.
51258
+ * - **Environment failures** (`ENOSPC`, `EIO`, `EROFS`, `EACCES`, `EPERM`,
51259
+ * `ENOTDIR`, plus a `spawn`-scoped `ENOENT` for a missing binary) — disk
51260
+ * full / failing / read-only, permission denied, or a path blocked by a
51261
+ * file. React Doctor cannot fix the user's environment; exit cleanly with an
51262
+ * actionable message instead of crashing. See `is-environment-error.ts` for
51263
+ * why the set stays narrow (codes that usually mean our bug keep reaching
51264
+ * Sentry).
51234
51265
  *
51235
51266
  * This composes the existing core narrowers rather than introducing a new
51236
51267
  * error-shape helper (AGENTS.md): it encodes CLI-layer reporting policy, not
51237
51268
  * knowledge of the `ReactDoctorError` shape.
51238
51269
  */
51239
- const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
51270
+ const isExpectedUserError = (error) => error instanceof CliInputError || isProjectDiscoveryError(error) || isEnvironmentError(error) || isReactDoctorError(error) && (error.reason._tag === "GitBaseBranchInvalid" || error.reason._tag === "GitBaseBranchMissing");
51240
51271
  //#endregion
51241
51272
  //#region src/cli/utils/build-handoff-payload.ts
51242
51273
  const buildHandoffPayload = (input) => {
@@ -51317,6 +51348,20 @@ const detectAvailableAgents = async () => {
51317
51348
  const detected = new Set([...detectPathAvailableAgents(), ...await detectInstalledSkillAgents()]);
51318
51349
  return getSkillAgentTypes().filter((agent) => agent !== "universal" && detected.has(agent));
51319
51350
  };
51351
+ const DEFAULT_INSTALL_AGENTS = [
51352
+ "claude-code",
51353
+ "cursor",
51354
+ "codex",
51355
+ "opencode"
51356
+ ];
51357
+ const computeDefaultSelectedAgents = (detectedAgents, rememberedAgents) => {
51358
+ const detected = new Set(detectedAgents);
51359
+ const remembered = rememberedAgents.filter((agent) => detected.has(agent));
51360
+ if (remembered.length > 0) return remembered;
51361
+ const defaults = DEFAULT_INSTALL_AGENTS.filter((agent) => detected.has(agent));
51362
+ if (defaults.length > 0) return defaults;
51363
+ return detectedAgents.length === 1 ? [...detectedAgents] : [];
51364
+ };
51320
51365
  //#endregion
51321
51366
  //#region src/cli/utils/install-doctor-script.ts
51322
51367
  const DOCTOR_SCRIPT_NAME = "doctor";
@@ -51398,7 +51443,7 @@ const installDoctorScript = (options) => {
51398
51443
  };
51399
51444
  })();
51400
51445
  const scriptStatus = scriptTarget.status;
51401
- if (scriptStatus === "created") writeJsonFile$1(packageJsonPath, {
51446
+ if (scriptStatus === "created") writeJsonFile(packageJsonPath, {
51402
51447
  ...packageJson,
51403
51448
  scripts: {
51404
51449
  ...isRecord$1(scripts) ? scripts : {},
@@ -51969,6 +52014,19 @@ const setUpGitHubActions = async (options) => {
51969
52014
  return didCreateWorkflow;
51970
52015
  };
51971
52016
  //#endregion
52017
+ //#region src/cli/utils/install-agents-preference.ts
52018
+ const INSTALL_AGENTS_PREFERENCE = {
52019
+ id: INSTALL_AGENTS_PREFERENCE_ID,
52020
+ scope: "global"
52021
+ };
52022
+ const PREFERENCE_SEPARATOR = ",";
52023
+ const readInstallAgents = (options = {}) => {
52024
+ const stored = readPreference(INSTALL_AGENTS_PREFERENCE, {}, options);
52025
+ if (stored === null) return [];
52026
+ return stored.split(PREFERENCE_SEPARATOR).map((entry) => entry.trim()).filter((entry) => isSkillAgentType(entry));
52027
+ };
52028
+ const rememberInstallAgents = (agents, options = {}) => writePreference(INSTALL_AGENTS_PREFERENCE, agents.join(PREFERENCE_SEPARATOR), {}, options);
52029
+ //#endregion
51972
52030
  //#region src/cli/utils/install-agent-hooks.ts
51973
52031
  const CLAUDE_AGENT = "claude-code";
51974
52032
  const CURSOR_AGENT = "cursor";
@@ -51979,20 +52037,34 @@ const CURSOR_HOOKS_RELATIVE_PATH = ".cursor/hooks.json";
51979
52037
  const CURSOR_HOOK_RELATIVE_PATH = ".cursor/hooks/react-doctor.sh";
51980
52038
  const CURSOR_HOOK_MATCHER = "Write|Edit|MultiEdit|ApplyPatch";
51981
52039
  const CURSOR_HOOKS_SCHEMA_VERSION = 1;
51982
- const JSON_INDENT_SPACES$1 = 2;
51983
52040
  const isSupportedAgent = (agent) => agent === CLAUDE_AGENT || agent === CURSOR_AGENT;
51984
52041
  const readJsonFile = (filePath, fallback) => {
51985
52042
  if (!NFS.existsSync(filePath)) return fallback;
51986
52043
  const content = NFS.readFileSync(filePath, "utf8").trim();
51987
52044
  if (content.length === 0) return fallback;
51988
- return JSON.parse(content);
52045
+ try {
52046
+ return JSON.parse(content);
52047
+ } catch (error) {
52048
+ 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.`);
52049
+ throw error;
52050
+ }
51989
52051
  };
51990
- const writeJsonFile = (filePath, value) => {
51991
- NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
51992
- NFS.writeFileSync(filePath, `${JSON.stringify(value, null, JSON_INDENT_SPACES$1)}\n`);
52052
+ const ensureDirectoryExists = (directoryPath) => {
52053
+ try {
52054
+ NFS.mkdirSync(directoryPath, { recursive: true });
52055
+ } catch (error) {
52056
+ const code = error.code;
52057
+ 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.`);
52058
+ 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.`);
52059
+ throw error;
52060
+ }
52061
+ };
52062
+ const writeJsonFileWithDirectoryCheck = (filePath, value) => {
52063
+ ensureDirectoryExists(Path.dirname(filePath));
52064
+ writeJsonFile(filePath, value);
51993
52065
  };
51994
52066
  const writeHookScript = (filePath) => {
51995
- NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
52067
+ ensureDirectoryExists(Path.dirname(filePath));
51996
52068
  NFS.writeFileSync(filePath, buildAgentHookScript());
51997
52069
  NFS.chmodSync(filePath, 493);
51998
52070
  };
@@ -52008,7 +52080,7 @@ const installClaudeHook = (projectRoot) => {
52008
52080
  command: CLAUDE_HOOK_COMMAND
52009
52081
  }] });
52010
52082
  hooks.PostToolBatch = postToolBatchHooks;
52011
- writeJsonFile(settingsPath, {
52083
+ writeJsonFileWithDirectoryCheck(settingsPath, {
52012
52084
  ...settings,
52013
52085
  hooks
52014
52086
  });
@@ -52028,7 +52100,7 @@ const installCursorHook = (projectRoot) => {
52028
52100
  timeout: 120
52029
52101
  });
52030
52102
  hooks.postToolUse = postToolUseHooks;
52031
- writeJsonFile(configPath, {
52103
+ writeJsonFileWithDirectoryCheck(configPath, {
52032
52104
  ...config,
52033
52105
  version: config.version ?? CURSOR_HOOKS_SCHEMA_VERSION,
52034
52106
  hooks
@@ -52264,7 +52336,7 @@ const installPackageJsonHook = (options, strategy) => {
52264
52336
  parent = cloned;
52265
52337
  }
52266
52338
  parent[leafKey] = strategy.leafShape === "array" ? appendArrayCommand(parent[leafKey]) : appendStringCommand(parent[leafKey]);
52267
- writeJsonFile$1(packageJsonPath, nextPackageJson);
52339
+ writeJsonFile(packageJsonPath, nextPackageJson);
52268
52340
  removeLegacyManagedRunner(options.projectRoot);
52269
52341
  return {
52270
52342
  hookPath: packageJsonPath,
@@ -52847,6 +52919,9 @@ const runInstallReactDoctor = async (options = {}) => {
52847
52919
  const shouldUpgradeWorkflow = canUpgradeWorkflow && (Boolean(options.yes) || upgradePromptOutcome === "yes");
52848
52920
  if (upgradePromptOutcome === "no" && !options.dryRun) recordActionUpgradeDecision(projectRoot, "declined");
52849
52921
  if ((ciPromptOutcome === "yes" || ciPromptOutcome === "no") && !options.dryRun) recordCiPromptDecision(projectRoot, ciPromptOutcome === "yes" ? "accepted" : "declined");
52922
+ const rememberedAgents = options.lastSelectedAgents ?? readInstallAgents();
52923
+ const defaultSelectedAgents = computeDefaultSelectedAgents(detectedAgents, rememberedAgents);
52924
+ const usedRememberedAgents = rememberedAgents.some((agent) => detectedAgents.includes(agent));
52850
52925
  const selectedAgents = skipPrompts ? detectedAgents : (await prompt({
52851
52926
  type: "multiselect",
52852
52927
  name: "agents",
@@ -52854,12 +52929,13 @@ const runInstallReactDoctor = async (options = {}) => {
52854
52929
  choices: detectedAgents.map((agent) => ({
52855
52930
  title: getSkillAgentConfig(agent).displayName,
52856
52931
  value: agent,
52857
- selected: true
52932
+ selected: defaultSelectedAgents.includes(agent)
52858
52933
  })),
52859
52934
  instructions: false,
52860
52935
  min: 1
52861
52936
  }, promptOptions)).agents ?? [];
52862
52937
  if (selectedAgents.length === 0) return;
52938
+ if (!skipPrompts && !options.dryRun) rememberInstallAgents(selectedAgents);
52863
52939
  let dependencyResult;
52864
52940
  if (!options.dryRun) {
52865
52941
  await installReactDoctorSkillStep(sourceDir, selectedAgents, projectRoot);
@@ -52918,6 +52994,8 @@ const runInstallReactDoctor = async (options = {}) => {
52918
52994
  }
52919
52995
  recordCount(METRIC.installCompleted, 1, {
52920
52996
  agentsCount: selectedAgents.length,
52997
+ agentsDetected: detectedAgents.length,
52998
+ usedRememberedAgents,
52921
52999
  gitHook: shouldInstallGitHook,
52922
53000
  agentHooks: shouldInstallAgentHooks,
52923
53001
  workflow: didInstallWorkflow,
@@ -53697,7 +53775,7 @@ const warnDeprecatedDiff = (flags, userConfig) => {
53697
53775
  };
53698
53776
  const warnDiffUnavailable = (requested, isQuiet) => {
53699
53777
  if (isQuiet) return;
53700
- if (typeof requested.base === "string") cliLogger.warn(`Could not compute diff against "${requested.base}" (merge-base failed or HEAD has no history). Running full scan.`);
53778
+ 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
53779
  else cliLogger.warn("No feature branch or uncommitted changes detected. Running full scan.");
53702
53780
  cliLogger.break();
53703
53781
  };
@@ -54001,69 +54079,6 @@ const warnDeprecatedFailOn = (flags, userConfig) => {
54001
54079
  cliLogger.warn(`${source} is deprecated; rename it to ${replacement}.`);
54002
54080
  };
54003
54081
  //#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
54082
  //#region src/cli/utils/validate-mode-flags.ts
54068
54083
  const usedDiffAlias = (flags) => flags.diff !== void 0 && flags.diff !== false && flags.diff !== "false" && flags.diff !== "";
54069
54084
  const usedScope = (flags) => typeof flags.scope === "string" && flags.scope.length > 0;
@@ -54164,7 +54179,6 @@ const inspectAction = async (directory, flags) => {
54164
54179
  setJsonReportDirectory(resolvedDirectory);
54165
54180
  warnDeprecatedFailOn(flags, userConfig);
54166
54181
  warnDeprecatedDiff(flags, userConfig);
54167
- warnIfAiTrainingEnvironment();
54168
54182
  if (scanTarget.didRedirectViaRootDir && !isQuiet) {
54169
54183
  cliLogger.dim(`Redirected to ${highlighter.info(toRelativePath(resolvedDirectory, requestedDirectory))} via react-doctor config "rootDir".`);
54170
54184
  cliLogger.break();
@@ -54452,6 +54466,10 @@ const installAction = async (options, command) => {
54452
54466
  projectRoot: options.cwd ?? process.cwd()
54453
54467
  });
54454
54468
  } catch (error) {
54469
+ if (isExpectedUserError(error)) {
54470
+ handleUserError(error);
54471
+ return;
54472
+ }
54455
54473
  handleError(error, { sentryEventId: await reportErrorToSentry(error) });
54456
54474
  }
54457
54475
  };
@@ -55459,4 +55477,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
55459
55477
  export {};
55460
55478
 
55461
55479
  //# sourceMappingURL=cli.js.map
55462
- //# debugId=34e4ad65-2650-5e3e-afd8-191931eb2a47
55480
+ //# debugId=89eea142-f3f2-5f35-a6b0-e9e10055d0cb
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]="1ef7f287-5a83-55e9-a20b-41145ffdda43")}catch(e){}}();
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]="62d09923-e78d-5501-8799-859098af2aaa")}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";
@@ -34487,7 +34487,10 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
34487
34487
  NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.set(nativeRuleKey, aliases);
34488
34488
  }
34489
34489
  const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
34490
- const canonicalizeRuleKey = (ruleKey) => LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey] ?? ruleKey;
34490
+ const canonicalizeRuleKey = (ruleKey) => {
34491
+ const nativeRuleKey = LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey];
34492
+ return typeof nativeRuleKey === "string" ? nativeRuleKey : ruleKey;
34493
+ };
34491
34494
  const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
34492
34495
  const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
34493
34496
  const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
@@ -35577,6 +35580,12 @@ const BOOLEAN_FIELD_NAMES = [
35577
35580
  "adoptExistingLintConfig"
35578
35581
  ];
35579
35582
  const STRING_FIELD_NAMES = ["rootDir"];
35583
+ const STRING_ARRAY_FIELD_NAMES = [
35584
+ "projects",
35585
+ "textComponents",
35586
+ "rawTextWrapperComponents",
35587
+ "serverAuthFunctionNames"
35588
+ ];
35580
35589
  const SURFACE_CONTROL_FIELD_NAMES = [
35581
35590
  "includeTags",
35582
35591
  "excludeTags",
@@ -35678,6 +35687,7 @@ const validateConfigTypes = (config) => {
35678
35687
  const validated = { ...config };
35679
35688
  for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
35680
35689
  for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
35690
+ for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
35681
35691
  applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
35682
35692
  for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
35683
35693
  applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
@@ -37931,7 +37941,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
37931
37941
  "rev-parse",
37932
37942
  "--verify",
37933
37943
  branch
37934
- ]).pipe(map$3((result) => result.status === 0));
37944
+ ]).pipe(map$3((result) => result.status === 0), catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(false) : fail$4(error)));
37935
37945
  const headSha = (directory) => runGit(directory, ["rev-parse", "HEAD"]).pipe(map$3((result) => result.status === 0 ? trimOrNull(result.stdout) : null));
37936
37946
  const mergeBase = (input) => isSafeGitRevision(input.ref) ? runGit(input.directory, [
37937
37947
  "merge-base",
@@ -41342,64 +41352,6 @@ const mergeReactDoctorConfigs = (baseConfig, overrideConfig) => {
41342
41352
  };
41343
41353
  //#endregion
41344
41354
  //#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
41355
  const buildDiagnoseLayer = (config, configOverrideTarget) => {
41404
41356
  const configLayer = configOverrideTarget === void 0 ? Config.layerNode : Config.layerOf({
41405
41357
  config,
@@ -41437,7 +41389,6 @@ const outputToDiagnoseResult = (output, elapsedMilliseconds) => {
41437
41389
  };
41438
41390
  };
41439
41391
  const diagnoseDirectory = async (directory, options) => {
41440
- warnIfAiTrainingEnvironment();
41441
41392
  const startTime = globalThis.performance.now();
41442
41393
  const scanTarget = await resolveScanTarget(directory);
41443
41394
  return outputToDiagnoseResult(await runPromise(restoreLegacyThrow(buildInspectProgram(scanTarget, options).pipe(provide(buildDiagnoseLayer(scanTarget.userConfig)), provide(layerOtlp)))), globalThis.performance.now() - startTime);
@@ -41484,7 +41435,6 @@ const diagnoseProject = async (projectDefinition, baseOptions, batchConfig) => {
41484
41435
  }
41485
41436
  };
41486
41437
  const diagnoseProjectBatch = async (input) => {
41487
- warnIfAiTrainingEnvironment();
41488
41438
  const startTime = globalThis.performance.now();
41489
41439
  const { projects, concurrency, config: batchConfig, ...baseOptions } = input;
41490
41440
  const projectResults = await mapWithConcurrency(projects, concurrency ?? 4, (projectDefinition) => diagnoseProject(projectDefinition, baseOptions, batchConfig));
@@ -41529,4 +41479,4 @@ const toJsonReport = (result, options) => buildJsonReport({
41529
41479
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
41530
41480
 
41531
41481
  //# sourceMappingURL=index.js.map
41532
- //# debugId=1ef7f287-5a83-55e9-a20b-41145ffdda43
41482
+ //# debugId=62d09923-e78d-5501-8799-859098af2aaa
package/dist/lsp.js CHANGED
@@ -34546,7 +34546,10 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
34546
34546
  NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.set(nativeRuleKey, aliases);
34547
34547
  }
34548
34548
  const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
34549
- const canonicalizeRuleKey = (ruleKey) => LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey] ?? ruleKey;
34549
+ const canonicalizeRuleKey = (ruleKey) => {
34550
+ const nativeRuleKey = LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey];
34551
+ return typeof nativeRuleKey === "string" ? nativeRuleKey : ruleKey;
34552
+ };
34550
34553
  const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
34551
34554
  const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
34552
34555
  const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
@@ -35610,6 +35613,12 @@ const BOOLEAN_FIELD_NAMES = [
35610
35613
  "adoptExistingLintConfig"
35611
35614
  ];
35612
35615
  const STRING_FIELD_NAMES = ["rootDir"];
35616
+ const STRING_ARRAY_FIELD_NAMES = [
35617
+ "projects",
35618
+ "textComponents",
35619
+ "rawTextWrapperComponents",
35620
+ "serverAuthFunctionNames"
35621
+ ];
35613
35622
  const SURFACE_CONTROL_FIELD_NAMES = [
35614
35623
  "includeTags",
35615
35624
  "excludeTags",
@@ -35711,6 +35720,7 @@ const validateConfigTypes = (config) => {
35711
35720
  const validated = { ...config };
35712
35721
  for (const fieldName of BOOLEAN_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => coerceMaybeBooleanString(fieldName, value));
35713
35722
  for (const fieldName of STRING_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateString(fieldName, value));
35723
+ for (const fieldName of STRING_ARRAY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateStringArrayField(fieldName, value));
35714
35724
  applyFieldValidator(config, validated, "surfaces", validateSurfacesField);
35715
35725
  for (const fieldName of SEVERITY_FIELD_NAMES) applyFieldValidator(config, validated, fieldName, (value) => validateSeverityMap(fieldName, value, fieldName === "categories"));
35716
35726
  applyFieldValidator(config, validated, "plugins", (value) => validateStringArrayField("plugins", value));
@@ -37916,7 +37926,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
37916
37926
  "rev-parse",
37917
37927
  "--verify",
37918
37928
  branch
37919
- ]).pipe(map$3((result) => result.status === 0));
37929
+ ]).pipe(map$3((result) => result.status === 0), catch_$1((error) => error.reason._tag === "GitInvocationFailed" ? succeed$2(false) : fail$4(error)));
37920
37930
  const headSha = (directory) => runGit(directory, ["rev-parse", "HEAD"]).pipe(map$3((result) => result.status === 0 ? trimOrNull(result.stdout) : null));
37921
37931
  const mergeBase = (input) => isSafeGitRevision(input.ref) ? runGit(input.directory, [
37922
37932
  "merge-base",
@@ -42903,6 +42913,7 @@ const SENTRY_FLUSH_TIMEOUT_MS = 2e3;
42903
42913
  const METRIC = {
42904
42914
  cliInvoked: "cli.invoked",
42905
42915
  cliError: "cli.error",
42916
+ cliEnvironmentError: "cli.env_error",
42906
42917
  projectDetected: "project.detected",
42907
42918
  projectPathSelected: "project.path_selected",
42908
42919
  projectConfigSelected: "project.config_selected",
@@ -43249,5 +43260,5 @@ const startLanguageServer = () => {
43249
43260
  };
43250
43261
  //#endregion
43251
43262
  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]="9ee72ccc-703c-588f-b7e4-c92657144721")}catch(e){}}();
43253
- //# debugId=9ee72ccc-703c-588f-b7e4-c92657144721
43263
+ !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]="1b85b637-9e6d-554c-a429-3652a14706b0")}catch(e){}}();
43264
+ //# debugId=1b85b637-9e6d-554c-a429-3652a14706b0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.5.8-dev.70ae19f",
3
+ "version": "0.5.8-dev.734c564",
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": "SEE LICENSE IN LICENSE",
23
+ "license": "MIT",
24
24
  "author": "Million Software, Inc",
25
25
  "repository": {
26
26
  "type": "git",
@@ -64,7 +64,7 @@
64
64
  "vscode-languageserver-textdocument": "^1.0.12",
65
65
  "vscode-uri": "^3.1.0",
66
66
  "deslop-js": "0.5.8",
67
- "oxlint-plugin-react-doctor": "0.5.8-dev.70ae19f"
67
+ "oxlint-plugin-react-doctor": "0.5.8-dev.734c564"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/babel__code-frame": "^7.27.0",