react-doctor 0.5.6-dev.5d1347e → 0.5.6-dev.66133f8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lsp.js CHANGED
@@ -14,7 +14,7 @@ import * as NodeUrl from "node:url";
14
14
  import { fileURLToPath } from "node:url";
15
15
  import { createJiti } from "jiti";
16
16
  import * as Crypto from "node:crypto";
17
- import crypto from "node:crypto";
17
+ import crypto, { createHash } from "node:crypto";
18
18
  import { gzipSync } from "node:zlib";
19
19
  import { CodeActionKind, CodeActionTriggerKind, DidChangeWatchedFilesNotification, DocumentDiagnosticReportKind, FileChangeType, TextDocumentSyncKind, TextDocuments, createConnection } from "vscode-languageserver/node.js";
20
20
  import { TextDocument } from "vscode-languageserver-textdocument";
@@ -19286,7 +19286,8 @@ var Diagnostic = class extends Class("Diagnostic")({
19286
19286
  category: String$1,
19287
19287
  fileContext: optional(Literals(["test", "story"])),
19288
19288
  suppressionHint: optional(String$1),
19289
- relatedLocations: optional(ArraySchema(DiagnosticRelatedLocation))
19289
+ relatedLocations: optional(ArraySchema(DiagnosticRelatedLocation)),
19290
+ fixGroupId: optional(String$1)
19290
19291
  }) {};
