react-doctor 0.8.2 → 0.8.3-dev.3d7ea66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,17 +27,7 @@ npx react-doctor@latest
27
27
 
28
28
  https://github.com/user-attachments/assets/07cc88d9-9589-44c3-aa73-5d603cb1c570
29
29
 
30
- ### 2. Run a focused design audit
31
-
32
- Use the design command when you only want UI composition, typography, interaction, accessibility, and motion findings:
33
-
34
- ```bash
35
- npx react-doctor@latest design
36
- ```
37
-
38
- This activates the complete design rule family, including focused rules that stay opt-in during a general health scan, and skips unrelated dead-code, supply-chain, custom-plugin, and health-score passes. It accepts the normal scan flags, including `--scope`, `--project`, `--verbose`, and `--json`.
39
-
40
- ### 3. Install for agents
30
+ ### 2. Install for agents
41
31
 
42
32
  Once you have an audit, you can install the skill for your coding agent to learn from the issues and fix them in the future.
43
33
 
@@ -47,7 +37,7 @@ npx react-doctor@latest install
47
37
 
48
38
  Works with Claude Code, Cursor, Codex, OpenCode, and many more.
49
39
 
50
- ### 4. Run in CI
40
+ ### 3. Run in CI
51
41
 
52
42
  React Doctor reviews every pull request and reports only the issues your change introduced, not your existing backlog. Set it up with one command:
53
43
 
@@ -59,20 +49,12 @@ This adds the workflow, scans every pull request, and posts a summary comment. C
59
49
 
60
50
  [CI docs →](https://react.doctor/ci)
61
51
 
62
- ### 5. Configure rules
52
+ ### 4. Configure rules
63
53
 
64
54
  You can configure which rules to run and how to run them in `doctor.config.ts`.
65
55
 
66
56
  [Learn more →](https://react.doctor/docs/configuration/config-files)
67
57
 
68
- ### 6. Consume JSON
69
-
70
- Use `--json` for stdout or `--json-out <path>` for a file. The default
71
- `schemaVersion: 3` report includes deterministic diagnostic IDs and exact
72
- per-project scan coverage.
73
-
74
- [JSON report contract →](./docs/json-report.md)
75
-
76
58
  ## Telemetry
77
59
 
78
60
  The CLI reports crashes, basic run traces, and anonymous usage counters to [Sentry](https://sentry.io/) to help us fix bugs and prioritize work.
package/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]="d5409106-40c9-567e-8099-f25e0a9b48d4")}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]="729213e0-f120-5159-8212-e0a881c2cf17")}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";
@@ -64656,6 +64656,13 @@ const IGNORED_DIRECTORIES = new Set([
64656
64656
  "storybook-static"
64657
64657
  ]);
64658
64658
  const JSX_FILE_PATTERN = /\.(tsx|jsx)$/;
64659
+ const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
64660
+ const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
64661
+ "TS(1036)",
64662
+ "TS(1038)",
64663
+ "TS(1183)",
64664
+ "TS(1319)"
64665
+ ]);
64659
64666
  const MILLISECONDS_PER_SECOND = 1e3;
64660
64667
  const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
64661
64668
  {
@@ -64979,7 +64986,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
64979
64986
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
64980
64987
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
64981
64988
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
64982
- const CORE_PACKAGE_VERSION = "0.8.2";
64989
+ const CORE_PACKAGE_VERSION = "0.8.3";
64983
64990
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
64984
64991
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
64985
64992
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -73188,13 +73195,13 @@ const decodeFileDiagnostics = (raw) => {
73188
73195
  }
73189
73196
  };
73190
73197
  const emptyCache$1 = () => ({
73191
- version: 1,
73198
+ version: 2,
73192
73199
  rulesets: {}
73193
73200
  });
