11 Commits

Author SHA1 Message Date
Aiden Bai 0eb635ac7f feat(react-doctor): add TanStack Start rules (#124)
Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-04-14 17:43:57 -07:00
Aiden Bai 10bd788323 fix: address multiple GitHub issues (#117, #113, #119, #106) (#120)
* fix: detect namespace hook calls (React.useState, React.useEffect) in all rules

Fixes #117: isHookCall now handles MemberExpression callee types
(e.g. React.useEffect, React.useState) in addition to plain Identifier
callee types. This fixes silent misses in no-derived-state-effect,
no-fetch-in-effect, no-cascading-set-state, no-effect-event-handler,
rerender-functional-setstate, rendering-hydration-no-flicker, and
the countSetStateCalls helper.

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

* fix: remove unsupported jsx-a11y/no-noninteractive-element-interactions rule

Fixes #113, #119: This rule does not exist in the bundled oxlint
binary, causing 'Failed to parse oxlint configuration file' errors
and score suppression on all scans.

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

* feat: add --no flag to skip prompts and always run full scan

Fixes #106: Adds -n/--no flag that skips all interactive prompts
(like --yes) but specifically declines the diff-only scan prompt,
ensuring a full project scan runs. Useful for CI agents that cannot
interact with TTY prompts.

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

* test: add namespace hook detection tests (React.useEffect, React.useState, etc.)

Adds 13 tests verifying that all rules correctly detect namespace-style
hook calls (import * as React; React.useEffect, React.useState, etc.).
Covers: no-derived-state-effect, no-fetch-in-effect, no-cascading-set-state,
no-effect-event-handler, no-derived-useState, rerender-lazy-state-init,
rerender-functional-setstate, rerender-dependencies, rendering-hydration-no-flicker,
no-usememo-simple-expression, prefer-useReducer, plus a regression guard for
direct-import fixtures.

Relates to #117.

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

* test: add edge case tests for project discovery and catalog resolution

Adds tests for:
- peerDependencies-only with catalog reference resolution
- Catalog reference to nonexistent catalog name (fallback to default)
- Empty pnpm-workspace.yaml handling
- Malformed package.json in workspace subdirectories
- Nonexistent root directory for discoverReactSubprojects
- File entries mixed with directory entries in project root

Relates to #101, #87, #105, #71.

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

* fix: handle malformed JSON in workspace package.json files gracefully

readPackageJson now catches SyntaxError from malformed JSON and returns
an empty object instead of crashing. This prevents workspace discovery
from aborting when a subdirectory has an invalid package.json.

Previously, a broken package.json in any workspace subdirectory would
crash the entire scan with an unhandled SyntaxError.

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

* feat: add customRulesOnly config to disable builtin react/jsx-a11y rules

Fixes #109: Teams with existing ESLint setups can now set
customRulesOnly: true in react-doctor.config.json to only run
react-doctor/* custom rules, skipping the bundled react/, jsx-a11y/,
react-perf, and react-compiler rules.

This avoids rule duplication for projects that already lint with
eslint-plugin-react, eslint-plugin-jsx-a11y, etc.

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

* feat: inherit config from ancestor directories for monorepo support

Fixes #73: loadConfig now walks up the directory tree to find
react-doctor.config.json or package.json reactDoctor key from
ancestor directories. This means a single config at the monorepo
root applies to all workspace packages without needing to duplicate
the config in each package.

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

* feat: add --annotations flag for GitHub Actions annotation output

Fixes #81: The --annotations flag outputs diagnostics in GitHub
Actions annotation format (::error / ::warning) so they appear
as inline annotations on PR diffs. Example:
  ::error file=src/App.tsx,line=42,title=react-doctor/no-fetch-in-effect::fetch() inside useEffect

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

* refactor: remove Ami integration

Removes all Ami-related code:
- --ami flag, --fix flag, fix subcommand, install-ami subcommand
- Ami detection, installation, deeplinks, and open-URL helpers
- Fix prompt (maybePromptFix) with Ami banners
- Skill installation prompt (maybePromptSkillInstall)
- fetchEstimatedScore and EstimatedScoreResult
- AMI_WEBSITE_URL, AMI_INSTALL_URL, AMI_RELEASES_URL, OPEN_BASE_URL,
  ESTIMATE_SCORE_API_URL, ERROR_ESTIMATED_FIX_RATE, WARNING_ESTIMATED_FIX_RATE
- skill-prompt.ts utility

CLI bundle reduced by ~39KB (324KB → 285KB).

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

* chore: remove .ami directory and all remaining Ami references

- Delete .ami/ directory (42 skill/config files)
- Delete packages/website/src/app/open/ (Ami redirect page)
- Remove Ami references from README.md, share page, install-skill
  route, llms.txt, and install-skill.sh
- Zero Ami references remain in the codebase

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

* chore: move .ami/skills to .agents/skills

Relocates all skill files from the deleted .ami/ directory into
.agents/skills/ and removes .agents from .gitignore so they are
tracked in version control.

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

* fix: recognize custom text components in rn-no-raw-text rule

Fixes #93: The rn-no-raw-text rule now recognizes a much wider set of
text-handling components:

1. Expanded built-in names: Typography, Paragraph, Span, H1-H6
2. Keyword matching instead of suffix-only: any component whose name
   contains Text, Title, Label, Heading, Caption, Subtitle, Typography,
   Paragraph, Description, or Body is treated as text-handling
   (e.g. StyledText, BodyText, CustomLabel, MyTypography)
3. New textComponents config option: users can specify arbitrary
   component names in react-doctor.config.json that should be treated
   as text-handling:

   {
     "textComponents": ["MyCustomComp", "NativeWindText"]
   }

   Diagnostics inside these components are filtered out post-lint.

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

* chore: upgrade dependencies

- oxlint: 1.47.0 → 1.59.0 (fixes SIGABRT crashes on large projects #84/#77)
- oxfmt: 0.32.0 → 0.44.0
- typescript: 5.9.3 → 6.0.2
- vitest: 4.0.18 → 4.1.4
- tsdown: 0.20.3 → 0.21.7
- knip: 5.83.1 → 6.3.1

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

* fix: add file count limit per oxlint batch to prevent OOM crashes

Mitigates #84/#77: Adds OXLINT_MAX_FILES_PER_BATCH (500) to cap the
number of files per oxlint invocation. Combined with the oxlint upgrade
from 1.47 to 1.59, this prevents SIGABRT/OOM crashes on large projects
with 100+ source files.

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

* feat: add --staged flag for pre-commit hook scanning

Fixes #115: The --staged flag scans only files in the git index
(staged with git add). It materializes staged content to a temp
directory so oxlint reads the exact index version, not the working
tree version. This is critical for pre-commit hooks where the working
tree may differ from what's being committed.

Usage:
  npx react-doctor . --staged --fail-on error

For lint-staged:
  "*.{tsx,jsx}": "npx react-doctor . --staged --fail-on error"

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

* refactor: code review fixes per AGENTS.md rules

- DRY: Extract shared createFileLinesCache in filter-diagnostics.ts
- DRY: Extract resolveFailOnLevel in cli.ts (was duplicated in
  staged and normal paths)
- DRY: Reuse exported getCalleeName from helpers.ts instead of
  duplicating in state-and-effects.ts and performance.ts
- Magic number: Move maxBuffer 10MB to GIT_SHOW_MAX_BUFFER_BYTES constant
- Variable naming: prevLine → previousLine, tagName → fullTagName,
  leafName → leafTagName, configFiles → projectConfigFilenames
- Remove .pop()! non-null assertion in favor of .at(-1) with fallback

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

* fix: prevent shell injection in staged file content reading

Replace execSync with string interpolation with spawnSync using an
args array. File paths with shell metacharacters (quotes, semicolons,
etc.) in their names are now passed safely without shell interpretation.

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

* fix: pass resolved config to staged scan to preserve ancestor inheritance

The staged scan materializes files to /tmp, where loadConfig's ancestor
traversal would never find a monorepo root's config. Now the CLI resolves
config from the real project directory first and passes it via the new
configOverride ScanOption, so customRulesOnly, share, ignore rules,
and textComponents all apply correctly during --staged scans.

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

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-04-10 21:49:25 -07:00
Aiden Bai 1aef45a509 fix: resolve 7 GitHub issues (catalog resolution, file ignoring, CLI, RN, Next.js, offline, monorepo) (#108)
Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-04-06 16:24:32 -07:00
Aiden Bai 14106508a6 Update package.json and constants for react-doctor
- Added homepage and bugs fields to package.json for better project visibility.
- Introduced new constants for React Native deprecated modules and legacy Expo package replacements in constants.ts.
- Updated index.ts to include new rules for React Native diagnostics.
2026-02-17 10:54:59 -08:00
Aiden Bai 34d1c5b79c 0.0.13 2026-02-17 10:23:45 -08:00
Aiden Bai 327fcc9b50 fix formatting
Generated with [Ami](https://ami.dev)
Co-Authored-By: Ami <noreply@ami.dev>
2026-02-16 05:55:14 -08:00
Aiden Bai 4b48dce62c add packageManager field for CI pnpm setup
Generated with [Ami](https://ami.dev)
Co-Authored-By: Ami <noreply@ami.dev>
2026-02-16 05:52:52 -08:00
Aiden Bai 43816dbc45 fix 2026-02-16 03:45:48 -08:00
Aiden Bai c3ba00b7c6 fix 2026-02-16 00:47:36 -08:00
Aiden Bai a8770b7a10 add CLI scaffolding with oxlint integration
Scaffolds the react-doctor CLI with project discovery, oxlint spawning,
and categorized diagnostic output. Bundles 36 rules across 5 plugins
(react, jsx-a11y, react-perf, import, typescript).

Generated with [Ami](https://ami.dev)
Co-Authored-By: Ami <noreply@ami.dev>
2026-02-15 18:09:23 -08:00
Aiden Bai f50426b5ad init 2026-02-13 04:08:01 -08:00