19291
19292
  /**
19292
19293
  * Deterministic identity string for a diagnostic. Same diagnostic
@@ -19335,6 +19336,7 @@ var JsonReportProjectEntry = class extends Class("JsonReportProjectEntry")({
19335
19336
  score: Unknown,
19336
19337
  skippedChecks: ArraySchema(String$1),
19337
19338
  skippedCheckReasons: optional(Record$1(String$1, String$1)),
19339
+ scannedFileCount: optional(Number$1),
19338
19340
  elapsedMilliseconds: Number$1
19339
19341
  }) {};
19340
19342
  /**
@@ -33720,6 +33722,13 @@ const APP_ONLY_RULE_KEYS = new Set([
33720
33722
  ]);
33721
33723
  const COMPILER_CLEANUP_BUCKET = "compiler-cleanup";
33722
33724
  const COMPILER_CLEANUP_RULE_KEYS = new Set(["react-doctor/react-compiler-no-manual-memoization"]);
33725
+ const ROOT_CAUSE_GROUPABLE_RULE_KEYS = new Set([
33726
+ "react-doctor/no-derived-state",
33727
+ "react-doctor/no-derived-state-effect",
33728
+ "react-doctor/no-derived-useState",
33729
+ "react-doctor/no-adjust-state-on-prop-change",
33730
+ "react-doctor/no-reset-all-state-on-prop-change"
33731
+ ]);
33723
33732
  const MAX_GLOB_PATTERN_LENGTH_CHARS = 1024;
33724
33733
  const CONFIG_CACHE_TTL_MS = 300 * 1e3;
33725
33734
  const SOCKET_FREE_PURL_API_BASE = "https://firewall-api.socket.dev/purl";
@@ -34297,115 +34306,6 @@ const buildRuleSeverityControls = (config) => {
34297
34306
  ...config.buckets !== void 0 ? { buckets: config.buckets } : {}
34298
34307
  };
34299
34308
  };
34300
- const JSX_OPENER_TAG_PATTERN = /<[A-Za-z][\w.]*/g;
34301
- const JSX_TAG_NAME_FOLLOW = /[A-Za-z]/;
34302
- const isOpenerMatchInsideLineComment = (line, openerCharIndex) => {
34303
- let stringDelimiter = null;
34304
- for (let charIndex = 0; charIndex < openerCharIndex; charIndex++) {
34305
- const character = line[charIndex];
34306
- if (stringDelimiter !== null) {
34307
- if (character === "\\") {
34308
- charIndex++;
34309
- continue;
34310
- }
34311
- if (character === stringDelimiter) stringDelimiter = null;
34312
- continue;
34313
- }
34314
- if (character === "\"" || character === "'" || character === "`") {
34315
- stringDelimiter = character;
34316
- continue;
34317
- }
34318
- if (character === "/" && line[charIndex + 1] === "/") return true;
34319
- }
34320
- return false;
34321
- };
34322
- const findOpenerTagOnLine = (line) => {
34323
- for (const match of line.matchAll(JSX_OPENER_TAG_PATTERN)) {
34324
- if (match.index === void 0) continue;
34325
- if (!isOpenerMatchInsideLineComment(line, match.index)) return { startCharIndex: match.index + match[0].length };
34326
- }
34327
- return null;
34328
- };
34329
- const findJsxOpenerSpan = (lines, openerLineIndex) => {
34330
- const openerLine = lines[openerLineIndex];
34331
- if (openerLine === void 0) return null;
34332
- const opener = findOpenerTagOnLine(openerLine);
34333
- if (!opener) return null;
34334
- const lookaheadLimit = Math.min(lines.length, openerLineIndex + 32);
34335
- let braceDepth = 0;
34336
- let innerAngleDepth = 0;
34337
- let stringDelimiter = null;
34338
- for (let lineIndex = openerLineIndex; lineIndex < lookaheadLimit; lineIndex++) {
34339
- const currentLine = lines[lineIndex];
34340
- const startCharForLine = lineIndex === openerLineIndex ? opener.startCharIndex : 0;
34341
- for (let charIndex = startCharForLine; charIndex < currentLine.length; charIndex++) {
34342
- const character = currentLine[charIndex];
34343
- if (stringDelimiter !== null) {
34344
- if (character === "\\") {
34345
- charIndex++;
34346
- continue;
34347
- }
34348
- if (character === stringDelimiter) stringDelimiter = null;
34349
- continue;
34350
- }
34351
- if (character === "\"" || character === "'" || character === "`") {
34352
- stringDelimiter = character;
34353
- continue;
34354
- }
34355
- if (character === "{") {
34356
- braceDepth++;
34357
- continue;
34358
- }
34359
- if (character === "}") {
34360
- braceDepth--;
34361
- continue;
34362
- }
34363
- if (braceDepth !== 0) continue;
34364
- if (character === "<") {
34365
- const followCharacter = currentLine[charIndex + 1];
34366
- if (followCharacter !== void 0 && JSX_TAG_NAME_FOLLOW.test(followCharacter)) innerAngleDepth++;
34367
- continue;
34368
- }
34369
- if (character !== ">") continue;
34370
- const previousCharacter = currentLine[charIndex - 1];
34371
- const nextCharacter = currentLine[charIndex + 1];
34372
- if (previousCharacter === "=" || nextCharacter === "=") continue;
34373
- if (innerAngleDepth > 0) {
34374
- innerAngleDepth--;
34375
- continue;
34376
- }
34377
- return lineIndex;
34378
- }
34379
- }
34380
- return null;
34381
- };
34382
- const findEnclosingMultilineJsxOpenerStart = (lines, diagnosticLineIndex) => {
34383
- for (let candidateIndex = diagnosticLineIndex - 1; candidateIndex >= 0 && diagnosticLineIndex - candidateIndex <= 32; candidateIndex--) {
34384
- const openerCloseIndex = findJsxOpenerSpan(lines, candidateIndex);
34385
- if (openerCloseIndex !== null && openerCloseIndex >= diagnosticLineIndex) return candidateIndex;
34386
- }
34387
- return null;
34388
- };
34389
- const DISABLE_NEXT_LINE_PATTERN = /(?:\/\/|\/\*)\s*react-doctor-disable-next-line\b(?:\s+([^\r\n]*?))?\s*(?:\*\/)?\s*\}?\s*$/;
34390
- const findStackedDisableCommentsAbove = (lines, anchorIndex) => {
34391
- const collected = [];
34392
- let isStillInChain = true;
34393
- for (let candidateIndex = anchorIndex - 1; candidateIndex >= 0 && anchorIndex - candidateIndex <= 10; candidateIndex--) {
34394
- const candidateLine = lines[candidateIndex];
34395
- if (candidateLine === void 0) break;
34396
- const match = candidateLine.match(DISABLE_NEXT_LINE_PATTERN);
34397
- if (match) {
34398
- collected.push({
34399
- commentLineIndex: candidateIndex,
34400
- ruleList: match[1],
34401
- isInChain: isStillInChain
34402
- });
34403
- continue;
34404
- }
34405
- isStillInChain = false;
34406
- }
34407
- return collected;
34408
- };
34409
34309
  const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
34410
34310
  "effect/no-adjust-state-on-prop-change": "react-doctor/no-adjust-state-on-prop-change",