73194
73201
  const loadRulesetEntries$1 = (cacheFilePath, rulesetHash) => {
73195
73202
  const entries = /* @__PURE__ */ new Map();
73196
73203
  const persisted = failOpenReadJson(cacheFilePath, emptyCache$1());
73197
- if (persisted.version !== 1 || !isRecord$1(persisted.rulesets)) return entries;
73204
+ if (persisted.version !== 2 || !isRecord$1(persisted.rulesets)) return entries;
73198
73205
  const bucket = persisted.rulesets[rulesetHash];
73199
73206
  if (!isRecord$1(bucket) || !isRecord$1(bucket.files)) return entries;
73200
73207
  for (const [fileKey, rawDiagnostics] of Object.entries(bucket.files)) {
@@ -73214,7 +73221,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
73214
73221
  },
73215
73222
  persist: () => {
73216
73223
  const onDisk = failOpenReadJson(cacheFilePath, emptyCache$1());
73217
- const rulesets = onDisk.version === 1 && isRecord$1(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
73224
+ const rulesets = onDisk.version === 2 && isRecord$1(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
73218
73225
  const existingBucket = rulesets[rulesetHash];
73219
73226
  const existingFiles = isRecord$1(existingBucket) && isRecord$1(existingBucket.files) ? existingBucket.files : {};
73220
73227
  const ourFiles = {};
@@ -73228,7 +73235,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
73228
73235
  files: Object.fromEntries(cappedEntries)
73229
73236
  };
73230
73237
  atomicWriteJson(cacheFilePath, {
73231
- version: 1,
73238
+ version: 2,
73232
73239
  rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord$1(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
73233
73240
  });
73234
73241
  }
@@ -73317,13 +73324,13 @@ const encodeSidecarFileEntry = (entry) => ({
73317
73324
  diagnostics: entry.diagnostics
73318
73325
  });
73319
73326
  const emptyCache = () => ({
73320
- version: 2,
73327
+ version: 3,
73321
73328
  rulesets: {}
73322
73329
  });
73323
73330
  const loadRulesetEntries = (cacheFilePath, rulesetHash) => {
73324
73331
  const entries = /* @__PURE__ */ new Map();
73325
73332
  const persisted = failOpenReadJson(cacheFilePath, emptyCache());
73326
- if (persisted.version !== 2 || !isRecord$1(persisted.rulesets)) return entries;
73333
+ if (persisted.version !== 3 || !isRecord$1(persisted.rulesets)) return entries;
73327
73334
  const bucket = persisted.rulesets[rulesetHash];
73328
73335
  if (!isRecord$1(bucket) || !isRecord$1(bucket.files)) return entries;
73329
73336
  for (const [fileKey, rawEntry] of Object.entries(bucket.files)) {
@@ -73343,7 +73350,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
73343
73350
  },
73344
73351
  persist: () => {
73345
73352
  const onDisk = failOpenReadJson(cacheFilePath, emptyCache());
73346
- const rulesets = onDisk.version === 2 && isRecord$1(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
73353
+ const rulesets = onDisk.version === 3 && isRecord$1(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
73347
73354
  const existingBucket = rulesets[rulesetHash];
73348
73355
  const existingFiles = isRecord$1(existingBucket) && isRecord$1(existingBucket.files) ? existingBucket.files : {};
73349
73356
  const ourFiles = {};
@@ -73357,7 +73364,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
73357
73364
  files: Object.fromEntries(cappedEntries)
73358
73365
  };
73359
73366
  atomicWriteJson(cacheFilePath, {
73360
- version: 2,
73367
+ version: 3,
73361
73368
  rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord$1(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
73362
73369
  });
73363
73370
  }
@@ -74290,7 +74297,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
74290
74297
  minifiedFileCache.set(absolutePath, minified);
74291
74298
  return minified;
74292
74299
  };
74293
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
74300
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
74294
74301
  const { plugin, rule } = parseRuleCode(diagnostic.code);
74295
74302
  const primaryLabel = diagnostic.labels[0];
74296
74303
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
@@ -77391,7 +77398,7 @@ const makeNoopConsole = () => ({
77391
77398
  });
77392
77399
  //#endregion
77393
77400
  //#region src/cli/utils/version.ts
77394
- const VERSION = "0.8.2";
77401
+ const VERSION = "0.8.3-dev.3d7ea66";
77395
77402
  //#endregion
77396
77403
  //#region src/cli/utils/json-mode.ts
77397
77404
  let context = null;
@@ -77749,13 +77756,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
77749
77756
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
77750
77757
  * standard `SENTRY_RELEASE` override.
77751
77758
  */
77752
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.2`;
77759
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.3-dev.3d7ea66`;
77753
77760
  /**
77754
77761
  * Deployment environment shown in Sentry's environment filter. Defaults to
77755
77762
  * `production` for tagged releases and `development` for dev/unbuilt versions,
77756
77763
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
77757
77764
  */
77758
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.2") ? "development" : "production");
77765
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.3-dev.3d7ea66") ? "development" : "production");
77759
77766
  /**
77760
77767
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
77761
77768
  * (set to `0` to disable tracing) and falls back to
@@ -89977,12 +89984,12 @@ const resolveCacheFilePath = (projectDirectory) => path.join(resolveReactDoctorC
89977
89984
  const readPersistedCache = (cacheFilePath) => {
89978
89985
  try {
89979
89986
  const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
89980
- if (!isRecord(parsed) || parsed.version !== 5) return {
89981
- version: 5,
89987
+ if (!isRecord(parsed) || parsed.version !== 6) return {
89988
+ version: 6,
89982
89989
  entries: []
89983
89990
  };
89984
89991
  if (!Array.isArray(parsed.entries)) return {
89985
- version: 5,
89992
+ version: 6,
89986
89993
  entries: []
89987
89994
  };
89988
89995
  const entries = [];
@@ -89992,12 +89999,12 @@ const readPersistedCache = (cacheFilePath) => {
89992
89999
  entries.push(entry);
89993
90000
  }
89994
90001
  return {
89995
- version: 5,
90002
+ version: 6,
89996
90003
  entries
89997
90004
  };
89998
90005
  } catch {
89999
90006
  return {
90000
- version: 5,
90007
+ version: 6,
90001
90008
  entries: []
90002
90009
  };
90003
90010
  }
@@ -90059,7 +90066,7 @@ const buildScanResultCacheKey = (input) => {
90059
90066
  if (headSha === null) return null;
90060
90067
  if (stringifyStableJson(input.userConfig) === null) return null;
90061
90068
  const cacheKeyJson = stringifyStableJson({
90062
- schemaVersion: 5,
90069
+ schemaVersion: 6,
90063
90070
  projectIdentity: resolveProjectIdentity(input.projectDirectory),
90064
90071
  headSha,
90065
90072
  worktreeFingerprint,
@@ -90102,7 +90109,7 @@ const createScanResultCache = (projectDirectory) => {
90102
90109
  for (const entry of persistedCache.entries) entries.set(entry.key, entry);
90103
90110
  const persist = () => {
90104
90111
  writePersistedCache(cacheFilePath, {
90105
- version: 5,
90112
+ version: 6,
90106
90113
  entries: [...entries.values()].sort((firstEntry, secondEntry) => secondEntry.createdAtMs - firstEntry.createdAtMs).slice(0, 20)
90107
90114
  });
90108
90115
  };
@@ -96476,4 +96483,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
96476
96483
  export {};
96477
96484
 
96478
96485
  //# sourceMappingURL=cli.js.map
96479
- //# debugId=d5409106-40c9-567e-8099-f25e0a9b48d4
96486
+ //# debugId=729213e0-f120-5159-8212-e0a881c2cf17
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]="c9b50d38-1251-547e-8985-91c7948c205c")}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]="cf84418d-5713-5c93-95cf-6a6747b9f247")}catch(e){}}();
3
3
  import { i as __toESM$1, r as __require, t as __commonJSMin$1 } from "./chunk-ChKA3wi6.js";
4
4
  import { createRequire } from "node:module";
5
5
  import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
@@ -61487,6 +61487,13 @@ const IGNORED_DIRECTORIES = new Set([
61487
61487
  "out",
61488
61488
  "storybook-static"
61489
61489
  ]);
61490
+ const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
61491
+ const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
61492
+ "TS(1036)",
61493
+ "TS(1038)",
61494
+ "TS(1183)",
61495
+ "TS(1319)"
61496
+ ]);
61490
61497
  const MILLISECONDS_PER_SECOND = 1e3;
61491
61498
  const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
61492
61499
  {
@@ -61777,7 +61784,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
61777
61784
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
61778
61785
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
61779
61786
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
61780
- const CORE_PACKAGE_VERSION = "0.8.2";
61787
+ const CORE_PACKAGE_VERSION = "0.8.3";
61781
61788
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
61782
61789
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
61783
61790
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -69948,13 +69955,13 @@ const decodeFileDiagnostics = (raw) => {
69948
69955
  }
69949
69956
  };
69950
69957
  const emptyCache$1 = () => ({
69951
- version: 1,
69958
+ version: 2,
69952
69959
  rulesets: {}
69953
69960
  });
69954
69961
  const loadRulesetEntries$1 = (cacheFilePath, rulesetHash) => {
69955
69962
  const entries = /* @__PURE__ */ new Map();
69956
69963
  const persisted = failOpenReadJson(cacheFilePath, emptyCache$1());
69957
- if (persisted.version !== 1 || !isRecord(persisted.rulesets)) return entries;
69964
+ if (persisted.version !== 2 || !isRecord(persisted.rulesets)) return entries;
69958
69965
  const bucket = persisted.rulesets[rulesetHash];
69959
69966
  if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
69960
69967
  for (const [fileKey, rawDiagnostics] of Object.entries(bucket.files)) {
@@ -69974,7 +69981,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
69974
69981
  },
69975
69982
  persist: () => {
69976
69983
  const onDisk = failOpenReadJson(cacheFilePath, emptyCache$1());
69977
- const rulesets = onDisk.version === 1 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
69984
+ const rulesets = onDisk.version === 2 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
69978
69985
  const existingBucket = rulesets[rulesetHash];
69979
69986
  const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
69980
69987
  const ourFiles = {};
@@ -69988,7 +69995,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
69988
69995
  files: Object.fromEntries(cappedEntries)
69989
69996
  };
69990
69997
  atomicWriteJson(cacheFilePath, {
69991
- version: 1,
69998
+ version: 2,
69992
69999
  rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
69993
70000
  });
69994
70001
  }
@@ -70077,13 +70084,13 @@ const encodeSidecarFileEntry = (entry) => ({
70077
70084
  diagnostics: entry.diagnostics
70078
70085
  });
70079
70086
  const emptyCache = () => ({
70080
- version: 2,
70087
+ version: 3,
70081
70088
  rulesets: {}
70082
70089
  });
70083
70090
  const loadRulesetEntries = (cacheFilePath, rulesetHash) => {
70084
70091
  const entries = /* @__PURE__ */ new Map();
70085
70092
  const persisted = failOpenReadJson(cacheFilePath, emptyCache());
70086
- if (persisted.version !== 2 || !isRecord(persisted.rulesets)) return entries;
70093
+ if (persisted.version !== 3 || !isRecord(persisted.rulesets)) return entries;
70087
70094
  const bucket = persisted.rulesets[rulesetHash];
70088
70095
  if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
70089
70096
  for (const [fileKey, rawEntry] of Object.entries(bucket.files)) {
@@ -70103,7 +70110,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
70103
70110
  },
70104
70111
  persist: () => {
70105
70112
  const onDisk = failOpenReadJson(cacheFilePath, emptyCache());
70106
- const rulesets = onDisk.version === 2 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
70113
+ const rulesets = onDisk.version === 3 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
70107
70114
  const existingBucket = rulesets[rulesetHash];
70108
70115
  const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
70109
70116
  const ourFiles = {};
@@ -70117,7 +70124,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
70117
70124
  files: Object.fromEntries(cappedEntries)
70118
70125
  };
70119
70126
  atomicWriteJson(cacheFilePath, {
70120
- version: 2,
70127
+ version: 3,
70121
70128
  rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
70122
70129
  });
70123
70130
  }
@@ -71050,7 +71057,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
71050
71057
  minifiedFileCache.set(absolutePath, minified);
71051
71058
  return minified;
71052
71059
  };
71053
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
71060
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
71054
71061
  const { plugin, rule } = parseRuleCode(diagnostic.code);
71055
71062
  const primaryLabel = diagnostic.labels[0];
71056
71063
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
@@ -73867,4 +73874,4 @@ const toJsonReport = (result, options) => buildJsonReport({
73867
73874
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
73868
73875
 
73869
73876
  //# sourceMappingURL=index.js.map
73870
- //# debugId=c9b50d38-1251-547e-8985-91c7948c205c
73877
+ //# debugId=cf84418d-5713-5c93-95cf-6a6747b9f247
package/dist/lsp.js CHANGED
@@ -61517,6 +61517,13 @@ const IGNORED_DIRECTORIES = new Set([
61517
61517
  "out",
61518
61518
  "storybook-static"
61519
61519
  ]);
61520
+ const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
61521
+ const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
61522
+ "TS(1036)",
61523
+ "TS(1038)",
61524
+ "TS(1183)",
61525
+ "TS(1319)"
61526
+ ]);
61520
61527
  const MILLISECONDS_PER_SECOND = 1e3;
61521
61528
  const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
61522
61529
  {
@@ -61830,7 +61837,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
61830
61837
  const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
61831
61838
  const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
61832
61839
  const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
61833
- const CORE_PACKAGE_VERSION = "0.8.2";
61840
+ const CORE_PACKAGE_VERSION = "0.8.3";
61834
61841
  const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
61835
61842
  const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
61836
61843
  const SUPPLY_CHAIN_PLUGIN = "socket";
@@ -69927,13 +69934,13 @@ const decodeFileDiagnostics = (raw) => {
69927
69934
  }
69928
69935
  };
69929
69936
  const emptyCache$1 = () => ({
69930
- version: 1,
69937
+ version: 2,
69931
69938
  rulesets: {}
69932
69939
  });
69933
69940
  const loadRulesetEntries$1 = (cacheFilePath, rulesetHash) => {
69934
69941
  const entries = /* @__PURE__ */ new Map();
69935
69942
  const persisted = failOpenReadJson(cacheFilePath, emptyCache$1());
69936
- if (persisted.version !== 1 || !isRecord(persisted.rulesets)) return entries;
69943
+ if (persisted.version !== 2 || !isRecord(persisted.rulesets)) return entries;
69937
69944
  const bucket = persisted.rulesets[rulesetHash];
69938
69945
  if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
69939
69946
  for (const [fileKey, rawDiagnostics] of Object.entries(bucket.files)) {
@@ -69953,7 +69960,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
69953
69960
  },
69954
69961
  persist: () => {
69955
69962
  const onDisk = failOpenReadJson(cacheFilePath, emptyCache$1());
69956
- const rulesets = onDisk.version === 1 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
69963
+ const rulesets = onDisk.version === 2 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
69957
69964
  const existingBucket = rulesets[rulesetHash];
69958
69965
  const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
69959
69966
  const ourFiles = {};
@@ -69967,7 +69974,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
69967
69974
  files: Object.fromEntries(cappedEntries)
69968
69975
  };
69969
69976
  atomicWriteJson(cacheFilePath, {
69970
- version: 1,
69977
+ version: 2,
69971
69978
  rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
69972
69979
  });
69973
69980
  }
@@ -70056,13 +70063,13 @@ const encodeSidecarFileEntry = (entry) => ({
70056
70063
  diagnostics: entry.diagnostics
70057
70064
  });
70058
70065
  const emptyCache = () => ({
70059
- version: 2,
70066
+ version: 3,
70060
70067
  rulesets: {}
70061
70068
  });
70062
70069
  const loadRulesetEntries = (cacheFilePath, rulesetHash) => {
70063
70070
  const entries = /* @__PURE__ */ new Map();
70064
70071
  const persisted = failOpenReadJson(cacheFilePath, emptyCache());
70065
- if (persisted.version !== 2 || !isRecord(persisted.rulesets)) return entries;
70072
+ if (persisted.version !== 3 || !isRecord(persisted.rulesets)) return entries;
70066
70073
  const bucket = persisted.rulesets[rulesetHash];
70067
70074
  if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
70068
70075
  for (const [fileKey, rawEntry] of Object.entries(bucket.files)) {
@@ -70082,7 +70089,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
70082
70089
  },
70083
70090
  persist: () => {
70084
70091
  const onDisk = failOpenReadJson(cacheFilePath, emptyCache());
70085
- const rulesets = onDisk.version === 2 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
70092
+ const rulesets = onDisk.version === 3 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
70086
70093
  const existingBucket = rulesets[rulesetHash];
70087
70094
  const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
70088
70095
  const ourFiles = {};
@@ -70096,7 +70103,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
70096
70103
  files: Object.fromEntries(cappedEntries)
70097
70104
  };
70098
70105
  atomicWriteJson(cacheFilePath, {
70099
- version: 2,
70106
+ version: 3,
70100
70107
  rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
70101
70108
  });
70102
70109
  }
@@ -71029,7 +71036,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
71029
71036
  minifiedFileCache.set(absolutePath, minified);
71030
71037
  return minified;
71031
71038
  };
71032
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
71039
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
71033
71040
  const { plugin, rule } = parseRuleCode(diagnostic.code);
71034
71041
  const primaryLabel = diagnostic.labels[0];
71035
71042
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
@@ -73458,7 +73465,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
73458
73465
  /** Display name used in client-facing messages and progress titles. */
73459
73466
  const SERVER_DISPLAY_NAME = "React Doctor";
73460
73467
  /** Server version reported in `serverInfo`; injected at build, `dev` from source. */
73461
- const SERVER_VERSION = "0.8.2";
73468
+ const SERVER_VERSION = "0.8.3";
73462
73469
  /** `Diagnostic.source` shown next to every published diagnostic. */
73463
73470
  const DIAGNOSTIC_SOURCE = "react-doctor";
73464
73471
  /**
@@ -74139,7 +74146,7 @@ const createLintCache = (input) => {
74139
74146
  let persistTimer = null;
74140
74147
  try {
74141
74148
  const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
74142
- if (parsed.version === 2 && parsed.fingerprint === input.fingerprint) for (const [fsPath, entry] of Object.entries(parsed.entries)) entries.set(fsPath, entry);
74149
+ if (parsed.version === 3 && parsed.fingerprint === input.fingerprint) for (const [fsPath, entry] of Object.entries(parsed.entries)) entries.set(fsPath, entry);
74143
74150
  } catch {}
74144
74151
  const persist = () => {
74145
74152
  if (persistTimer) {
@@ -74150,7 +74157,7 @@ const createLintCache = (input) => {
74150
74157
  dirty = false;
74151
74158
  try {
74152
74159
  const payload = {
74153
- version: 2,
74160
+ version: 3,
74154
74161
  fingerprint: input.fingerprint,
74155
74162
  entries: Object.fromEntries(entries)
74156
74163
  };
@@ -75488,5 +75495,5 @@ const startLanguageServer = () => {
75488
75495
  };
75489
75496
  //#endregion
75490
75497
  export { startLanguageServer };
75491
- !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]="eb779168-479d-50b0-b8fc-ca4184330b93")}catch(e){}}();
75492
- //# debugId=eb779168-479d-50b0-b8fc-ca4184330b93
75498
+ !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]="97b31424-577f-5b74-ac26-46212d2f1aaf")}catch(e){}}();
75499
+ //# debugId=97b31424-577f-5b74-ac26-46212d2f1aaf
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.8.2",
3
+ "version": "0.8.3-dev.3d7ea66",
4
4
  "description": "Your agent writes bad React. This catches it",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -58,15 +58,15 @@
58
58
  "eslint-plugin-react-hooks": "^7.1.1",
59
59
  "jiti": "^2.7.0",
60
60
  "magicast": "^0.5.3",
61
- "oxlint": ">=1.66.0 <1.67.0",
61
+ "oxlint": ">=1.74.0 <1.75.0",
62
62
  "prompts": "^2.4.2",
63
63
  "typescript": ">=5.0.4 <6",
64
64
  "vscode-languageserver": "^9.0.1",
65
65
  "vscode-languageserver-textdocument": "^1.0.12",
66
66
  "vscode-uri": "^3.1.0",
67
67
  "yaml": "^2.9.0",
68
- "deslop-js": "0.8.2",
69
- "oxlint-plugin-react-doctor": "0.8.2"
68
+ "deslop-js": "0.8.3",
69
+ "oxlint-plugin-react-doctor": "0.8.3-dev.3d7ea66"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/babel__code-frame": "^7.27.0",
@@ -74,9 +74,9 @@
74
74
  "@xterm/headless": "^6.0.0",
75
75
  "commander": "^14.0.3",
76
76
  "ora": "^9.4.0",
77
- "@react-doctor/api": "0.8.2",
78
- "@react-doctor/core": "0.8.2",
79
- "@react-doctor/language-server": "0.8.2"
77
+ "@react-doctor/api": "0.8.3",
78
+ "@react-doctor/core": "0.8.3",
79
+ "@react-doctor/language-server": "0.8.3"
80
80
  },
81
81
  "engines": {
82
82
  "node": "^20.19.0 || >=22.13.0"