Commit Graph

602 Commits

Author SHA1 Message Date
github-actions[bot] 269ca17f52 chore: version packages (#558) react-doctor@0.2.12 eslint-plugin-react-doctor@0.2.12 oxlint-plugin-react-doctor@0.2.12 2026-05-29 18:01:18 -07:00
Nisarg Patel 2e369e2d3b fix(action): disable setup-node v5 auto package-manager cache
setup-node@v5 defaults `package-manager-cache: true`, which auto-detects
a `packageManager` field (e.g. pnpm) and runs the package manager to
resolve the cache path. Consumer CI that doesn't install pnpm fails with
"Unable to locate executable file: pnpm", which then cascades into the
skipped scan step and a "Missing report path" render crash. The action
runs via `npm exec` and never installs the consumer's deps, so there is
nothing to cache — turn it off.

Co-authored-by: Cursor <cursoragent@cursor.com>
v1.0.1
2026-05-29 17:55:50 -07:00
Aiden Bai 15e5fecf3b temp ci fix 2026-05-29 17:54:43 -07:00
Ray Arayilakath b2934f93e4 fix(oxlint-plugin): treat fbtee translation tags as transparent in rn-no-raw-text (#582)
Co-authored-by: Ray Arayilakath <me@rayhanadev.com>
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-05-29 17:48:20 -07:00
Ray Arayilakath b65b15794f feat(zod): add Zod v4 migration rules (#578) 2026-05-29 17:18:27 -07:00
Nisarg Patel b5cf7670f7 feat(cli): pair verbose diagnostics with per-rule fix-recipe URLs (#574)
* feat(cli): pair verbose diagnostics with per-rule fix-recipe URLs

In --verbose output, every error/warning rule group now prints a
`Fix recipe:` line pointing at the canonical, reviewer-tested prompt
at https://www.react.doctor/prompts/rules/<plugin>/<rule>.md (also
written into the verbose diagnostics dump). This lets the /doctor
playbook fetch the recipe on demand so each fix follows the canonical
recipe instead of being improvised per diagnostic.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: drop changeset for verbose fix-recipe URLs

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(cli): make verbose recipe line a fetch directive for agents

Replace the bare "Fix recipe:" label with an explicit
"Fetch & follow the canonical fix recipe before fixing:" directive so
the consuming agent treats the per-rule prompt URL as a step to perform
rather than optional reference docs. Share the line between the verbose
output and the diagnostics dump to keep them in sync.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(cli): explain per-rule recipe fetching in non-verbose summary

Non-verbose output only lists category counts, so the agent never sees
the per-rule recipe URLs. Add a closing hint that points at the
canonical recipe pattern (https://www.react.doctor/prompts/rules/<plugin>/<rule>.md)
and tells the agent to run --verbose for the exact per-rule URLs, so it
can fetch & follow the recipe before fixing.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): separate recipe hint from per-project summary bars

Add a blank line before the multi-project per-project summary rows so the
recipe-fetch hint isn't visually glued to the project score bars.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(cli): include per-rule fix recipes in clipboard copy

The "Copy issues to clipboard" summary now prints each rule's canonical
fix-recipe URL (reusing the shared fetch directive) and adds a how-to-fix
step telling the agent to fetch & follow it before fixing, matching the
verbose terminal output.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): show a real example recipe URL in non-verbose summary

The <plugin>/<rule>.md placeholder was ambiguous in non-verbose mode,
where the agent never sees rule names. Use a concrete recipe URL built
from an actual finding (an error when present) as the example, and point
to --verbose for the full per-rule list.

Co-authored-by: Cursor <cursoragent@cursor.com>

* style: format recipe-label constant onto a single line

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): group clipboard issues by plugin/rule for correct recipe URLs

Bugbot: the clipboard summary grouped diagnostics by rule name only, so
two plugins sharing a rule name collapsed into one group and emitted the
first plugin's fix-recipe URL for all of them. Key the grouping by
`<plugin>/<rule>` (matching every other grouping in the codebase) so each
group's recipe URL and header are correct.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 15:44:20 -07:00
Ray Arayilakath f4035fce9a refactor(action): rebuild PR reporting flow (#577)
Co-authored-by: Cursor <cursoragent@cursor.com>
v1.0.0
2026-05-29 16:24:17 -04:00
Aiden Bai d0f52062e0 feat(oxlint): add no-self-updating-effect rule (#572) 2026-05-29 01:48:42 -07:00
Aiden Bai e7a998a9fa fix(react-doctor): unref stdin so an inherited pipe/socket can't keep the CLI alive (#576)
* fix(react-doctor): unref stdin so an inherited pipe/socket can't keep the CLI alive

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>

* refactor(react-doctor): drop redundant comment, tighten test helper type

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>

* test(react-doctor): extract shared stubProcessStdinProperty helper

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>

---------

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-28 23:01:20 -07:00
Aiden Bai 402c7ea7a0 feat(oxlint-plugin): add 10 performance rules derived from 3perf, coryhouse, million-lint-benchmark (#523)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-05-28 22:27:31 -07:00
Aiden Bai d917f62ed6 feat(oxlint-plugin): add no-prop-types rule (React 19) (#570) 2026-05-28 22:18:03 -07:00
Aiden Bai f036b0fc52 done 2026-05-28 20:16:27 -07:00
Ray Arayilakath 1c87c65a87 docs: mention changesets in rule validation (#571)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 23:14:22 -04:00
Ray Arayilakath ec90c94381 feat(core): generalize the run gate to a project-analyzability check (enables Preact) (#556)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 23:00:24 -04:00
Aiden Bai 606817c868 fix(website): enforce score request-body cap on the actual read (#561) 2026-05-28 19:54:06 -07:00
Aiden Bai 447674d63f refactor(core): wire ambient-config References; drop dead refs/path brands (#569) 2026-05-28 19:42:42 -07:00
Aiden Bai 309f4c050f fix(oxlint-plugin): record param-default/computed-key references; fix exhaustive-deps FP (#564) 2026-05-28 19:35:35 -07:00
Aiden Bai ab1d19c1a0 fix(cli): default --fail-on to none (advisory) (#560) 2026-05-28 19:34:30 -07:00
Aiden Bai 55b853c206 fix(core): clamp React-major capability loop to prevent hang/OOM (#565) 2026-05-28 19:34:06 -07:00
Aiden Bai deaa194c14 fix(core,cli): plug temp-dir leaks and fix staged path remap (#568) 2026-05-28 19:33:12 -07:00
Aiden Bai da5d00243d fix(cli): dispatch oxlint-failure hint on structured kind, not message text (#567) 2026-05-28 19:32:49 -07:00
Aiden Bai ef9330811a fix(core): enforce git show byte cap via streaming counter (#563) 2026-05-28 19:32:21 -07:00
Ray Arayilakath 7329613f1b fix(action): default PR runs to the target-branch diff (#527) (#551)
Co-authored-by: Cursor <cursoragent@cursor.com>
v0.5.4
2026-05-28 22:24:14 -04:00
Aiden Bai db277ee678 fix(api): surface lint failures via diagnose().skippedChecks (#559) 2026-05-28 19:17:31 -07:00
Nisarg Patel 3a8ef93931 chore: triage-driven rule severity and scope adjustments (#536)
* fix(a11y): skip alt-text on Next.js metadata image route files

Next.js App Router treats `opengraph-image.tsx`, `twitter-image.tsx`,
`icon.tsx`, and `apple-icon.tsx` (with optional numeric suffix) as
metadata image routes. Their default export returns an `ImageResponse`
from `next/og` that rasterizes JSX into a static PNG/JPG — no browser
DOM, no screen reader, so `alt` / `aria-*` are unactionable noise.

Extract `isNextjsMetadataImageRouteFilename` as a shared util (so other
DOM-flavoured a11y rules can opt in later) and early-return from
`alt-text.create()` when the filename matches. Adds a regression suite
covering both extensions, numeric suffixes, and the negative case
(`my-opengraph-image.tsx` still flags).

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(architecture): demote only-export-components to warn

Mixing non-component exports in a component module is a Fast Refresh
hint, not a hard failure — projects routinely co-locate stable
constants alongside components and ship fine. Drop from `error` to
`warn` so triage output reflects the actual severity gradient.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(architecture): unregister react-compiler-destructure-method

The React-Compiler memoization premise didn't hold up for the three
canonical hooks the rule targeted: `useRouter`, `useSearchParams`, and
`useNavigation` all return stable references, so destructuring their
methods produces no measurable compiler win. On Pages Router
(`next/router`) destructuring `push` is actively wrong — it captures
a stale reference.

Introduce a `RULE_IDS_TO_SKIP_REGISTRATION` skiplist in the registry
generator (with a required justification comment per entry) so we can
park a rule without deleting its implementation. Drops the rule from
the registered set (297 → 296), `describe.skip`'s the regression
suite, and prunes the rule from the vercel-skill parity table. The
fixture seed is kept so re-enabling is a one-line skiplist edit.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(state-and-effects): promote no-adjust-state-on-prop-change to error

Adjusting derived state inside a useEffect when a prop changes always
forces an extra render with a stale UI between the two commits —
there is no benign instance of this pattern, so a warning understates
the cost. Promote to `severity: "error"` and rewrite the recommendation
and message in the authoritative "what's wrong → why → fix" shape used
by the rest of the error-level effect rules.

Upstream `eslint-plugin-react-you-might-not-need-an-effect` ships this
as a softened `type: "suggestion"`. Document the intentional divergence
(severity + copy only — detector logic is still a 1:1 port) in
`effect/SOURCE.md`, and update the registered-severity assertion in
`scan-resilience.test.ts` to expect `error` for this id.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: address review nits — drop explanatory comments, inline regex

Per @rayhanadev's review:
- drop the two `transient-and-async-issues.tsx` block comments around
  `useRouter` / `LoginLink` (the test files document the rule's intent
  on their own)
- drop the duplicate early-return rationale in `alt-text.ts` (the
  shared util's header doc already explains the why)
- inline the metadata-image basename regex into the helper to remove
  the named-constant indirection

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(a11y): use context.filename instead of removed getFilename

After merging main, `RuleContext` no longer exposes `getFilename` (PR
\#549 made it `Omit<BaseRuleContext, "getFilename">` and exposed the
absolute path as a property). Switch the alt-text early-return to read
`context.filename` to match the new API.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 17:16:51 -07:00
Ray Arayilakath c387645858 feat: default to the scanning the branch diff vs all files when in pr (#547)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 20:16:26 -04:00
Aiden Bai 67848aec9c fix(core): scope React subproject discovery to skip app-data dirs and bound depth (#545) (#557) 2026-05-28 17:05:32 -07:00
github-actions[bot] 21b42e740a chore: version packages (#554) oxlint-plugin-react-doctor@0.2.11 react-doctor@0.2.11 eslint-plugin-react-doctor@0.2.11 2026-05-28 19:14:32 -04:00
Ray Arayilakath 6f8640f6d9 fix(oxlint-plugin): skip js-tosorted-immutable on React Native/Expo (Hermes) (#546)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 18:38:22 -04:00
Ray Arayilakath 0596d63d1b feat(rn): hint Reanimated .get()/.set() on react-compiler immutability findings (#548)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 18:38:00 -04:00
Ray Arayilakath 646e80c1ed fix(oxlint-plugin): use context.filename instead of deprecated getFilename (#539) (#549)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 18:36:34 -04:00
Ray Arayilakath 19f5f61152 fix(ci): stabilize Windows vitest worker pool (#550)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 18:25:33 -04:00
Aiden Bai 7605c9538d chore: version packages for 0.2.10
Prepare the 0.2.10 patch release with expanded changelog entries.
eslint-plugin-react-doctor@0.2.10 react-doctor@0.2.10 oxlint-plugin-react-doctor@0.2.10
2026-05-28 02:46:55 -07:00
Aiden Bai d29cdad64c fix(cli): avoid dead-code scan freezes (#537) 2026-05-28 02:39:09 -07:00
Aiden Bai 7fe3e41131 feat: add Preact framework support and rules (#519) 2026-05-28 02:39:01 -07:00
Aiden Bai 7ab5dbdc35 feat(cli): combine install setup prompts (#535) 2026-05-27 23:48:18 -07:00
Aiden Bai 1c5647cc9c fix(cli): show setup prompt for monorepo scans (#534) 2026-05-27 22:41:40 -07:00
Ray Arayilakath 928f21cd68 MIL-1559: no-giant-component flags non-React TypeScript modules (#525)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-05-27 17:34:25 -07:00
Aiden Bai 849b25dd91 feat(jotai): add three Jotai rules + register jotai bucket (#531) 2026-05-27 17:33:52 -07:00
Ray Arayilakath 07dcb0882c MIL-1560: Fix false positives in control-has-associated-label (#528)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-05-27 17:13:20 -07:00
Aiden Bai f6938f93b8 feat(react-native): add three Pressable / list / ScrollView perf rules (#529) 2026-05-27 16:55:27 -07:00
Aiden Bai a1be777904 feat(state-and-effects): add activity-wraps-effect-heavy-subtree (#532) 2026-05-27 16:55:14 -07:00
Aiden Bai 0ece9c4e08 feat(js-performance): add js-async-reduce-without-awaited-acc (#530) 2026-05-27 16:04:17 -07:00
Aiden Bai dc5f2f0972 feat(rn): add rn-no-renderitem-key rule (#526) 2026-05-27 14:40:01 -07:00
Ray Arayilakath 8244f1f28f docs: consolidate fragmented rule skills (#522)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 04:46:10 -04:00
Rayhan Noufal Arayilakath 27e684c1dd chore: format the damn code gng 🥀 2026-05-27 01:25:32 -07:00
Aiden Bai ef47202cbd fix: remove registry-url and upgrade npm for OIDC trusted publishing
setup-node's registry-url writes an .npmrc with _authToken placeholder
that short-circuits the OIDC exchange. Also need npm 11.5.1+ for
trusted publishing support.
eslint-plugin-react-doctor@0.2.9 oxlint-plugin-react-doctor@0.2.9 react-doctor@0.2.9
2026-05-27 01:03:10 -07:00
github-actions[bot] 4c02514ab8 chore: version packages (#521)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-27 00:57:15 -07:00
Aiden Bai 6531454b95 fix: use pnpm run version in publish workflow 2026-05-27 00:54:37 -07:00
Aiden Bai 30afe81c4a chore: add changeset to test trusted publishing 2026-05-27 00:53:44 -07:00