34411
34311
  "effect/no-chain-state-updates": "react-doctor/no-chain-state-updates",
@@ -34530,7 +34430,13 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
34530
34430
  }
34531
34431
  const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
34532
34432
  const canonicalizeRuleKey = (ruleKey) => LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey] ?? ruleKey;
34533
- const isSameRuleKey = (candidateRuleKey, targetRuleKey) => canonicalizeRuleKey(candidateRuleKey) === canonicalizeRuleKey(targetRuleKey);
34433
+ const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
34434
+ const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
34435
+ const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
34436
+ const canonicalTarget = canonicalizeRuleKey(targetRuleKey);
34437
+ if (canonicalCandidate === canonicalTarget) return true;
34438
+ return isReactDoctorShortIdOf(canonicalCandidate, canonicalTarget) || isReactDoctorShortIdOf(canonicalTarget, canonicalCandidate);
34439
+ };
34534
34440
  const getEquivalentRuleKeys = (ruleKey) => {
34535
34441
  const nativeRuleKey = canonicalizeRuleKey(ruleKey);
34536
34442
  return [nativeRuleKey, ...getLegacyRuleKeysForNative(nativeRuleKey)];
@@ -34540,12 +34446,182 @@ const stripDescriptionTail = (ruleList) => {
34540
34446
  if (!descriptionMatch || descriptionMatch.index === void 0) return ruleList;
34541
34447
  return ruleList.slice(0, descriptionMatch.index);
34542
34448
  };
34543
- const isRuleListedInComment = (ruleList, ruleId) => {
34449
+ const tokenizeRuleList = (ruleList) => {
34544
34450
  const trimmed = ruleList?.trim();
34545
- if (!trimmed) return true;
34451
+ if (!trimmed) return [];
34546
34452
  const ruleSection = stripDescriptionTail(trimmed).trim();
34547
- if (!ruleSection) return true;
34548
- return ruleSection.split(/[,\s]+/).some((token) => isSameRuleKey(token.trim(), ruleId));
34453
+ if (!ruleSection) return [];
34454
+ return ruleSection.split(/[,\s]+/).map((token) => token.trim()).filter(Boolean);
34455
+ };
34456
+ const FOREIGN_INLINE_DISABLE_PATTERN = /(?:\/\/|\/\*)[ \t]*(eslint|oxlint)-disable-(next-line|line)(?![\w-])([^\r\n]*)/;
34457
+ const FOREIGN_BLOCK_DISABLE_PATTERN = /\/\*[ \t]*(eslint|oxlint)-disable(?![\w-])([^*\r\n]*)/;
34458
+ const FOREIGN_BLOCK_ENABLE_PATTERN = /\/\*[ \t]*(?:eslint|oxlint)-enable(?![\w-])([^*\r\n]*)/;
34459
+ const buildHint = (tool, token, ruleId) => `oxlint matches plugin rules only by their full name, so \`${token}\` in your ${tool}-disable comment does not silence \`${ruleId}\` — change it to \`${ruleId}\`.`;
34460
+ const tokenMisnamesRule = (token, ruleId) => token !== ruleId && isSameRuleKey(token, ruleId);
34461
+ const detectInlineNearMiss = (lines, diagnosticLineIndex, ruleId) => {
34462
+ const candidates = [{
34463
+ line: lines[diagnosticLineIndex],
34464
+ requiredScope: "line"
34465
+ }, {
34466
+ line: lines[diagnosticLineIndex - 1],
34467
+ requiredScope: "next-line"
34468
+ }];
34469
+ for (const { line, requiredScope } of candidates) {
34470
+ const match = line?.match(FOREIGN_INLINE_DISABLE_PATTERN);
34471
+ if (!match) continue;
34472
+ const [, tool, scope, ruleList] = match;
34473
+ if (scope !== requiredScope) continue;
34474
+ const tokens = tokenizeRuleList(ruleList);
34475
+ if (tokens.includes(ruleId)) continue;
34476
+ for (const token of tokens) if (tokenMisnamesRule(token, ruleId)) return buildHint(tool, token, ruleId);
34477
+ }
34478
+ return null;
34479
+ };
34480
+ const detectBlockNearMiss = (lines, diagnosticLineIndex, ruleId) => {
34481
+ let openMisname = null;
34482
+ const lastLineIndex = Math.min(diagnosticLineIndex, lines.length - 1);
34483
+ for (let lineIndex = 0; lineIndex <= lastLineIndex; lineIndex++) {
34484
+ const line = lines[lineIndex];
34485
+ if (line === void 0 || !line.includes("-disable") && !line.includes("-enable")) continue;
34486
+ const disableMatch = line.match(FOREIGN_BLOCK_DISABLE_PATTERN);
34487
+ if (disableMatch) {
34488
+ const [, tool, ruleList] = disableMatch;
34489
+ const tokens = tokenizeRuleList(ruleList);
34490
+ if (tokens.includes(ruleId)) openMisname = null;
34491
+ else {
34492
+ const misnamed = tokens.find((token) => tokenMisnamesRule(token, ruleId));
34493
+ if (misnamed) openMisname = {
34494
+ tool,
34495
+ token: misnamed
34496
+ };
34497
+ }
34498
+ continue;
34499
+ }
34500
+ const enableMatch = line.match(FOREIGN_BLOCK_ENABLE_PATTERN);
34501
+ if (enableMatch) {
34502
+ const enabledRules = tokenizeRuleList(enableMatch[1]);
34503
+ if (enabledRules.length === 0 || enabledRules.some((rule) => isSameRuleKey(rule, ruleId))) openMisname = null;
34504
+ }
34505
+ }
34506
+ return openMisname ? buildHint(openMisname.tool, openMisname.token, ruleId) : null;
34507
+ };
34508
+ const detectForeignDisableNearMiss = (lines, diagnosticLineIndex, ruleId) => {
34509
+ if (!ruleId.startsWith("react-doctor/")) return null;
34510
+ return detectInlineNearMiss(lines, diagnosticLineIndex, ruleId) ?? detectBlockNearMiss(lines, diagnosticLineIndex, ruleId);
34511
+ };
34512
+ const JSX_OPENER_TAG_PATTERN = /<[A-Za-z][\w.]*/g;
34513
+ const JSX_TAG_NAME_FOLLOW = /[A-Za-z]/;
34514
+ const isOpenerMatchInsideLineComment = (line, openerCharIndex) => {
34515
+ let stringDelimiter = null;
34516
+ for (let charIndex = 0; charIndex < openerCharIndex; charIndex++) {
34517
+ const character = line[charIndex];
34518
+ if (stringDelimiter !== null) {
34519
+ if (character === "\\") {
34520
+ charIndex++;
34521
+ continue;
34522
+ }
34523
+ if (character === stringDelimiter) stringDelimiter = null;
34524
+ continue;
34525
+ }
34526
+ if (character === "\"" || character === "'" || character === "`") {
34527
+ stringDelimiter = character;
34528
+ continue;
34529
+ }
34530
+ if (character === "/" && line[charIndex + 1] === "/") return true;
34531
+ }
34532
+ return false;
34533
+ };
34534
+ const findOpenerTagOnLine = (line) => {
34535
+ for (const match of line.matchAll(JSX_OPENER_TAG_PATTERN)) {
34536
+ if (match.index === void 0) continue;
34537
+ if (!isOpenerMatchInsideLineComment(line, match.index)) return { startCharIndex: match.index + match[0].length };
34538
+ }
34539
+ return null;
34540
+ };
34541
+ const findJsxOpenerSpan = (lines, openerLineIndex) => {
34542
+ const openerLine = lines[openerLineIndex];
34543
+ if (openerLine === void 0) return null;
34544
+ const opener = findOpenerTagOnLine(openerLine);
34545
+ if (!opener) return null;
34546
+ const lookaheadLimit = Math.min(lines.length, openerLineIndex + 32);
34547
+ let braceDepth = 0;
34548
+ let innerAngleDepth = 0;
34549
+ let stringDelimiter = null;
34550
+ for (let lineIndex = openerLineIndex; lineIndex < lookaheadLimit; lineIndex++) {
34551
+ const currentLine = lines[lineIndex];
34552
+ const startCharForLine = lineIndex === openerLineIndex ? opener.startCharIndex : 0;
34553
+ for (let charIndex = startCharForLine; charIndex < currentLine.length; charIndex++) {
34554
+ const character = currentLine[charIndex];
34555
+ if (stringDelimiter !== null) {
34556
+ if (character === "\\") {
34557
+ charIndex++;
34558
+ continue;
34559
+ }
34560
+ if (character === stringDelimiter) stringDelimiter = null;
34561
+ continue;
34562
+ }
34563
+ if (character === "\"" || character === "'" || character === "`") {
34564
+ stringDelimiter = character;
34565
+ continue;
34566
+ }
34567
+ if (character === "{") {
34568
+ braceDepth++;
34569
+ continue;
34570
+ }
34571
+ if (character === "}") {
34572
+ braceDepth--;
34573
+ continue;
34574
+ }
34575
+ if (braceDepth !== 0) continue;
34576
+ if (character === "<") {
34577
+ const followCharacter = currentLine[charIndex + 1];
34578
+ if (followCharacter !== void 0 && JSX_TAG_NAME_FOLLOW.test(followCharacter)) innerAngleDepth++;
34579
+ continue;
34580
+ }
34581
+ if (character !== ">") continue;
34582
+ const previousCharacter = currentLine[charIndex - 1];
34583
+ const nextCharacter = currentLine[charIndex + 1];
34584
+ if (previousCharacter === "=" || nextCharacter === "=") continue;
34585
+ if (innerAngleDepth > 0) {
34586
+ innerAngleDepth--;
34587
+ continue;
34588
+ }
34589
+ return lineIndex;
34590
+ }
34591
+ }
34592
+ return null;
34593
+ };
34594
+ const findEnclosingMultilineJsxOpenerStart = (lines, diagnosticLineIndex) => {
34595
+ for (let candidateIndex = diagnosticLineIndex - 1; candidateIndex >= 0 && diagnosticLineIndex - candidateIndex <= 32; candidateIndex--) {
34596
+ const openerCloseIndex = findJsxOpenerSpan(lines, candidateIndex);
34597
+ if (openerCloseIndex !== null && openerCloseIndex >= diagnosticLineIndex) return candidateIndex;
34598
+ }
34599
+ return null;
34600
+ };
34601
+ const DISABLE_NEXT_LINE_PATTERN = /(?:\/\/|\/\*)\s*react-doctor-disable-next-line\b(?:\s+([^\r\n]*?))?\s*(?:\*\/)?\s*\}?\s*$/;
34602
+ const findStackedDisableCommentsAbove = (lines, anchorIndex) => {
34603
+ const collected = [];
34604
+ let isStillInChain = true;
34605
+ for (let candidateIndex = anchorIndex - 1; candidateIndex >= 0 && anchorIndex - candidateIndex <= 10; candidateIndex--) {
34606
+ const candidateLine = lines[candidateIndex];
34607
+ if (candidateLine === void 0) break;
34608
+ const match = candidateLine.match(DISABLE_NEXT_LINE_PATTERN);
34609
+ if (match) {
34610
+ collected.push({
34611
+ commentLineIndex: candidateIndex,
34612
+ ruleList: match[1],
34613
+ isInChain: isStillInChain
34614
+ });
34615
+ continue;
34616
+ }
34617
+ isStillInChain = false;
34618
+ }
34619
+ return collected;
34620
+ };
34621
+ const isRuleListedInComment = (ruleList, ruleId) => {
34622
+ const tokens = tokenizeRuleList(ruleList);
34623
+ if (tokens.length === 0) return true;
34624
+ return tokens.some((token) => isSameRuleKey(token, ruleId));
34549
34625
  };
34550
34626
  const DISABLE_LINE_PATTERN = /(?:\/\/|\/\*)\s*react-doctor-disable-line\b(?:\s+([^\r\n]*?))?\s*(?:\*\/)?\s*\}?\s*$/;
