Skip to content

chore(deps): update dependency react-doctor to v0.5.6 - #25

Merged
koki-develop merged 1 commit into
mainfrom
renovate/react-doctor-0.x
Jun 26, 2026
Merged

chore(deps): update dependency react-doctor to v0.5.6#25
koki-develop merged 1 commit into
mainfrom
renovate/react-doctor-0.x

Conversation

@renovate

@renovate renovate Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
react-doctor (source) 0.2.80.5.6 age confidence

Release Notes

millionco/react-doctor (react-doctor)

v0.5.6

Compare Source

Patch Changes
  • #​812 ea3b827 Thanks @​aidenybai! - Add five security-scan rules distilled from security-researcher writeups and the deepsec scanner-matcher catalog, closing CWE shapes the bucket didn't cover:

    • unsafe-json-in-htmlJSON.stringify(...) embedded in dangerouslySetInnerHTML or inline <script> markup. JSON.stringify does not HTML-escape, so data containing </script> or < breaks out — the classic SSR data-hydration XSS. Suppressed when an HTML-safe serializer (serialize-javascript, devalue, superjson) or \u003c escaping is used.
    • jwt-insecure-verification — the JWT none algorithm (alg: none / algorithms: ["none"]), which disables signature verification and lets any forged token through. (Detecting an unpinned jwt.verify precisely needs scope-aware analysis, so that is left to a future AST rule.)
    • secret-in-fallback — a secret-shaped env var with a hardcoded string fallback (process.env.STRIPE_SECRET_KEY ?? "<hardcoded>"): a committed secret that also makes the app fail open when the var is unset. Skips public vars (PUBLIC/PUBLISHABLE/ANON) and placeholder defaults.
    • request-body-mass-assignment — spreading or merging request input ({ ...req.body }, Object.assign(target, req.body), lodash merge/defaultsDeep) without a field allowlist: mass assignment (client-set owner/role/price columns) or prototype pollution.
    • insecure-session-cookie — auth/session cookies exposed to JavaScript: httpOnly: false, set via document.cookie, or a bare res.cookie("session", value) / cookies().set(...) with no options.

    All five register through defineRule with a project-level scan, carry the Security category and security-scan tag, and are silenced by react-doctor rules ignore-tag security-scan like the rest of the family.

  • #​824 cf9e05b Thanks @​aidenybai! - Show the full file total when the scan hands off to dead-code analysis, so the live counter no longer looks stuck below N (#​815).

    The linter already emits a final (N, N) progress tick when its last batch finishes, but ora throttles renders to its frame interval — that last frame was overwritten by the "Analyzing dead code…" text before it ever painted, so the spinner appeared to freeze at whatever value the smooth-creep timer last drew (e.g. 80/165). Every file was always scanned; only the counter looked short. The dead-code phase now reads Scanned N files, analyzing dead code…, keeping the complete count visible for the whole (longer) dead-code pass.

  • #​819 5fc0e27 Thanks @​aidenybai! - Fix false positives reported in the security and TanStack rules:

    • query-destructure-result (#​818): only flags useQuery/useSuspenseQuery/… when they actually come from a TanStack Query package (@tanstack/*-query, legacy react-query). A same-named hook imported from elsewhere — notably Convex's useQuery from convex/react, which returns the data directly — is no longer flagged.
    • artifact-env-leak / artifact-secret-leak (#​816, #​817): no longer treat server-side or dev-mode Next.js output as browser artifacts. .next/dev/server/** (dev source maps), any .next/**/server/**, .output/server/**, and the dev server's .next/dev/** output are excluded; production browser bundles (.next/static, dist/assets, public/, …) are still scanned.
    • repository-secret-file / key-lifecycle-risk (#​813): no longer flag a credential/key file that git ignores — a local-only, gitignored .env is not "checked into the repository". Findings are dropped only when git definitively reports the path as ignored (the finding stands when there is no repo or git is unavailable).
    • webhook-signature-risk (#​814): recognizes a delegated verification helper (a call pairing a verify-ish verb with a security noun, e.g. isValidSecret(...), verifySignature(...), checkWebhookHmac(...)) as verification evidence, so an extracted timingSafeEqual comparison in another module no longer trips the rule.
  • #​812 ea3b827 Thanks @​aidenybai! - Add a supabase-table-missing-rls security-scan rule. It flags a Supabase migration (supabase/migrations/**, supabase/schemas/**) that runs create table for a public-schema table but never enables Row Level Security — the highest-impact and most common Supabase misconfiguration, because RLS is OFF by default for SQL-created tables, so every row is readable and writable with the public anon key. It targets the same misconfiguration Supabase's own rls_disabled_in_public database linter flags, and the gap that turns the public anon key into the service key.

    The existing supabase-rls-policy-risk only caught an explicit disable row level security; this complements it by catching the far more common "never enabled it" case. RLS is checked per table — each create table must have an alter table <name> enable row level security for that same table, after the create (a sibling table enabling RLS, or a policy without enabling it, does not vouch). SQL comments and string literals are ignored, non-public/Supabase-managed schemas (auth., storage., a private. schema, …) are skipped, and the rule is scoped to the supabase/ directory so plain Drizzle/Prisma .sql migrations are not flagged. The scan runs per migration file, so enabling RLS in a different migration than the create table is not detected — the same-file pattern (what Supabase tooling emits) is the supported case. Like the rest of the family it carries the security-scan tag and is silenced by react-doctor rules ignore-tag security-scan.

  • #​823 bac7c82 Thanks @​rayhanadev! - Fix a supply-chain scan crash on npm dist-tags and wildcards (#​807).

    resolveConcreteVersion called semver.minVersion(spec) directly, but semver throws (TypeError: Invalid comparator: latest) on a non-range spec instead of returning null. Any full scan — or PR scan touching package.json — containing a dist-tag like "trigger.dev": "latest" (or "next") crashed before the Socket fail-open path could run (regression from #​804, affecting 0.5.3–0.5.5).

    The spec is now validated with semver.validRange before resolving its floor: dist-tags and other non-ranges are skipped (nothing to score), as is a wildcard-only range (*/x/X), which previously resolved to a synthetic 0.0.0 and scored a version nobody pinned. Real ranges (^1.2.3, 1.x, >=2 <3) and protocol/URL specs (workspace:, file:, npm:, git+…) are unchanged.

  • Updated dependencies [ea3b827, 5fc0e27, ea3b827]:

    • oxlint-plugin-react-doctor@​0.5.6

v0.5.5

Compare Source

Patch Changes
  • Updated dependencies [e90eb7a]:
    • oxlint-plugin-react-doctor@​0.5.5

v0.5.4

Compare Source

Patch Changes
  • #​744 eacdcf2 Thanks @​aidenybai! - Add a project-level security file scan: 36 first-class scan rules (leaked artifact secrets and env dumps, permissive Firebase/Supabase rules, raw SQL injection risk, unsafe webhook signature comparisons, committed private key material, public debug artifacts, …) ship in the oxlint plugin as ordinary defineRule modules that declare a project-level scan instead of AST visitors and run in @react-doctor/core's environment-check phase over one bounded whole-tree walk — covering shipped bundles, dotenv/config files, SQL, and Firebase rules files that per-file linting never sees.

    Scan rules register metadata (id, title, severity, recommendation, Security category, security-scan tag) like any other rule but carry a project-level scan instead of AST visitors, so their findings flow through the standard diagnostic pipeline: per-rule and per-category severity overrides, inline disables, and output surfaces now apply to scan-rule diagnostics, and react-doctor rules ignore-tag security-scan (config ignore.tags) silences the whole family. They never appear in generated oxlint configs or the ESLint presets — they only execute through React Doctor's scan. A plain --diff / --staged scan skips them like the other whole-project checks, and the gate is now diff mode itself rather than the presence of include paths, so projects configuring ignore.files get the security scan too.

  • #​744 eacdcf2 Thanks @​aidenybai! - Remove the --sfw demo flag (the standalone Socket.dev supply-chain score listing that printed every direct dependency's score and exited).

    The Socket.dev supply-chain check is unaffected — it still runs during normal full scans (and on diff scans whose package.json changed) and its scores still appear in the JSON report. Only the standalone listing is gone, along with its demo-only internals (collectSupplyChainScores, the DependencyScore type, the monorepo-wide dependency collector, and the score-table renderer).

  • Updated dependencies [eacdcf2, eacdcf2]:

    • oxlint-plugin-react-doctor@​0.5.4

v0.5.3

Compare Source

Patch Changes
  • #​804 022790b Thanks @​NisargIO! - Clearer Socket supply-chain diagnostics (socket/low-supply-chain-score). When Socket returns a concrete alert, the message now names it — e.g. a critical "known malware" alert, the offending file, and a one-line description — instead of only a bare score; when it doesn't (metric-driven dips like CVE-only scores), the message explains what the failing axis means. The help is now axis-aware: remove a package flagged as compromised, upgrade past known vulnerabilities (npm audit), or vet-and-raise the threshold — rather than a generic "update or replace". The headline leads with the exact failing axis and collapses the redundant "declared as X, scored at X" phrasing (a range now reads pkg@floor (lowest version "^x.y.z" allows)). JSON report shape is unchanged (schemaVersion: 1).

  • Updated dependencies []:

    • oxlint-plugin-react-doctor@​0.5.3

v0.5.2

Compare Source

Patch Changes
  • #​767 486c68f Thanks @​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 94f9f4f Thanks @​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 1ca6f0e Thanks @​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 22268f7 Thanks @​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). 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 9cc6555 Thanks @​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 3de9106 Thanks @​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 2f26228 Thanks @​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 <base> 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 <ref> 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 <base>--scope changed --base <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 04e72a4 Thanks @​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 038aaf7 Thanks @​rayhanadev! - 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.

  • #​768 a64093c Thanks @​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 a48fb06 Thanks @​devin-ai-integration! - Add a --output-dir <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 19d99ee Thanks @​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 0f91fa3 Thanks @​devin-ai-integration! - Add rn-no-metro-babel-runtime-version — warns when a babel config uses module:@&#8203;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 f52bd07 Thanks @​devin-ai-integration! - Fix false positives in rn-no-raw-text (#​788) for custom components that forward their children into a <Text>: the in-file wrapper detection now recognizes components that render {children} (or {props.children}) inside a nested <Text> (the <View><Text>{children}</Text></View> shape), not just components whose returned root is a <Text>. 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 <Text children={children} /> 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 (<Text {...props} />, <Text {...rest} />, <Text {...this.props} />), 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 <Chip>Test Chip</Chip> in a .test.tsx) were the main source of unfixable noise there.

  • #​780 f5f539a Thanks @​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). 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, 038aaf7, fee3fc4, c4f0e60, f52bd07, 7c88165]:

    • oxlint-plugin-react-doctor@​0.5.2

v0.5.1

Compare Source

Patch Changes
  • Updated dependencies [77a70ab]:
    • oxlint-plugin-react-doctor@​0.5.1

v0.5.0

Compare Source

Minor Changes
  • #​756 93d4eec Thanks @​NisargIO! - React Doctor now runs on repositories that don't depend on React. Previously a scan hard-failed with No React project found / No React dependency, even though many checks (security, bundle size, JS performance, architecture, and the Zod rules) are framework-agnostic and apply to any TypeScript / JavaScript codebase.

    A project is now analyzable when it has source files, with or without React. A bare directory of TypeScript files — including a monorepo's packages/ subfolder that has no package.json of its own — is scanned by inheriting dependency/framework detection from the enclosing workspace root.

    React-flavoured rules stay off without React. A new react capability (set only when React or Preact is present) gates every React-runtime rule family (hooks, JSX, accessibility, render performance, React state) plus any rule tagged react-jsx-only, so hook/component-name heuristics like rules-of-hooks, no-legacy-class-lifecycles, and no-nested-component-definition can't false-fire on ordinary TypeScript. Once React (or Preact) is detected, every rule behaves exactly as before.

  • #​747 a254414 Thanks @​NisargIO! - Add a --sfw demo flag that prints the Socket.dev supply-chain score (0–100) of every direct dependency — across every workspace package.json in a monorepo, de-duplicated by name@version — color-coded and sorted worst-first, then exits without running a scan. Scores come from Socket's free, keyless PURL endpoint (the same one the supply-chain check uses).

  • #​747 a254414 Thanks @​NisargIO! - Add a Socket.dev supply-chain score check. Every direct dependency in package.json is scored against Socket's free, keyless PURL endpoint (the same lookup Socket Firewall's free tier uses) and any dependency whose Socket score falls below supplyChain.minScore (default 50, 0–100 scale) produces a Security diagnostic anchored at the offending package.json entry. At the default severity: "error" a low score fails the scan at the standard blocking gate.

    The check runs by default; opt out with supplyChain: { enabled: false }. It is fail-open (per-package timeouts / network failures are skipped, never sinking the scan). A plain --diff / --staged scan skips it like the other whole-project checks, but a diff that edits a package.json (including any workspace's in a monorepo) still scores that project's dependencies — so a PR that adds or bumps a dependency is covered. next is excluded (its framework-specific risks are already covered by the Next.js / server-components rules).

Patch Changes
  • #​739 829655c Thanks @​NisargIO! - CI setup: collapsed the multi-line inline comments in the generated .github/workflows/react-doctor.yml to a single explanatory sentence per trigger and one line for the concurrency block, and dropped the permissions comment (the four well-named keys are self-explanatory). The resulting workflow still configures the same triggers, permissions, and action ref — just with less scrolling for new users.

  • #​729 25cc69b Thanks @​aidenybai! - Fold the standalone doctor-explain skill into the react-doctor skill as references/explain.md.

    Rule-explanation and config-tuning guidance now ships as an on-demand reference inside the primary skill (per the agentskills.io references/ convention) instead of a separate sibling skill. react-doctor install installs a single skill, and the dead bundled-sibling-skill install machinery is removed.

  • #​752 5b06a86 Thanks @​rayhanadev! - Name every unused dependency in the verbose warning tail.

    Unused-dependency warnings all report at the same line-less location (package.json:0), so the dim location header collapsed every finding into one line and dropped the package names — leaving only a generic deslop/unused-dependency ×N line (#​690). react-doctor --verbose now lists each deslop/unused-dependency and deslop/unused-dev-dependency by name, with the shared "why" explanation shown once instead of repeated per package. Errors and code-frame rendering are unchanged.

  • Updated dependencies [b4b79ad, af98f83, 93d4eec]:

    • oxlint-plugin-react-doctor@​0.5.0

v0.4.2

Compare Source

Patch Changes
  • #​721 d17dc87 Thanks @​aidenybai! - Add a defineConfig helper for authoring a typed doctor.config.{ts,js,mjs,cjs} and read react-doctor.config.json as a deprecated fallback.

    defineConfig is exported from react-doctor/api (and @react-doctor/api / @react-doctor/core) as an identity helper that gives editor autocomplete and type-checking without an explicit satisfies ReactDoctorConfig annotation:

    // doctor.config.ts
    import { defineConfig } from "react-doctor/api";
    
    export default defineConfig({
      lint: true,
      rules: { "react-doctor/no-array-index-as-key": "off" },
    });

    The pre-migration react-doctor.config.json filename is now read as the lowest-priority fallback (after doctor.config.* and package.json#reactDoctor) instead of being ignored, so an un-migrated config keeps applying. It still emits a deprecation warning nudging a rename, and interactive runs continue to auto-migrate it to doctor.config.ts. A present-but-broken legacy file stops config resolution (it won't silently inherit an ancestor repo's config), and react-doctor rules <...> migrates a legacy file to doctor.config.json on write rather than editing it in place.

    Note: a react-doctor.config.json that was previously ignored in non-interactive runs (CI, coding agents, --json/--score/--staged) is now honored again, which can change which rules fire, the score, and PR gating for projects that still have one. Rename it to doctor.config.json (or delete it) to avoid surprises.

  • Updated dependencies []:

    • oxlint-plugin-react-doctor@​0.4.2

v0.4.1

Compare Source

Patch Changes
  • #​711 36ecd05 Thanks @​devin-ai-integration! - Fix false positive in require-reduced-motion: the check now searches untracked files so newly created source (e.g. a providers.tsx with <MotionConfig reducedMotion="user"> not yet committed) is detected.

  • #​706 15bd9d8 Thanks @​rayhanadev! - CI setup now offers a one-time, per-repo prompt to upgrade an existing React Doctor GitHub Actions workflow from @v1 to @v2 — accepting opens a PR with the bump, declining is remembered so it never asks again. The generated / "Add to CI" workflow now pins millionco/react-doctor@v2 and grants statuses: write, so the action can publish the score as a commit status (and surface results on pushes to the default branch).

  • Updated dependencies [dc35070, b1a22ef, 73dcb20, 64667da, ee9ab33, fe5f3de, 831cf3f]:

    • oxlint-plugin-react-doctor@​0.4.1

v0.4.0

Compare Source

Minor Changes
  • #​663 9a8ad6e Thanks @​rayhanadev! - Rework CI reporting: a renamed blocking gate, PR-introduced-issues-only baselines, inline PR review comments, and a simpler CLI flag surface.

    CI gate

    • fail-on is renamed to blocking (CLI --blocking <level>, config blocking, GitHub Action blocking input). Same error | warning | none values, default error: a scan fails CI when an error-severity diagnostic reaches the ciFailure surface; warning blocks on any diagnostic; none stays advisory (always exits 0). --fail-on / failOn still work as a deprecated, warned alias hidden from --help.
    • --blocking warning now wins over --no-warnings (it previously silently no-op'd the gate — you can't block on warnings you've hidden).

    Baseline — report only the issues a PR introduces (Codecov-style)

    • In --diff <base> mode, react-doctor runs a second lint pass over the changed files as they existed at the base merge-base and reports only the diagnostics the change introduced; pre-existing findings that merely shifted lines are matched out by a content fingerprint (file + rule + flagged-line hash). The head project-health score is unchanged; the gate fails on newly-introduced errors only. If the baseline can't be computed (base unreachable, or a lint pass failed), the run degrades to a plain diff — all findings stay visible and CI isn't gated on findings whose new-vs-pre-existing attribution is unknown.
    • New core API: computeDiagnosticDelta, Git.showRefContent / Git.mergeBase, materializeSourceTree, and InspectOptions.baseline / InspectResult.baselineDelta.
    • JSON report v2: baseline runs emit schemaVersion: 2 with a baseline block (newCount, fixedCount, baseTotalCount) and mode: "baseline"; summary.score stays the head score. v1 reports are unchanged.

    GitHub Action

    • Posts inline PR review comments on the changed lines that triggered each diagnostic (with fix guidance + a docs link), plus a restyled CLI-style sticky summary with linkable findings and the new / fixed delta. The annotations input was removed.
    • On pull requests it fetches the base commit for baselining — use fetch-depth: 0 on actions/checkout. New fixed-issues output. Defaults: project: "*", node-version: 24.

    CLI flags (fewer flags, fewer footguns)

    • --explain / --why → the react-doctor why <file>:<line> subcommand (rules explain <rule> still explains what a rule means).
    • Removed --full (use --diff false to force a full scan), --pr-comment (the Action renders its comment from --json), and the positive --respect-inline-disables (already the default; use --no-respect-inline-disables for audit mode). The internal --changed-files-from is hidden from --help.
    • Removed flags now fail with a migration error instead of being silently dropped, and an empty --project filter (e.g. --project ",") is rejected.
Patch Changes
  • #​681 915745e Thanks @​rayhanadev! - Add react-doctor experimental-lsp, an experimental language server that surfaces React Doctor diagnostics directly in your editor — VS Code, Cursor, Zed, Neovim, Sublime Text, Emacs, Helix, or any LSP client. It is gated behind the experimental- prefix while its protocol, caching, and diagnostics stabilize. It scans the file you are editing live from the unsaved buffer, underlines the exact offending token via precise ranges, shows rich hovers (rule, category, recommendation, docs link), and offers quick fixes (disable-for-this-line with the correct comment style, suppress-all-in-file, explain, open docs, report false positive). It discovers every React project across workspace folders and monorepo packages, runs offline (no score lookup, no git), prioritizes open-buffer scans, supports push and pull diagnostics, and invalidates caches when config / package.json / lockfiles change. The background workspace scan is chunked so diagnostics stream in progressively (seconds to first results on large repos), parallelizes across all CPU cores, reserves a slot so edits stay responsive while it runs, and cancels in-flight work when config changes. Results are cached per file (by content metadata, invalidated on config change) and persisted to disk, so re-opening the editor or re-scanning surfaces diagnostics almost instantly — on an ~8,800-file repo a cold scan is ~27s and a warm scan ~2s.

    Start it with react-doctor experimental-lsp --stdio (or npx react-doctor@latest experimental-lsp --stdio). A scanOnType initialization option toggles live-as-you-type scanning, with first-class companion extensions for VS Code/Cursor and Zed.

    Like the CLI, the language server reports anonymized usage analytics to Sentry — a per-workspace-scan wide event plus session/scan counters — sharing the CLI's IP-stripping and path/secret scrubbing. Opt out with REACT_DOCTOR_NO_TELEMETRY=1 (or by launching it with --no-telemetry).

  • Updated dependencies []:

    • oxlint-plugin-react-doctor@​0.4.0

v0.3.0

Compare Source

Minor Changes
  • #​658 cbdff62 Thanks @​aidenybai! - Add an "Add to CI" path to the post-scan handoff and make install set up CI by default.

    The post-scan prompt now leads with an "Add to CI" choice (the default) that installs the react-doctor dev dependency + doctor script and writes a .github/workflows/react-doctor.yml GitHub Actions workflow so every pull request is scanned. When you instead hand off to an agent, the generated prompt now asks the agent to offer CI setup first. The install subcommand pre-selects the workflow and install --yes now writes it by default. The workflow's action is pinned to the @v1 floating major (never @main, per the supply-chain guidance in issue #​299).

Patch Changes
  • #​676 08e1d55 Thanks @​devin-ai-integration! - react-doctor --full --yes no longer errors with "Cannot combine --yes and --full; pick one."

    --yes (skip prompts, scan all workspace projects) and --full (force a full scan, overriding any diff value) control orthogonal concerns, so combining them is a valid request — "scan every workspace project fully, without prompting." The mutual-exclusion check that rejected the pair has been removed.

  • #​674 6851a78 Thanks @​aidenybai! - Bump bundled deslop-js to ^0.0.17, which stops deslop/unused-dev-dependency from false-positiving on dependencies referenced in a package.json script as a flag argument rather than the leading command — e.g. jest --testResultsProcessor jest-sonar-reporter or --reporters=jest-junit (#​653).

  • #​668 3c05fc4 Thanks @​aidenybai! - Update the dead-code analysis engine (deslop-js) to 0.0.16.

  • #​655 d594f69 Thanks @​rayhanadev! - react-doctor no longer crashes when the --changed-files-from file can't be read.

    --changed-files-from <file> is user input, so an unreadable file — missing, a directory, permission-denied, or a stale pipe/process-substitution descriptor (EBADF, REACT-DOCTOR-V) — is an invocation mistake, not a bug. It now exits non-zero with a clean, single-line message telling you to pass a readable text file, instead of printing the generic "Something went wrong" block and reporting the read failure to Sentry.

  • #​660 e3b106e Thanks @​rayhanadev! - react-doctor now records a single anonymized per-scan "wide event" on its Sentry run span — the full run/CI/project/outcome context (scan mode, score, diagnostics by severity and category, top rule, lint/dead-code state, and, in CI, the GitHub event, an official-action marker, the forwarded action inputs, and the pull-request gate) — so usage and CI behavior can be analyzed by querying spans instead of pre-aggregated counters.

    It also mints a random per-run runId attached to the Sentry run context (never as a tag or metric dimension) to correlate the spans of a single run. Telemetry stays anonymized — no repo, owner, username, branch, or path is sent to Sentry — and --no-score / --no-telemetry still opts out entirely. The official GitHub Action forwards its inputs (fail-on, non-blocking, comment, annotations, version) so action configuration is visible in telemetry.

  • #​658 cbdff62 Thanks @​aidenybai! - Polished the first-run onboarding experience — the animated welcome scene now plays on every interactive regular-mode run (not just the first) but at half the cadence for returning users (hasCompletedOnboarding()), --verbose skips the intro entirely and goes straight to the static branded header, and the closing "Let's scan your codebase..." typewriter beat was cut so the intro ends on the tagline.

    Restructured the scan-report layout so the top-errors detail (code frames + fixes) leads the report and the per-category breakdown moves down as a wrap-up overview directly above the score. The breakdown now has its own bold All N issues header (mirroring Top N errors you should fix) with the total folded into the header text, categories sort in a fixed Security → Bugs → Performance → Accessibility → Maintainability order, and warnings no longer get boxed code frames in --verbose (errors still do) so a long warning tail stops drowning the report. The trailing --verbose CTA drops the redundant +N more rules and +N optional warnings stats (the breakdown above already carries those) and reads as a clean Run npx react-doctor@latest --verbose to list every error and warning.

    Quieted the "Add to CI" handoff: it no longer runs the local dev-dep install (the doctor package script and the GitHub workflow both invoke npx react-doctor@latest, so a local copy adds nothing and on pnpm with a beta channel it noisily trips the supply-chain trust guard for zero user benefit). The trust-policy skip on the react-doctor install path now renders as a yellow warning with a tightened one-liner and a dim follow-up showing the manual install command, instead of a red that read like a crash next to its own "React Doctor still works" reassurance.

    Made the case for GitHub Actions before the handoff prompt instead of after it. The scan-report footer now closes with a GitHub Actions: https://react.doctor/ci entry (matching the Share / Docs / GitHub bold label + dim description shape) carrying the strongest reasons in two short lines: Scan every pull request: new PRs stay clean while you fix the backlog + Used by teams at PayPal, Rippling, and Alibaba. Sitting last in the footer makes it the final thing read before the handoff prompt that recommends the same action. The prompt's choice reads as Add to GitHub Actions (recommended) (or (already configured)) with a description of what gets set up; the state tag lives in the title so the description always describes what the option does, not the project's current state. The post-pick message drops the social-proof + backlog framing (now redundant — the footer already showed it) and just confirms what changed plus the docs link.

  • #​667 4dc48d7 Thanks @​aidenybai! - React Compiler projects no longer report jsx-no-constructed-context-values for fresh context provider values that the compiler memoizes automatically.

  • #​654 eab6dc2 Thanks @​rayhanadev! - react-doctor no longer crashes when a directory can't be enumerated during project discovery.

    The recursive subproject crawl reads directories best-effort and already skipped ones it couldn't open for permission or missing-path reasons (EACCES/EPERM/ENOENT/ENOTDIR). It now also skips directories the underlying filesystem rejects outright — EINVAL on scandir (REACT-DOCTOR-N, seen on special/virtual mounts), plus symlink loops (ELOOP) and over-long paths (ENAMETOOLONG) — instead of throwing and reporting the environment issue to Sentry. The crawl continues past the unreadable directory.

  • #​666 5d7b36b Thanks @​aidenybai! - Retires rn-animate-layout-property. Reanimated useAnimatedStyle runs entirely on the UI thread, so layout-affecting style animations driven by helpers like withTiming or withSpring are valid and should not be flagged.

  • #​645 4aadaab Thanks @​aidenybai! - Two React Native rules no longer false-positive on Expo Universal UI (@expo/ui).

    @expo/ui is a native UI layer (it delegates to SwiftUI / Jetpack Compose), not React Native's core primitives, so several RN-core assumptions don't hold for its components:

    • rn-no-raw-text: Universal UI's <ListItem> renders its raw string children inside the native headline text area, and its compound slot markers (<ListItem.Leading>, <ListItem.Supporting>, <ListItem.Trailing>) forward strings into native text too — so raw text inside them is safe, unlike React Native's core <View>. The rule now recognizes them as text-handling.
    • rn-no-scrollview-mapped-list: Universal UI's <ScrollView> is a native scroll container; React Native's virtualized lists (FlashList/FlatList) can't compose inside its <Host> tree, and @expo/ui ships

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At 12:00 AM through 04:59 AM and 10:00 PM through 11:59 PM, Monday through Friday (* 0-4,22-23 * * 1-5)
    • Only on Sunday and Saturday (* * * * 0,6)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/react-doctor-0.x branch 2 times, most recently from 1fcd80d to f2909ea Compare June 16, 2026 17:54
@renovate renovate Bot changed the title chore(deps): update dependency react-doctor to v0.4.2 chore(deps): update dependency react-doctor to v0.5.0 Jun 16, 2026
@renovate
renovate Bot force-pushed the renovate/react-doctor-0.x branch from f2909ea to 8e0f6e9 Compare June 17, 2026 03:46
@renovate renovate Bot changed the title chore(deps): update dependency react-doctor to v0.5.0 chore(deps): update dependency react-doctor to v0.5.1 Jun 17, 2026
@renovate
renovate Bot force-pushed the renovate/react-doctor-0.x branch from 8e0f6e9 to 93dcb76 Compare June 20, 2026 04:47
@renovate renovate Bot changed the title chore(deps): update dependency react-doctor to v0.5.1 chore(deps): update dependency react-doctor to v0.5.2 Jun 20, 2026
@renovate
renovate Bot force-pushed the renovate/react-doctor-0.x branch from 93dcb76 to 94db681 Compare June 20, 2026 11:23
@renovate renovate Bot changed the title chore(deps): update dependency react-doctor to v0.5.2 chore(deps): update dependency react-doctor to v0.5.4 Jun 20, 2026
@renovate
renovate Bot force-pushed the renovate/react-doctor-0.x branch from 94db681 to 5ad8ab6 Compare June 21, 2026 04:55
@renovate renovate Bot changed the title chore(deps): update dependency react-doctor to v0.5.4 chore(deps): update dependency react-doctor to v0.5.5 Jun 21, 2026
@renovate
renovate Bot force-pushed the renovate/react-doctor-0.x branch from 5ad8ab6 to 578f540 Compare June 22, 2026 14:01
@renovate renovate Bot changed the title chore(deps): update dependency react-doctor to v0.5.5 chore(deps): update dependency react-doctor to v0.5.6 Jun 22, 2026
@koki-develop
koki-develop merged commit 3d26478 into main Jun 26, 2026
3 checks passed
@koki-develop
koki-develop deleted the renovate/react-doctor-0.x branch June 26, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant