Commit Graph

556 Commits

Author SHA1 Message Date
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
Aiden Bai d9a6d68509 chore: add trusted publishing workflow via OIDC 2026-05-27 00:53:19 -07:00
Aiden Bai 1b325b8678 fix(test): bump surface-filter test timeout to 60s for Windows CI
The test calls inspect() twice, which exceeds the 30s default on
Windows runners.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 00:29:18 -07:00
Aiden Bai 94af28784f feat(oxlint-plugin): harden React Native list performance rules (#514) 2026-05-27 00:16:42 -07:00
Aiden Bai 71242ad73c feat(oxlint-plugin): add rn-no-falsy-and-render rule (#518) 2026-05-26 23:47:13 -07:00
Aiden Bai 7fa53326e2 feat(oxlint-plugin): improve animation and gesture detection rules (#516) 2026-05-26 23:43:48 -07:00
Aiden Bai 14bad8fad5 feat(oxlint-plugin): expand deprecated package and import detection (#515) 2026-05-26 23:43:22 -07:00
Aiden Bai fc32204674 feat(oxlint-plugin): expand shadow, style, and scroll rules (#517) 2026-05-26 23:41:33 -07:00
Ray Arayilakath 444fbeb760 feat: add skills and docs for writing new rules (#495)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 02:41:23 -04:00
Ray Arayilakath 4e3fa6e10c fix: caution agents on hook dependency fixes (#511)
* fix: caution agents on hook dependency fixes

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

* fix: keep hook dependency guidance scoped

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

* fix: simplify exhaustive deps guidance

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

* fix: add exhaustive deps guidance example

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

* fix: expand exhaustive deps example guidance

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 01:58:02 -04:00
Ray Arayilakath 68e7b80053 feat: animate perfect score terminal header (#506)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:55:09 -04:00
Aiden Bai e3fd765051 feat(oxlint-plugin): error on manual memoization when React Compiler is enabled (#504) 2026-05-26 20:01:04 -07:00
Ray Arayilakath bfe1b8ed13 [MIL-1555] False positive for tanstack-start-missing-head-content (#487)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 22:09:37 -04:00
Aiden Bai 1fc25d1afe fix 2026-05-26 18:31:56 -07:00
Aiden Bai 07b8a6c3e0 fix: cross-platform spawn errors (#498, #501) and add Windows/macOS CI (#502) 2026-05-26 18:19:41 -07:00
Ray Arayilakath 910645f4c2 [MIL-1547] Recognize subscription.remove() as effect cleanup (#471)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Ray Arayilakath <me@rayhanadev.com>
2026-05-26 21:12:58 -04:00
Ray Arayilakath 86928b4cdd feat: run formatter pre-commit (#503)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 20:57:17 -04:00
Ray Arayilakath 27ed9a72ef [MIL-1550] fix navigation and Expo image false positives (#481) 2026-05-26 17:47:29 -07:00
Ray Arayilakath b4d7928200 [MIL-1549] Gate expo-image recommendation for bare React Native (#482) 2026-05-26 17:47:03 -07:00
Ray Arayilakath 397b1d7828 [MIL-1548] Fix bottom sheet React Native false positive (#480) 2026-05-26 17:45:31 -07:00
Rayhan Noufal Arayilakath 9e0f96944e chore: run the formatter lol 2026-05-26 17:17:50 -07:00
Aiden Bai e332310146 refactor(api): rename diagnoseModules → diagnoseProjects, clean up API shape
- Single object arg (`DiagnoseProjectsInput`) instead of two positional args
- "Projects" vocabulary matching the rest of the codebase
- Per-project scan options (`deadCode`, `lint`, etc.) flat on the entry
  instead of nested in `config.deadCode`
- `config` on a project entry means `ReactDoctorConfig` directly
- Discriminated union `ProjectResult` (`ok: true | false`) instead of
  separate `modules` + `errors` arrays
2026-05-26 16:23:04 -07:00
Nisarg Patel 87eb13a4ac fix: harden 2026-05-26 16:15:27 -07:00
Aiden Bai a7b72e19a1 feat(api): add diagnoseModules() for native per-module scoring (#499) 2026-05-26 16:13:03 -07:00
Aiden Bai 5690704080 schema 2026-05-26 05:13:34 -07:00
Aiden Bai 28da2ae32a 0.2.7 2026-05-26 05:08:47 -07:00
Aiden Bai eb5157e806 fix: bundle eslint-plugin-react-hooks as a direct dependency
The React Compiler rules (`react-hooks-js/*`) were silently missing in
published builds because `resolveReactHooksJsPlugin` resolved
`eslint-plugin-react-hooks` via `createRequire(import.meta.url)` — which
found the package in the monorepo's devDependencies but not in the
npm-installed package where it was only an optional peer dep.

Move `eslint-plugin-react-hooks` from optional peerDependencies +
devDependencies to a real dependency in both `@react-doctor/core` and
`react-doctor` so the compiler rules fire automatically for any project
with `babel-plugin-react-compiler` detected.
2026-05-26 04:52:11 -07:00
Aiden Bai 81fce1e205 fix 2026-05-26 03:52:45 -07:00
Aiden Bai 3cd81605a6 feat: agent install hint, concurrent lint+dead-code, remove setup delay (#493) 2026-05-26 03:50:15 -07:00
Nisarg Patel e5139e4c5a fix: downgrade react-doctor skill version 2026-05-25 22:54:15 -07:00
Nisarg Patel 8b994b9ac0 chore(skill): bump version to 1.1.1 and refine playbook description
Updated the version of the react-doctor skill from 1.1.0 to 1.1.1. The playbook description has been refined for clarity, emphasizing its role as the single source of truth in the triage process. No functional changes were made to the skill's operation.
2026-05-25 22:54:14 -07:00
Nisarg Patel 61ea050907 feat(skill): add /doctor full-triage workflow that fetches the canonical playbook
The skill body now points the agent at https://www.react.doctor/prompts/react-doctor-agent.md
when the user types `/doctor` or asks for a full triage. The remote playbook is the
single source of truth (same scan -> filter -> triage -> fix -> validate loop as the
daily GitHub Actions bot, adapted for local use), so prompt edits propagate to every
installed agent on the next invocation without re-publishing the skill.

Bumps SKILL.md version 1.0.0 -> 1.1.0.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 22:38:06 -07:00
Ray Arayilakath 098a966098 fix(cli): suppress CI and agent interactivity (#492)
* fix(cli): suppress CI and agent interactivity

Use a shared CI-or-agent environment check to skip core progress spinners and optional setup prompts in automated React Doctor runs.

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

* fix(tests): isolate setup prompt CI env

Clear the same CI and coding-agent environment signals used by the prompt guard so setup prompt tests remain deterministic in CI.

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 01:36:55 -04:00
Ray Arayilakath 4b5d40e831 feat: implement no-mutating-reducer-state rule (#491)
* implement no-mutating-reducer-state rule

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

* fix reducer mutation switch fallthrough

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

* fix reducer mutation review findings

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

* format reducer mutation rule

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

* cleaning up comments

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

* fix: remove unnecessary run wrapper

* clean up Object.assign return check

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

* fix static member method detection

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 01:17:34 -04:00
Ray Arayilakath 5da342b1bf [MIL-1552] Animate the React Doctor score progress bar (#485)
* Animate score bar in CLI results

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

* Format score header helper

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

* Respect silent mode for score animation

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 00:17:01 -04:00
Ray Arayilakath e93e9afcd6 feat: create a utility to detect CI or coding agent and skip animations (#483)
* detect coding agent environments

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

* consolidate environment detection helpers

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

* fix prompt env test cleanup

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

* centralize environment test signals

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

* fix environment helper formatting

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

* Fix case-sensitive AGENT matching, swap eval order, add missing test coverage

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-05-25 23:35:25 -04:00
Ray Arayilakath d87318df46 feat: skip prefilled project question outside monorepos (#484)
* fix(cli): skip project selection outside monorepos

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

* Mock cliLogger directly, move cleanup into describe, add monorepo discovery test

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

* Fix formatting in select-projects test

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-05-25 23:35:13 -04:00
Ray Arayilakath 4e23e5dd34 fix(ci): point smoke test at core fixture (#486)
* fix(ci): point smoke test at core fixture

Co-authored-by: Ray Arayilakath <me@rayhanadev.com>

* style: format JSON smoke fixture path

Co-authored-by: Ray Arayilakath <me@rayhanadev.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-05-25 16:37:29 -04:00
Cursor Agent d6e6377be7 refactor(tests): collapse collectRuleHits ProjectInfo construction into buildTestProject
Both helpers built identical ProjectInfo shapes inline. Moved the
omitted-vs-explicit-null reactMajorVersion distinction into
buildTestProject so collectRuleHits can just delegate.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 17:04:56 +00:00
Cursor Agent af34ef6666 style: drop unused EsTreeNode type import from forbid-elements
Lint flagged it as no-unused-vars — left over from when the local
flattenMemberName helper used the type directly. After aliasing to
the canonical flattenCalleeName, the type-only import is dead.

Behaviour-neutral.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:49:02 +00:00
Cursor Agent 76a971c931 refactor(oxlint-plugin): drop transitional re-export of isInlineFunctionExpression
After the canonical helper landed in `utils/is-inline-function-expression.ts`,
`event-handler-reference.ts` kept a re-export so collect-function-like-
local-names could keep its existing import path. Migrate that single
remaining consumer to import the canonical location directly, then
drop the transitional re-export.

`event-handler-reference.ts` still imports the helper internally
(used by isEventHandlerValue) so the import line stays — just no
longer fronted as a public surface of this module.

Behaviour-neutral.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:45:18 +00:00
Cursor Agent 809d02b7cf style: pnpm format after the latest consolidation sweep
Format drift in 6 files touched by d09a994c (isInlineFunctionExpression
promotion + 7 rule-file applications). Reformat is behaviour-neutral.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:40:24 +00:00
Cursor Agent d09a994c22 refactor(oxlint-plugin): promote isInlineFunctionExpression + apply across 7 rule files
`isInlineFunctionExpression` (the 2-type `ArrowFunctionExpression`
or `FunctionExpression` predicate, used for expression-position
checks where a FunctionDeclaration can't appear) was tucked inside
`rules/state-and-effects/utils/event-handler-reference.ts`. Promote
to `utils/is-inline-function-expression.ts` so all rule files can
use one canonical type guard.

Apply to seven new sites that previously inlined the 2-type triplet:

- architecture/no-many-boolean-props.ts (VariableDeclarator.init check)
- architecture/react-compiler-destructure-method.ts (initializer check)
- correctness/no-prevent-default.ts (JSX prop expression check)
- correctness/no-uncontrolled-input.ts (VariableDeclarator.init check)
- js-performance/async-await-in-loop.ts (replaces local
  isFunctionishExpression with the canonical helper)
- js-performance/js-length-check-first.ts (CallExpression callback check)
- nextjs/nextjs-async-client-component.ts (VariableDeclarator.init check)

The 2-type pattern is intentionally narrower than isFunctionLike
because declarations only appear as statements — using the wider
`isFunctionLike` at these expression-position call sites would be
incorrect (and even if it weren't, the type-narrow wouldn't match).

event-handler-reference.ts re-exports the helper so its existing
intra-directory consumer keeps working without an import path change.

Behaviour-neutral; -28 lines net across the 7 files.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:37:51 +00:00
Cursor Agent 565f9c07f5 refactor(oxlint-plugin): replace inline 3-type function checks with isFunctionLike in 6 more rule files
Sweep across rule files where the inline triplet
`isNodeOfType(x, 'FunctionDeclaration') || ... || ...ArrowFunctionExpression`
was used as a pure boundary-check (not part of a richer predicate):

- architecture/no-legacy-context-api.ts
- js-performance/async-await-in-loop.ts (inside walkAst visitor)
- js-performance/js-batch-dom-css.ts
- js-performance/js-hoist-intl.ts
- nextjs/nextjs-no-side-effect-in-get-handler.ts
- performance/async-defer-await.ts (two sites — positive + negated)

Each site now imports the canonical isFunctionLike type guard.

Files where the triplet check is intentionally selective (e.g.
no-unstable-nested-components includes ClassDeclaration / ClassExpression,
inferFunctionLikeName in no-unstable-nested-components only matches
FunctionDeclaration + FunctionExpression for named-function lookup,
react-compiler-destructure-method uses a 2-type ArrowFunction/FunctionExpression
check for an initializer position) are left as-is.

Behaviour-neutral; ~30 lines net removed across the 6 files.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:21:55 +00:00
Cursor Agent f14eed5483 refactor(oxlint-plugin): no-array-index-as-key uses isFunctionLike for boundary checks
Two adjacent function-boundary checks (each constructed the same
isCrossingFunctionBoundary local from the 3-type triplet) collapse
to direct isFunctionLike(current) calls.

Behaviour-neutral; -10 lines net.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:12:32 +00:00
Cursor Agent 6d9103c863 refactor(oxlint-plugin): no-unstable-nested-components uses isFunctionLike for the parent-walker check
The walker that walks up the AST to find an enclosing component
inlined the 3-check (FunctionDeclaration / FunctionExpression /
ArrowFunctionExpression) pattern. Replace with the canonical
`isFunctionLike` type guard.

The other 3-check at `inferFunctionLikeName` is NOT replaced — that
one is specifically about "has a named function id" and only
matches FunctionDeclaration + FunctionExpression (excludes
ArrowFunctionExpression). Different semantic; left alone.

Behaviour-neutral; -4 lines net.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:09:11 +00:00
Cursor Agent 61edc3f0b7 refactor(oxlint-plugin): function-body-has-return-with-value uses FUNCTION_LIKE_TYPES
The local NESTED_FUNCTION_TYPES set (FunctionDeclaration /
FunctionExpression / ArrowFunctionExpression) was the same 3-element
set already centralised as FUNCTION_LIKE_TYPES in constants/js.ts.
Drop the local copy; import the canonical version.

Behaviour-neutral; -5 lines net.

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-05-25 16:05:06 +00:00