34551
34627
  const formatLineGap = (gapLineCount) => `${gapLineCount} line${gapLineCount === 1 ? "" : "s"}`;
@@ -34589,7 +34665,7 @@ const evaluateSuppression = (lines, diagnosticLineIndex, ruleId) => {
34589
34665
  };
34590
34666
  return {
34591
34667
  isSuppressed: false,
34592
- nearMissHint: classifyFromComments([directComments, openerComments], diagnosticLineIndex, ruleId)
34668
+ nearMissHint: classifyFromComments([directComments, openerComments], diagnosticLineIndex, ruleId) ?? detectForeignDisableNearMiss(lines, diagnosticLineIndex, ruleId)
34593
34669
  };
34594
34670
  };
34595
34671
  /**
@@ -35518,6 +35594,29 @@ const resolveConfigRootDir = (config, configSourceDirectory) => {
35518
35594
  }
35519
35595
  return resolvedRootDir;
35520
35596
  };
35597
+ const buildFixGroupId = (diagnostic) => createHash("sha1").update(JSON.stringify([
35598
+ diagnostic.filePath,
35599
+ `${diagnostic.plugin}/${diagnostic.rule}`,
35600
+ diagnostic.message
35601
+ ])).digest("hex").slice(0, 16);
35602
+ const isGroupableRule = (diagnostic) => ROOT_CAUSE_GROUPABLE_RULE_KEYS.has(`${diagnostic.plugin}/${diagnostic.rule}`);
35603
+ const assignFixGroups = (diagnostics) => {
35604
+ const siteCountByGroupId = /* @__PURE__ */ new Map();
35605
+ for (const diagnostic of diagnostics) {
35606
+ if (!isGroupableRule(diagnostic)) continue;
35607
+ const groupId = buildFixGroupId(diagnostic);
35608
+ siteCountByGroupId.set(groupId, (siteCountByGroupId.get(groupId) ?? 0) + 1);
35609
+ }
35610
+ return diagnostics.map((diagnostic) => {
35611
+ if (!isGroupableRule(diagnostic)) return diagnostic;
35612
+ const groupId = buildFixGroupId(diagnostic);
35613
+ if ((siteCountByGroupId.get(groupId) ?? 0) < 2) return diagnostic;
35614
+ return {
35615
+ ...diagnostic,
35616
+ fixGroupId: groupId
35617
+ };
35618
+ });
35619
+ };
35521
35620
  const getDirectDependencyNames = (packageJson) => new Set([...Object.keys(packageJson.dependencies ?? {}), ...Object.keys(packageJson.devDependencies ?? {})]);
