diff --git a/.changeset/action-blocking-default-advisory.md b/.changeset/action-blocking-default-advisory.md
deleted file mode 100644
index d80e6714c..000000000
--- a/.changeset/action-blocking-default-advisory.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-"react-doctor": patch
----
-
-The GitHub Action's `blocking` input now defaults to `none` (advisory) instead of `error`. Every PR still gets the full React Doctor report — the sticky summary comment, inline review comments, and a commit status with the health score — but the check no longer fails on findings, so a brand-new install can't red-X a teammate's PR on day one (trust-before-gate). To turn the gate back on, set `blocking: warning` (fail on any finding) or `blocking: error` (fail on error-severity findings) on the action. The generated `react-doctor.yml` documents this inline.
-
-Note: this changes behavior for existing `millionco/react-doctor@v2` workflows that never set `blocking` — they were gating on error-severity findings and will now run advisory. Add `blocking: error` to the action's `with:` block to keep the previous behavior.
-
-The CLI / config default is unchanged: `react-doctor` (and `--blocking` / the `blocking` config key) still defaults to `error`, so local runs, pre-commit hooks, and non-action CI keep failing on error-severity findings.
diff --git a/.changeset/bump-node-engines.md b/.changeset/bump-node-engines.md
deleted file mode 100644
index 7f2c24dd2..000000000
--- a/.changeset/bump-node-engines.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-"react-doctor": patch
-"eslint-plugin-react-doctor": patch
-"oxlint-plugin-react-doctor": patch
----
-
-Bump `engines.node` to `^20.19.0 || >=22.13.0` so the declared support range matches transitive dependencies (`eslint-scope@9`, `eslint-visitor-keys@5` require `^22.13.0`), preventing EBADENGINE warnings on npm and hard install failures on Yarn 1 under Node 22.12.x.
diff --git a/.changeset/bundle-effect-for-cli.md b/.changeset/bundle-effect-for-cli.md
deleted file mode 100644
index 758b2de93..000000000
--- a/.changeset/bundle-effect-for-cli.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Bundle Effect into the published CLI so `npx react-doctor@latest` no longer installs Effect's `ini@7` dependency and avoids the Node 22.19 engine warning.
diff --git a/.changeset/cap-oxlint-below-1-67.md b/.changeset/cap-oxlint-below-1-67.md
deleted file mode 100644
index 8b1fbcd32..000000000
--- a/.changeset/cap-oxlint-below-1-67.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Cap the `oxlint` dependency to `>=1.66.0 <1.67.0`. oxlint 1.67.0 added an optional peer dependency on `vite-plus`, which in pnpm workspaces that install `vite-plus` at the root forces a second peer-resolution context for the Vite+ toolchain. That split installs a duplicate copy of the Vitest fork (`@voidzero-dev/vite-plus-test`), and test runs fail at collection with `Vitest failed to find the current suite` because hooks register in one copy while suites live in the other (#699). Pinning below 1.67 keeps react-doctor's oxlint free of the `vite-plus` peer edge, so pnpm dedupes the toolchain back to a single instance.
diff --git a/.changeset/compiler-bailout-reason-in-message.md b/.changeset/compiler-bailout-reason-in-message.md
deleted file mode 100644
index e292efdbd..000000000
--- a/.changeset/compiler-bailout-reason-in-message.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Carry the React Compiler bail-out reason in the primary diagnostic message. `react-hooks-js/*` diagnostics previously all rendered the same generic "This component misses React Compiler's automatic memoization…" message, with the specific reason relegated to `help`. The message now includes the first line of the compiler's reason (e.g. `useMemo() callbacks may not be async or generator functions`) so contexts that only show the message explain _why_ the compiler bailed; the reason's remaining lines stay in `help`, so the rendered message + suggestion never repeat the same sentence. `todo` diagnostics keep the generic message — their reasons are compiler-internal work notes, not user-facing copy. Because diagnostics dedupe on their full message, two _different_ bail-out reasons anchored at the same source location now survive as two diagnostics instead of collapsing into one, so counts can rise slightly on affected projects.
diff --git a/.changeset/config-self-import-fallback.md b/.changeset/config-self-import-fallback.md
deleted file mode 100644
index b069b692d..000000000
--- a/.changeset/config-self-import-fallback.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Load `doctor.config.ts` files that import `defineConfig` from `react-doctor/api` even when the scanned repo has no installed node_modules (e.g. the GitHub Action runs the CLI via `npm exec` without installing the repo's dependencies). The config loader now retries the load with `react-doctor/api` aliased to the running package's own copy instead of silently falling back to default config.
diff --git a/.changeset/consolidate-scan-scope-flag.md b/.changeset/consolidate-scan-scope-flag.md
deleted file mode 100644
index b8a12e2af..000000000
--- a/.changeset/consolidate-scan-scope-flag.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-"@react-doctor/core": patch
-"react-doctor": patch
----
-
-Consolidate the scan-scope controls into one `--scope` flag (and `scope` config option) with four values, shared verbatim by the CLI and the GitHub Action:
-
-- `full` (default) — the whole project, every issue. Whole-project checks (dead-code, environment, supply-chain) run only here.
-- `files` — only the files changed vs the base, with all issues in them (no compare-to-main). What `--staged` and an uncommitted `--diff` did.
-- `changed` — only issues the change introduced vs the base (the baseline delta). What `--diff ` and the action's `scope: changed` did.
-- `lines` — only issues on the lines the change actually touched. New: previously this scoping existed only inside the GitHub Action's inline-review-comment step; it now lives in the engine, so the CI gate, score display, summary, and inline comments all honor one scope.
-
-`--base [` sets the comparison base for `files` / `changed` / `lines` (auto-detected when omitted). Behavior is unchanged by default: the CLI `--scope` defaults to `full` and the action `scope` input still defaults to `changed`. `--diff` / `config.diff` keep working as a deprecated alias (`--diff ` → `--scope changed --base `, `--diff false` → `--scope full`) and emit a one-time deprecation warning; `--staged` is retained as the source selector and composes with `--scope files` / `--scope lines`.
diff --git a/.changeset/file-context-labels.md b/.changeset/file-context-labels.md
deleted file mode 100644
index fe288289d..000000000
--- a/.changeset/file-context-labels.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Diagnostics in test, spec, fixture, and Storybook files are now labeled with their file context. The terminal report and the per-rule text dumps tag those sites as `(test file)` / `(story file)` so a finding in a spec doesn't read as a production problem, and each diagnostic in the JSON report carries an optional `fileContext` field (`"test"` / `"story"`; omitted for production files). The classification reuses the same path heuristics that already drive test-noise auto-suppression, so the label and the suppression can never disagree.
diff --git a/.changeset/nextjs-missing-metadata-inherited-layout.md b/.changeset/nextjs-missing-metadata-inherited-layout.md
deleted file mode 100644
index 6a6425909..000000000
--- a/.changeset/nextjs-missing-metadata-inherited-layout.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"oxlint-plugin-react-doctor": patch
-"react-doctor": patch
----
-
-Fix a false positive in `nextjs-missing-metadata` (#775): an App Router page is no longer flagged as "missing metadata for search previews" when it inherits `metadata` / `generateMetadata` from a co-located or ancestor `layout.*`. Next.js merges metadata down the segment chain, so a page covered by a parent layout's title/description already has search-preview metadata. The rule now walks up the App Router directory tree (bounded, stopping at `app/`) and stays quiet when an ancestor layout supplies metadata; pages with no metadata anywhere in the chain are still flagged.
diff --git a/.changeset/no-barrel-import-rn-wording.md b/.changeset/no-barrel-import-rn-wording.md
deleted file mode 100644
index bf32b9579..000000000
--- a/.changeset/no-barrel-import-rn-wording.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"oxlint-plugin-react-doctor": patch
----
-
-`no-barrel-import` messaging is now framework-aware: files that target React Native / Expo (per the nearest `package.json` platform, native/web file extensions, and the project `framework` setting) say the barrel import "ships extra code in your app bundle & slows startup" instead of the web-only "slows page load" wording. Web projects, web-extension files inside RN monorepos, and projects with an unknown framework keep the existing page-load wording.
diff --git a/.changeset/onboarding-pr-default-branch.md b/.changeset/onboarding-pr-default-branch.md
deleted file mode 100644
index 379156bc8..000000000
--- a/.changeset/onboarding-pr-default-branch.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-CI onboarding now resolves the repository's actual default branch instead of assuming `main`. The pull request opened during setup asks GitHub (`gh repo view`) for the default branch — falling back to `origin/HEAD`, then `main`/`master` — and uses it as the PR base, and the installed workflow's push trigger scans that same branch (`master`, `develop`, …) so the health-score trend works on repos whose default branch isn't `main`.
diff --git a/.changeset/only-export-components-framework-route-files.md b/.changeset/only-export-components-framework-route-files.md
deleted file mode 100644
index 72416ba92..000000000
--- a/.changeset/only-export-components-framework-route-files.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-"oxlint-plugin-react-doctor": patch
----
-
-`only-export-components` now recognizes the route/special files of every file-routing framework react-doctor covers and skips them, so the documented "co-export config/metadata next to the default component" shape stops producing false-positive "non-component export" warnings:
-
-- **Next.js** — App Router (`page`, `layout`, `loading`, `error`, `not-found`, `template`, `default`, `global-error`, `route`) and Pages Router (`_app`, `_document`, `_error`) special files, plus metadata image routes (`opengraph-image`, `twitter-image`, `icon`, `apple-icon`, incl. numbered variants), which fixes the `alt` / `size` / `contentType` / `revalidate` exports in `opengraph-image.tsx` ([#776](https://github.com/millionco/react-doctor/issues/776)).
-- **Expo Router** — `_layout` and the `+html` / `+not-found` / `+native-intent` reserved files.
-- **TanStack Router / Start** — `__root` and `*.lazy` route modules.
-- **Remix / React Router** — `root`, `entry.client`, and `entry.server` modules.
diff --git a/.changeset/output-dir-flag.md b/.changeset/output-dir-flag.md
deleted file mode 100644
index bb6bdd564..000000000
--- a/.changeset/output-dir-flag.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"@react-doctor/core": patch
-"react-doctor": patch
----
-
-Add a `--output-dir ` flag that writes the full diagnostics dump (diagnostics.json + one .txt per rule) to a directory of your choice instead of a random temp folder, prints the written path whenever the flag is set (previously `--verbose`-only), and makes the agent handoff reuse that directory instead of writing a second temp copy. Without the flag, behavior is unchanged.
diff --git a/.changeset/react-compiler-todo-title.md b/.changeset/react-compiler-todo-title.md
deleted file mode 100644
index 04d274e93..000000000
--- a/.changeset/react-compiler-todo-title.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Title `react-hooks-js/todo` diagnostics "React Compiler doesn't support this syntax" instead of the generic "React Compiler can't optimize this" headline. The `todo` rule fires when the compiler bails out on syntax it doesn't handle yet, so the headline now says what actually happened.
diff --git a/.changeset/rn-enable-babel-runtime.md b/.changeset/rn-enable-babel-runtime.md
deleted file mode 100644
index d055f8f07..000000000
--- a/.changeset/rn-enable-babel-runtime.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-Add `rn-no-metro-babel-runtime-version` — warns when a babel config uses `module:@react-native/babel-preset` without an `enableBabelRuntime` version. Without a version the preset can duplicate Babel runtime helpers across files instead of importing them once from `@babel/runtime`, increasing the JS bundle (facebook/react-native#57123). It fires as a `warning` (a bundle-size optimization, not a broken build, so it never blocks CI on the default React Native config), only when the preset is referenced as a real string literal (Expo's `babel-preset-expo` and comment mentions are unaffected), and treats `enableBabelRuntime: true`/`false` as still missing a version.
diff --git a/.changeset/rn-no-raw-text-wrapper-false-positive.md b/.changeset/rn-no-raw-text-wrapper-false-positive.md
deleted file mode 100644
index c426b233d..000000000
--- a/.changeset/rn-no-raw-text-wrapper-false-positive.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"oxlint-plugin-react-doctor": patch
-"react-doctor": patch
----
-
-Fix false positives in `rn-no-raw-text` (#788) for custom components that forward their children into a ``: the in-file wrapper detection now recognizes components that render `{children}` (or `{props.children}`) inside a nested `` (the `{children}` shape), not just components whose returned root is a ``. Detection also handles parenthesized `return (...)` bodies, `memo`/`forwardRef`-wrapped components, fragment roots, conditional and logical returns, early returns inside `if` branches, renamed destructured children (`{ children: content }`), the `` prop form, wrappers that forward through another in-file wrapper, children aliased to a variable or destructured from props in the body, props spreads that carry children (``, ``, ``), class components, and `styled(Text)` / `styled.Text` factories. The rule is also tagged `test-noise`, so it no longer fires in test/story files — raw text rendered through React Native Testing Library never ships to users, and cross-file wrappers (an imported `Test Chip` in a `.test.tsx`) were the main source of unfixable noise there.
diff --git a/.changeset/rules-of-hooks-hoc-callback-binding-name.md b/.changeset/rules-of-hooks-hoc-callback-binding-name.md
deleted file mode 100644
index 6affa222f..000000000
--- a/.changeset/rules-of-hooks-hoc-callback-binding-name.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"oxlint-plugin-react-doctor": patch
----
-
-`rules-of-hooks` and `exhaustive-deps` no longer report false positives for hooks called inside a `forwardRef(...)` / `memo(...)` render callback whose binding name is not PascalCase (e.g. `const _Wrapped = forwardRef((props, ref) => { useHook(); ... })`). The render callback passed as the first argument to React's HoCs is a component by construction, so both rules now treat it as one regardless of the variable name it lands on. Only the first argument is promoted — hooks inside `memo`'s second argument (the props comparator) still report, as do genuinely non-component functions like `const _helper = () => { useState(); }`.
diff --git a/.changeset/supply-chain-gate-security-axes.md b/.changeset/supply-chain-gate-security-axes.md
deleted file mode 100644
index 6a65cb327..000000000
--- a/.changeset/supply-chain-gate-security-axes.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"react-doctor": patch
----
-
-The Socket supply-chain check now gates on the security axes (supply chain, vulnerability) instead of Socket's `overall` score, and the diagnostic names the exact axis that failed. Socket's `overall` is its lowest axis, so a package with perfect security scores could fail the Security gate purely on quality/maintenance — `@types/bun` was reported as having a "supply-chain score of 48" while socket.dev showed Supply Chain 100 (issue #770). Known-bad packages (`event-stream@3.3.6`, vulnerable `minimist`/`lodash` releases) are still flagged via their vulnerability axis, and the reported number now always matches the axis named on the socket.dev package page.
diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md
index 44d725f72..02e604a8e 100644
--- a/packages/api/CHANGELOG.md
+++ b/packages/api/CHANGELOG.md
@@ -1,5 +1,12 @@
# @react-doctor/api
+## 0.5.2
+
+### Patch Changes
+
+- Updated dependencies [[`2f26228`](https://github.com/millionco/react-doctor/commit/2f26228e36cfe64a430a41596d7b1053d6d7d307), [`a48fb06`](https://github.com/millionco/react-doctor/commit/a48fb06ffbe7221655e18529fcc954ecae17a22f)]:
+ - @react-doctor/core@0.5.2
+
## 0.5.1
### Patch Changes
diff --git a/packages/api/package.json b/packages/api/package.json
index 6637a92ce..e5bed6f56 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -1,6 +1,6 @@
{
"name": "@react-doctor/api",
- "version": "0.5.1",
+ "version": "0.5.2",
"private": true,
"description": "Internal: programmatic diagnose() API for React Doctor — thin Effect.runPromise shell around @react-doctor/core's runInspect orchestrator. Not published.",
"license": "MIT",
diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md
index f5f6bb380..fb5868237 100644
--- a/packages/core/CHANGELOG.md
+++ b/packages/core/CHANGELOG.md
@@ -1,5 +1,23 @@
# @react-doctor/core
+## 0.5.2
+
+### Patch Changes
+
+- [#769](https://github.com/millionco/react-doctor/pull/769) [`2f26228`](https://github.com/millionco/react-doctor/commit/2f26228e36cfe64a430a41596d7b1053d6d7d307) Thanks [@rayhanadev](https://github.com/rayhanadev)! - Consolidate the scan-scope controls into one `--scope` flag (and `scope` config option) with four values, shared verbatim by the CLI and the GitHub Action:
+
+ - `full` (default) — the whole project, every issue. Whole-project checks (dead-code, environment, supply-chain) run only here.
+ - `files` — only the files changed vs the base, with all issues in them (no compare-to-main). What `--staged` and an uncommitted `--diff` did.
+ - `changed` — only issues the change introduced vs the base (the baseline delta). What `--diff ` and the action's `scope: changed` did.
+ - `lines` — only issues on the lines the change actually touched. New: previously this scoping existed only inside the GitHub Action's inline-review-comment step; it now lives in the engine, so the CI gate, score display, summary, and inline comments all honor one scope.
+
+ `--base ][` sets the comparison base for `files` / `changed` / `lines` (auto-detected when omitted). Behavior is unchanged by default: the CLI `--scope` defaults to `full` and the action `scope` input still defaults to `changed`. `--diff` / `config.diff` keep working as a deprecated alias (`--diff ` → `--scope changed --base `, `--diff false` → `--scope full`) and emit a one-time deprecation warning; `--staged` is retained as the source selector and composes with `--scope files` / `--scope lines`.
+
+- [#783](https://github.com/millionco/react-doctor/pull/783) [`a48fb06`](https://github.com/millionco/react-doctor/commit/a48fb06ffbe7221655e18529fcc954ecae17a22f) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Add a `--output-dir ` flag that writes the full diagnostics dump (diagnostics.json + one .txt per rule) to a directory of your choice instead of a random temp folder, prints the written path whenever the flag is set (previously `--verbose`-only), and makes the agent handoff reuse that directory instead of writing a second temp copy. Without the flag, behavior is unchanged.
+
+- Updated dependencies [[`94f9f4f`](https://github.com/millionco/react-doctor/commit/94f9f4fe98207181958f82275b41d94963bc73a2), [`038aaf7`](https://github.com/millionco/react-doctor/commit/038aaf78c12f7f9a2699f46d3a6aa304dc69fc12), [`fee3fc4`](https://github.com/millionco/react-doctor/commit/fee3fc436e502ad4a6609ab8bda9c9a782d8ecd7), [`c4f0e60`](https://github.com/millionco/react-doctor/commit/c4f0e607b6092485d226c0d67c783270f4eec8b2), [`f52bd07`](https://github.com/millionco/react-doctor/commit/f52bd0737527df9ab81f3746e64bdb5ac1defbc7), [`7c88165`](https://github.com/millionco/react-doctor/commit/7c8816575aff26f11b5099c7ef009c4793fe260f)]:
+ - oxlint-plugin-react-doctor@0.5.2
+
## 0.5.1
### Patch Changes
diff --git a/packages/core/package.json b/packages/core/package.json
index f33912391..32e5dc411 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@react-doctor/core",
- "version": "0.5.1",
+ "version": "0.5.2",
"private": true,
"description": "Internal: diagnostic engine for React Doctor (lint runner, scoring, config, suppressions). Not published.",
"license": "MIT",
diff --git a/packages/eslint-plugin-react-doctor/CHANGELOG.md b/packages/eslint-plugin-react-doctor/CHANGELOG.md
index 557606b21..3cb0dea38 100644
--- a/packages/eslint-plugin-react-doctor/CHANGELOG.md
+++ b/packages/eslint-plugin-react-doctor/CHANGELOG.md
@@ -1,5 +1,14 @@
# eslint-plugin-react-doctor
+## 0.5.2
+
+### Patch Changes
+
+- [#766](https://github.com/millionco/react-doctor/pull/766) [`94f9f4f`](https://github.com/millionco/react-doctor/commit/94f9f4fe98207181958f82275b41d94963bc73a2) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Bump `engines.node` to `^20.19.0 || >=22.13.0` so the declared support range matches transitive dependencies (`eslint-scope@9`, `eslint-visitor-keys@5` require `^22.13.0`), preventing EBADENGINE warnings on npm and hard install failures on Yarn 1 under Node 22.12.x.
+
+- Updated dependencies [[`94f9f4f`](https://github.com/millionco/react-doctor/commit/94f9f4fe98207181958f82275b41d94963bc73a2), [`038aaf7`](https://github.com/millionco/react-doctor/commit/038aaf78c12f7f9a2699f46d3a6aa304dc69fc12), [`fee3fc4`](https://github.com/millionco/react-doctor/commit/fee3fc436e502ad4a6609ab8bda9c9a782d8ecd7), [`c4f0e60`](https://github.com/millionco/react-doctor/commit/c4f0e607b6092485d226c0d67c783270f4eec8b2), [`f52bd07`](https://github.com/millionco/react-doctor/commit/f52bd0737527df9ab81f3746e64bdb5ac1defbc7), [`7c88165`](https://github.com/millionco/react-doctor/commit/7c8816575aff26f11b5099c7ef009c4793fe260f)]:
+ - oxlint-plugin-react-doctor@0.5.2
+
## 0.5.1
### Patch Changes
diff --git a/packages/eslint-plugin-react-doctor/package.json b/packages/eslint-plugin-react-doctor/package.json
index 0e5a62060..4f7bb9567 100644
--- a/packages/eslint-plugin-react-doctor/package.json
+++ b/packages/eslint-plugin-react-doctor/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-react-doctor",
- "version": "0.5.1",
+ "version": "0.5.2",
"description": "ESLint plugin for React Doctor: diagnose React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
"keywords": [
"accessibility",
diff --git a/packages/language-server/CHANGELOG.md b/packages/language-server/CHANGELOG.md
index 3853f8edd..6d05d77de 100644
--- a/packages/language-server/CHANGELOG.md
+++ b/packages/language-server/CHANGELOG.md
@@ -1,5 +1,12 @@
# @react-doctor/language-server
+## 0.5.2
+
+### Patch Changes
+
+- Updated dependencies [[`2f26228`](https://github.com/millionco/react-doctor/commit/2f26228e36cfe64a430a41596d7b1053d6d7d307), [`a48fb06`](https://github.com/millionco/react-doctor/commit/a48fb06ffbe7221655e18529fcc954ecae17a22f)]:
+ - @react-doctor/core@0.5.2
+
## 0.5.1
### Patch Changes
diff --git a/packages/language-server/package.json b/packages/language-server/package.json
index 2269ba9ef..eca35750d 100644
--- a/packages/language-server/package.json
+++ b/packages/language-server/package.json
@@ -1,6 +1,6 @@
{
"name": "@react-doctor/language-server",
- "version": "0.5.1",
+ "version": "0.5.2",
"private": true,
"description": "Internal: editor language server for React Doctor — daemonized diagnostics, hovers, and code actions over LSP. Not published directly; bundled into the react-doctor CLI as `react-doctor experimental-lsp`.",
"license": "MIT",
diff --git a/packages/oxlint-plugin-react-doctor/CHANGELOG.md b/packages/oxlint-plugin-react-doctor/CHANGELOG.md
index 8ac6ea5c2..57ce0cd67 100644
--- a/packages/oxlint-plugin-react-doctor/CHANGELOG.md
+++ b/packages/oxlint-plugin-react-doctor/CHANGELOG.md
@@ -1,5 +1,26 @@
# oxlint-plugin-react-doctor
+## 0.5.2
+
+### Patch Changes
+
+- [#766](https://github.com/millionco/react-doctor/pull/766) [`94f9f4f`](https://github.com/millionco/react-doctor/commit/94f9f4fe98207181958f82275b41d94963bc73a2) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Bump `engines.node` to `^20.19.0 || >=22.13.0` so the declared support range matches transitive dependencies (`eslint-scope@9`, `eslint-visitor-keys@5` require `^22.13.0`), preventing EBADENGINE warnings on npm and hard install failures on Yarn 1 under Node 22.12.x.
+
+- [#784](https://github.com/millionco/react-doctor/pull/784) [`038aaf7`](https://github.com/millionco/react-doctor/commit/038aaf78c12f7f9a2699f46d3a6aa304dc69fc12) Thanks [@rayhanadev](https://github.com/rayhanadev)! - Fix a false positive in `nextjs-missing-metadata` ([#775](https://github.com/millionco/react-doctor/issues/775)): an App Router page is no longer flagged as "missing metadata for search previews" when it inherits `metadata` / `generateMetadata` from a co-located or ancestor `layout.*`. Next.js merges metadata down the segment chain, so a page covered by a parent layout's title/description already has search-preview metadata. The rule now walks up the App Router directory tree (bounded, stopping at `app/`) and stays quiet when an ancestor layout supplies metadata; pages with no metadata anywhere in the chain are still flagged.
+
+- [#796](https://github.com/millionco/react-doctor/pull/796) [`fee3fc4`](https://github.com/millionco/react-doctor/commit/fee3fc436e502ad4a6609ab8bda9c9a782d8ecd7) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - `no-barrel-import` messaging is now framework-aware: files that target React Native / Expo (per the nearest `package.json` platform, native/web file extensions, and the project `framework` setting) say the barrel import "ships extra code in your app bundle & slows startup" instead of the web-only "slows page load" wording. Web projects, web-extension files inside RN monorepos, and projects with an unknown framework keep the existing page-load wording.
+
+- [#782](https://github.com/millionco/react-doctor/pull/782) [`c4f0e60`](https://github.com/millionco/react-doctor/commit/c4f0e607b6092485d226c0d67c783270f4eec8b2) Thanks [@rayhanadev](https://github.com/rayhanadev)! - `only-export-components` now recognizes the route/special files of every file-routing framework react-doctor covers and skips them, so the documented "co-export config/metadata next to the default component" shape stops producing false-positive "non-component export" warnings:
+
+ - **Next.js** — App Router (`page`, `layout`, `loading`, `error`, `not-found`, `template`, `default`, `global-error`, `route`) and Pages Router (`_app`, `_document`, `_error`) special files, plus metadata image routes (`opengraph-image`, `twitter-image`, `icon`, `apple-icon`, incl. numbered variants), which fixes the `alt` / `size` / `contentType` / `revalidate` exports in `opengraph-image.tsx` ([#776](https://github.com/millionco/react-doctor/issues/776)).
+ - **Expo Router** — `_layout` and the `+html` / `+not-found` / `+native-intent` reserved files.
+ - **TanStack Router / Start** — `__root` and `*.lazy` route modules.
+ - **Remix / React Router** — `root`, `entry.client`, and `entry.server` modules.
+
+- [#790](https://github.com/millionco/react-doctor/pull/790) [`f52bd07`](https://github.com/millionco/react-doctor/commit/f52bd0737527df9ab81f3746e64bdb5ac1defbc7) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Fix false positives in `rn-no-raw-text` ([#788](https://github.com/millionco/react-doctor/issues/788)) for custom components that forward their children into a ``: the in-file wrapper detection now recognizes components that render `{children}` (or `{props.children}`) inside a nested `` (the `{children}` shape), not just components whose returned root is a ``. Detection also handles parenthesized `return (...)` bodies, `memo`/`forwardRef`-wrapped components, fragment roots, conditional and logical returns, early returns inside `if` branches, renamed destructured children (`{ children: content }`), the `` prop form, wrappers that forward through another in-file wrapper, children aliased to a variable or destructured from props in the body, props spreads that carry children (``, ``, ``), class components, and `styled(Text)` / `styled.Text` factories. The rule is also tagged `test-noise`, so it no longer fires in test/story files — raw text rendered through React Native Testing Library never ships to users, and cross-file wrappers (an imported `Test Chip` in a `.test.tsx`) were the main source of unfixable noise there.
+
+- [#794](https://github.com/millionco/react-doctor/pull/794) [`7c88165`](https://github.com/millionco/react-doctor/commit/7c8816575aff26f11b5099c7ef009c4793fe260f) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - `rules-of-hooks` and `exhaustive-deps` no longer report false positives for hooks called inside a `forwardRef(...)` / `memo(...)` render callback whose binding name is not PascalCase (e.g. `const _Wrapped = forwardRef((props, ref) => { useHook(); ... })`). The render callback passed as the first argument to React's HoCs is a component by construction, so both rules now treat it as one regardless of the variable name it lands on. Only the first argument is promoted — hooks inside `memo`'s second argument (the props comparator) still report, as do genuinely non-component functions like `const _helper = () => { useState(); }`.
+
## 0.5.1
### Patch Changes
diff --git a/packages/oxlint-plugin-react-doctor/package.json b/packages/oxlint-plugin-react-doctor/package.json
index b379681b3..66368045e 100644
--- a/packages/oxlint-plugin-react-doctor/package.json
+++ b/packages/oxlint-plugin-react-doctor/package.json
@@ -1,6 +1,6 @@
{
"name": "oxlint-plugin-react-doctor",
- "version": "0.5.1",
+ "version": "0.5.2",
"description": "oxlint plugin for React Doctor: diagnose React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
"keywords": [
"accessibility",
diff --git a/packages/react-doctor/CHANGELOG.md b/packages/react-doctor/CHANGELOG.md
index 70436d501..314f0dc67 100644
--- a/packages/react-doctor/CHANGELOG.md
+++ b/packages/react-doctor/CHANGELOG.md
@@ -1,5 +1,53 @@
# react-doctor
+## 0.5.2
+
+### Patch Changes
+
+- [#767](https://github.com/millionco/react-doctor/pull/767) [`486c68f`](https://github.com/millionco/react-doctor/commit/486c68f655117819dc268f2b0715ed5b5bebce84) Thanks [@rayhanadev](https://github.com/rayhanadev)! - The GitHub Action's `blocking` input now defaults to `none` (advisory) instead of `error`. Every PR still gets the full React Doctor report — the sticky summary comment, inline review comments, and a commit status with the health score — but the check no longer fails on findings, so a brand-new install can't red-X a teammate's PR on day one (trust-before-gate). To turn the gate back on, set `blocking: warning` (fail on any finding) or `blocking: error` (fail on error-severity findings) on the action. The generated `react-doctor.yml` documents this inline.
+
+ Note: this changes behavior for existing `millionco/react-doctor@v2` workflows that never set `blocking` — they were gating on error-severity findings and will now run advisory. Add `blocking: error` to the action's `with:` block to keep the previous behavior.
+
+ The CLI / config default is unchanged: `react-doctor` (and `--blocking` / the `blocking` config key) still defaults to `error`, so local runs, pre-commit hooks, and non-action CI keep failing on error-severity findings.
+
+- [#766](https://github.com/millionco/react-doctor/pull/766) [`94f9f4f`](https://github.com/millionco/react-doctor/commit/94f9f4fe98207181958f82275b41d94963bc73a2) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Bump `engines.node` to `^20.19.0 || >=22.13.0` so the declared support range matches transitive dependencies (`eslint-scope@9`, `eslint-visitor-keys@5` require `^22.13.0`), preventing EBADENGINE warnings on npm and hard install failures on Yarn 1 under Node 22.12.x.
+
+- [#731](https://github.com/millionco/react-doctor/pull/731) [`1ca6f0e`](https://github.com/millionco/react-doctor/commit/1ca6f0ead3d69ddf4feababb54ddeea8d8c0d01d) Thanks [@aidenybai](https://github.com/aidenybai)! - Bundle Effect into the published CLI so `npx react-doctor@latest` no longer installs Effect's `ini@7` dependency and avoids the Node 22.19 engine warning.
+
+- [#791](https://github.com/millionco/react-doctor/pull/791) [`22268f7`](https://github.com/millionco/react-doctor/commit/22268f70ac2a557dd6170fb582eb020c4e9d3cf0) Thanks [@rayhanadev](https://github.com/rayhanadev)! - Cap the `oxlint` dependency to `>=1.66.0 <1.67.0`. oxlint 1.67.0 added an optional peer dependency on `vite-plus`, which in pnpm workspaces that install `vite-plus` at the root forces a second peer-resolution context for the Vite+ toolchain. That split installs a duplicate copy of the Vitest fork (`@voidzero-dev/vite-plus-test`), and test runs fail at collection with `Vitest failed to find the current suite` because hooks register in one copy while suites live in the other ([#699](https://github.com/millionco/react-doctor/issues/699)). Pinning below 1.67 keeps react-doctor's oxlint free of the `vite-plus` peer edge, so pnpm dedupes the toolchain back to a single instance.
+
+- [#793](https://github.com/millionco/react-doctor/pull/793) [`9cc6555`](https://github.com/millionco/react-doctor/commit/9cc655591e85b90734f23a19f3181cbe1625fae8) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Carry the React Compiler bail-out reason in the primary diagnostic message. `react-hooks-js/*` diagnostics previously all rendered the same generic "This component misses React Compiler's automatic memoization…" message, with the specific reason relegated to `help`. The message now includes the first line of the compiler's reason (e.g. `useMemo() callbacks may not be async or generator functions`) so contexts that only show the message explain _why_ the compiler bailed; the reason's remaining lines stay in `help`, so the rendered message + suggestion never repeat the same sentence. `todo` diagnostics keep the generic message — their reasons are compiler-internal work notes, not user-facing copy. Because diagnostics dedupe on their full message, two _different_ bail-out reasons anchored at the same source location now survive as two diagnostics instead of collapsing into one, so counts can rise slightly on affected projects.
+
+- [#800](https://github.com/millionco/react-doctor/pull/800) [`3de9106`](https://github.com/millionco/react-doctor/commit/3de910612de481a063ff19c6c7b2c62f0098411a) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Load `doctor.config.ts` files that import `defineConfig` from `react-doctor/api` even when the scanned repo has no installed node_modules (e.g. the GitHub Action runs the CLI via `npm exec` without installing the repo's dependencies). The config loader now retries the load with `react-doctor/api` aliased to the running package's own copy instead of silently falling back to default config.
+
+- [#769](https://github.com/millionco/react-doctor/pull/769) [`2f26228`](https://github.com/millionco/react-doctor/commit/2f26228e36cfe64a430a41596d7b1053d6d7d307) Thanks [@rayhanadev](https://github.com/rayhanadev)! - Consolidate the scan-scope controls into one `--scope` flag (and `scope` config option) with four values, shared verbatim by the CLI and the GitHub Action:
+
+ - `full` (default) — the whole project, every issue. Whole-project checks (dead-code, environment, supply-chain) run only here.
+ - `files` — only the files changed vs the base, with all issues in them (no compare-to-main). What `--staged` and an uncommitted `--diff` did.
+ - `changed` — only issues the change introduced vs the base (the baseline delta). What `--diff ` and the action's `scope: changed` did.
+ - `lines` — only issues on the lines the change actually touched. New: previously this scoping existed only inside the GitHub Action's inline-review-comment step; it now lives in the engine, so the CI gate, score display, summary, and inline comments all honor one scope.
+
+ `--base ][` sets the comparison base for `files` / `changed` / `lines` (auto-detected when omitted). Behavior is unchanged by default: the CLI `--scope` defaults to `full` and the action `scope` input still defaults to `changed`. `--diff` / `config.diff` keep working as a deprecated alias (`--diff ` → `--scope changed --base `, `--diff false` → `--scope full`) and emit a one-time deprecation warning; `--staged` is retained as the source selector and composes with `--scope files` / `--scope lines`.
+
+- [#795](https://github.com/millionco/react-doctor/pull/795) [`04e72a4`](https://github.com/millionco/react-doctor/commit/04e72a4d563b792af09c15f069ce9d523a9c538c) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Diagnostics in test, spec, fixture, and Storybook files are now labeled with their file context. The terminal report and the per-rule text dumps tag those sites as `(test file)` / `(story file)` so a finding in a spec doesn't read as a production problem, and each diagnostic in the JSON report carries an optional `fileContext` field (`"test"` / `"story"`; omitted for production files). The classification reuses the same path heuristics that already drive test-noise auto-suppression, so the label and the suppression can never disagree.
+
+- [#784](https://github.com/millionco/react-doctor/pull/784) [`038aaf7`](https://github.com/millionco/react-doctor/commit/038aaf78c12f7f9a2699f46d3a6aa304dc69fc12) Thanks [@rayhanadev](https://github.com/rayhanadev)! - Fix a false positive in `nextjs-missing-metadata` ([#775](https://github.com/millionco/react-doctor/issues/775)): an App Router page is no longer flagged as "missing metadata for search previews" when it inherits `metadata` / `generateMetadata` from a co-located or ancestor `layout.*`. Next.js merges metadata down the segment chain, so a page covered by a parent layout's title/description already has search-preview metadata. The rule now walks up the App Router directory tree (bounded, stopping at `app/`) and stays quiet when an ancestor layout supplies metadata; pages with no metadata anywhere in the chain are still flagged.
+
+- [#768](https://github.com/millionco/react-doctor/pull/768) [`a64093c`](https://github.com/millionco/react-doctor/commit/a64093c8a14255dc2108d834d56f4d21b9d9ac60) Thanks [@rayhanadev](https://github.com/rayhanadev)! - CI onboarding now resolves the repository's actual default branch instead of assuming `main`. The pull request opened during setup asks GitHub (`gh repo view`) for the default branch — falling back to `origin/HEAD`, then `main`/`master` — and uses it as the PR base, and the installed workflow's push trigger scans that same branch (`master`, `develop`, …) so the health-score trend works on repos whose default branch isn't `main`.
+
+- [#783](https://github.com/millionco/react-doctor/pull/783) [`a48fb06`](https://github.com/millionco/react-doctor/commit/a48fb06ffbe7221655e18529fcc954ecae17a22f) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Add a `--output-dir ` flag that writes the full diagnostics dump (diagnostics.json + one .txt per rule) to a directory of your choice instead of a random temp folder, prints the written path whenever the flag is set (previously `--verbose`-only), and makes the agent handoff reuse that directory instead of writing a second temp copy. Without the flag, behavior is unchanged.
+
+- [#792](https://github.com/millionco/react-doctor/pull/792) [`19d99ee`](https://github.com/millionco/react-doctor/commit/19d99eee1e91d1748fe7e80776fe3d5e6a1c59f2) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Title `react-hooks-js/todo` diagnostics "React Compiler doesn't support this syntax" instead of the generic "React Compiler can't optimize this" headline. The `todo` rule fires when the compiler bails out on syntax it doesn't handle yet, so the headline now says what actually happened.
+
+- [#801](https://github.com/millionco/react-doctor/pull/801) [`0f91fa3`](https://github.com/millionco/react-doctor/commit/0f91fa36b8b26ef78f2fc64b5cba2ff2e3ba4e9b) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Add `rn-no-metro-babel-runtime-version` — warns when a babel config uses `module:@react-native/babel-preset` without an `enableBabelRuntime` version. Without a version the preset can duplicate Babel runtime helpers across files instead of importing them once from `@babel/runtime`, increasing the JS bundle (facebook/react-native#57123). It fires as a `warning` (a bundle-size optimization, not a broken build, so it never blocks CI on the default React Native config), only when the preset is referenced as a real string literal (Expo's `babel-preset-expo` and comment mentions are unaffected), and treats `enableBabelRuntime: true`/`false` as still missing a version.
+
+- [#790](https://github.com/millionco/react-doctor/pull/790) [`f52bd07`](https://github.com/millionco/react-doctor/commit/f52bd0737527df9ab81f3746e64bdb5ac1defbc7) Thanks [@devin-ai-integration](https://github.com/apps/devin-ai-integration)! - Fix false positives in `rn-no-raw-text` ([#788](https://github.com/millionco/react-doctor/issues/788)) for custom components that forward their children into a ``: the in-file wrapper detection now recognizes components that render `{children}` (or `{props.children}`) inside a nested `` (the `{children}` shape), not just components whose returned root is a ``. Detection also handles parenthesized `return (...)` bodies, `memo`/`forwardRef`-wrapped components, fragment roots, conditional and logical returns, early returns inside `if` branches, renamed destructured children (`{ children: content }`), the `` prop form, wrappers that forward through another in-file wrapper, children aliased to a variable or destructured from props in the body, props spreads that carry children (``, ``, ``), class components, and `styled(Text)` / `styled.Text` factories. The rule is also tagged `test-noise`, so it no longer fires in test/story files — raw text rendered through React Native Testing Library never ships to users, and cross-file wrappers (an imported `Test Chip` in a `.test.tsx`) were the main source of unfixable noise there.
+
+- [#780](https://github.com/millionco/react-doctor/pull/780) [`f5f539a`](https://github.com/millionco/react-doctor/commit/f5f539a1a3c6609136808a0d0e091669d8443584) Thanks [@rayhanadev](https://github.com/rayhanadev)! - The Socket supply-chain check now gates on the security axes (supply chain, vulnerability) instead of Socket's `overall` score, and the diagnostic names the exact axis that failed. Socket's `overall` is its lowest axis, so a package with perfect security scores could fail the Security gate purely on quality/maintenance — `@types/bun` was reported as having a "supply-chain score of 48" while socket.dev showed Supply Chain 100 (issue [#770](https://github.com/millionco/react-doctor/issues/770)). Known-bad packages (`event-stream@3.3.6`, vulnerable `minimist`/`lodash` releases) are still flagged via their vulnerability axis, and the reported number now always matches the axis named on the socket.dev package page.
+
+- Updated dependencies [[`94f9f4f`](https://github.com/millionco/react-doctor/commit/94f9f4fe98207181958f82275b41d94963bc73a2), [`038aaf7`](https://github.com/millionco/react-doctor/commit/038aaf78c12f7f9a2699f46d3a6aa304dc69fc12), [`fee3fc4`](https://github.com/millionco/react-doctor/commit/fee3fc436e502ad4a6609ab8bda9c9a782d8ecd7), [`c4f0e60`](https://github.com/millionco/react-doctor/commit/c4f0e607b6092485d226c0d67c783270f4eec8b2), [`f52bd07`](https://github.com/millionco/react-doctor/commit/f52bd0737527df9ab81f3746e64bdb5ac1defbc7), [`7c88165`](https://github.com/millionco/react-doctor/commit/7c8816575aff26f11b5099c7ef009c4793fe260f)]:
+ - oxlint-plugin-react-doctor@0.5.2
+
## 0.5.1
### Patch Changes
diff --git a/packages/react-doctor/package.json b/packages/react-doctor/package.json
index e8d633dcd..e1d21ed44 100644
--- a/packages/react-doctor/package.json
+++ b/packages/react-doctor/package.json
@@ -1,6 +1,6 @@
{
"name": "react-doctor",
- "version": "0.5.1",
+ "version": "0.5.2",
"description": "Your agent writes bad React. This catches it",
"keywords": [
"accessibility",
]