35522
35621
  const buildExpoCheckContext = (rootDirectory, expoVersion) => {
35523
35622
  const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
@@ -39964,12 +40063,12 @@ const runInspect = (input, hooks = {}) => gen(function* () {
39964
40063
  else if (input.suppressScanSummary) yield* scanProgress.stop();
39965
40064
  else yield* scanProgress.succeed(`Scanned ${scannedFilesLabel} in ${scanElapsedSeconds}s${workerCountSuffix}`);
39966
40065
  yield* reporterService.finalize;
39967
- const finalDiagnostics = [
40066
+ const finalDiagnostics = assignFixGroups([
39968
40067
  ...envCollected,
39969
40068
  ...supplyChainCollected,
39970
40069
  ...lintCollected,
39971
40070
  ...deadCodeCollected
39972
- ];
40071
+ ]);
39973
40072
  const githubViewerPermission = yield* join(githubViewerPermissionFiber);
39974
40073
  const scoreMetadata = {
39975
40074
  ...repo !== null ? { repo } : {},
@@ -42377,5 +42476,5 @@ const startLanguageServer = () => {
42377
42476
  };
42378
42477
  //#endregion
42379
42478
  export { startLanguageServer };
42380
- !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]="7b102472-d01e-5d6a-9975-91795fe8abc5")}catch(e){}}();
42381
- //# debugId=7b102472-d01e-5d6a-9975-91795fe8abc5
42479
+ !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]="6fbf847f-43b8-5c5c-ba97-c26c2e08e250")}catch(e){}}();
42480
+ //# debugId=6fbf847f-43b8-5c5c-ba97-c26c2e08e250
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.5.6-dev.5d1347e",
3
+ "version": "0.5.6-dev.66133f8",
4
4
  "description": "Your agent writes bad React. This catches it",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -64,7 +64,7 @@
64
64
  "vscode-languageserver": "^9.0.1",
65
65
  "vscode-languageserver-textdocument": "^1.0.12",
66
66
  "vscode-uri": "^3.1.0",
67
- "oxlint-plugin-react-doctor": "0.5.6-dev.5d1347e"
67
+ "oxlint-plugin-react-doctor": "0.5.6-dev.66133f8"
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.6",
76
- "@react-doctor/language-server": "0.5.6",
77
- "@react-doctor/core": "0.5.6"
76
+ "@react-doctor/core": "0.5.6",
77
+ "@react-doctor/language-server": "0.5.6"
78
78
  },
79
79
  "engines": {
80
80
  "node": "^20.19.0 || >=22.13.0"