Commit Graph

97 Commits

Author SHA1 Message Date
Aiden Bai 13138a4af5 refactor: simplify internals across the workspace (#1590) 2026-08-08 00:20:14 -07:00
Aiden Bai 60e4d8e102 fix(cli): isolate interactive React runtime (#1577)
Bundle the Ink and React renderer so inspected projects cannot supply a missing or incompatible React runtime. Exercise the packed CLI in a real PTY against a React 18 fixture.
2026-08-04 15:01:08 -07:00
Aiden Bai 212b8b4113 fix: harden CLI against Sentry crash clusters (#1572) 2026-08-04 03:37:33 -07:00
Aiden Bai 19f2148e00 FPFNFIX82 Fix CSS-reserved image dimensions (#1550)
* fix(rule): recognize CSS-reserved image layout

* fix(rule): scope static CSS image evidence

* fix(no-img-without-dimensions): compose CSS with classes

* fix(no-img-without-dimensions): parse layered CSS

* fix(no-img-without-dimensions): ignore interaction-only CSS

* fix(no-img-without-dimensions): expand selector functions

* fix(no-img-without-dimensions): parse CSS with Lightning CSS

* fix(no-img-without-dimensions): model flex axes

* test(evals): stabilize manifest verification timeout

* test(evals): reset manifest operation deadlines

* fix(no-img-without-dimensions): honor nested CSS cascade

* fix(no-img-without-dimensions): compose Tailwind with CSS

* fix(no-img-without-dimensions): resolve same-layer cascade
2026-08-02 21:48:52 -07:00
Aiden Bai c3683a2850 feat(cli): make the interactive report the default (#1542)
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-08-02 01:09:19 -07:00
Aiden Bai 2db2a97283 perf: reduce scan startup and workspace contention (#1533) 2026-07-30 19:42:52 -07:00
Aiden Bai 83f3ff8ac7 fix: support Astro project scans (#1519) 2026-07-29 23:09:02 -07:00
Aiden Bai 3728102af1 chore: upgrade Oxc toolchain (#1467) 2026-07-27 19:03:34 -07:00
Aiden Bai 846c2df844 feat: add parsed Three.js shader lint rules (#1455)
* feat: add parsed Three.js shader lint rules

* fix: tighten shader rule precision

* fix: address shader rule review findings

* fix: harden parsed shader edge cases

* fix: harden shader variant analysis

* fix: complete parsed shader edge coverage

* fix: close shader control-flow gaps

* fix: tighten shader interface analysis

* fix: recognize GLSL3 integer samplers

* fix: close shader control-flow gaps

* fix: close remaining shader rule gaps

* fix: close shader review gaps

* fix: track shader cache key invalidation

* fix: handle shader material review edge cases

* fix: close remaining shader review gaps

* fix: skip uncertain shader position writes

* fix: harden shader position analysis

* fix: track divergent shader loop controls

* fix: track parameter shader variants

* fix: complete shader variant detection

* fix: identify and clean up parity sandboxes

* fix: tolerate Daytona cleanup races

* fix: restore complete parity corpus

* fix: tighten Three shader diagnostics

* fix: download large eval reports

* fix: trace shader variant aliases
2026-07-25 22:04:43 -07:00
Aiden Bai 1aa6b12fd6 fix: detect React Compiler through dependency configs (#1458) 2026-07-25 19:48:27 -07:00
Skosh 599e30d9e1 fix: share safe built-in control-flow proof across async rules (#1422)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Aiden Bai <aiden@million.dev>
2026-07-22 04:15:57 -07:00
Aiden Bai 9155bc0bc9 feat(cli): add experimental interactive Ink TUI (#979)
* feat(cli): add experimental interactive TUI

* fix(tui): isolate concurrent project reporters

* fix(tui): preserve project scoring config

* fix(tui): merge monorepo rule priorities

* fix(tui): finalize terminal lifecycle

* fix(tui): surface lint hard failures

* fix(tui): preserve monorepo project selection

* fix(tui): address interactive review findings

* fix(tui): constrain report to terminal height

* test(tui): tolerate colored code frames

* fix(tui): address final review findings

* fix(tui): honor configured blocking gate

---------

Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-07-22 02:13:58 -07:00
Aiden Bai 3d7ea66c3f perf: speed up React Doctor scans (#1423) 2026-07-21 20:35:22 -07:00
Aiden Bai 8c4959bb74 fix(rules): harden parity diagnostics (#1419)
* fix(rules): harden parity diagnostics

* fix(evals): keep parity artifacts parseable

* fix(evals): support Windows harness tests

* fix(fuzz): parse CRLF corpus directives
2026-07-20 22:28:25 -07:00
Aiden Bai 7c9dbeda0d feat(evals): add Daytona corpus parity runner (#1384) 2026-07-19 00:21:46 -07:00
Aiden Bai 76cd6bea69 perf: reduce cold scan startup and add V8 profiling (#1114)
* perf: reduce cold scan startup and add V8 profiling

Add repeatable CPU and heap profiling so cold-run bottlenecks can be measured, then remove profile-proven startup, traversal, and security-scan overhead.

* perf: add deterministic stress benchmark

Exercise cold scans with reproducible diagnostics and remove redundant visitor-map allocations so regressions are measurable and behavior stays hash-verifiable.

* fix(tests): normalize benchmark paths cross-platform

Resolve the absolute fixture path through Node so the harness expectation matches Windows path semantics.

* perf: avoid effect analysis parent traversal

Reuse Oxc visitor keys with a parent-safe fallback so effect scope analysis no longer strips and restores every AST parent reference.

* perf: reduce repeated semantic traversal

Reuse host visitors and shared analysis caches to avoid redundant cold-scan AST passes while preserving diagnostic parity.

* fix: harden performance regression coverage

* fix(perf): support profiling on Node 20

* fix(plugin): skip CFGs for bodyless functions

* fix: harden profiling and semantic compatibility

Prevent benchmark artifacts and host differences from corrupting comparisons, while preserving host AST and React Compiler compatibility across optimized scan paths.

* fix(plugin): preserve rule correctness in fast scan paths

Keep security prefilters comment-tolerant and resolve React HOC wrappers by binding provenance so scan optimizations cannot hide valid diagnostics.

* fix: address review findings and consolidate duplicated code

- wrapWithSemanticContext copies the rule's visitors instead of mutating
  a possibly shared object; walkAst regains its null-root guard
- no-multi-comp HOC identity accepts React-compat runtimes via
  REACT_RUNTIME_MODULE_SOURCES (now incl. @wordpress/element) across
  ESM, require(), and TS import-equals, with regression coverage in
  both directions
- shared traversal core (forEachChildNode) replaces the walkChildren and
  containsJsx copies; isImportedFromReact deduped into is-react-api-call
- performance harness consolidated (27 -> 22 files): shared commander
  options, shared profile-frame accumulation, record shape guards, dead
  BenchmarkSample.profileDirectory removed
- CLI-spawning harness tests skip without a built dist; dead and
  tautological test assertions removed

Net -282 LOC against the branch head.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(plugin): capture the Program root for every rule

Rules can reach context.scopes through shared helpers and factories
(createDeprecatedReactImportRule resolves namespace aliases via
resolveConstIdentifierAlias), so the codegen'd requiresSemanticContext
flag — a regex over the rule's own file — silently left factory-based
rules on stub scope analyses: no-react-dom-deprecated-apis and
no-react19-deprecated-apis stopped reporting namespace usages through
the host wrapper.

Delete the flag and its regex detector entirely and install the
root-capture Program visitor on every rule. The analyses stay lazy and
memoized per Program, so rules that never read them still pay only one
call per rule per file, and no future helper-routed consumer can be
missed. Regression test runs the real host-wrapped rule and fails
against the gated wrapper.

Fixes cursor bugbot review finding on PR #1114.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(scripts): reject cyclic heap-profile node graphs during collection

collectNodes flattened the parsed tree with no visited guard, so a
cyclic or shared-node object graph would loop before reaching the
duplicate-ID check. Unreachable through analyzeHeapProfiles (JSON.parse
output is always a strict tree), but guard and throw like the CPU
analyzer so a synthetic graph fails deterministically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 21:40:52 -04:00
devin-ai-integration[bot] 0748a4ba19 test: adversarial fuzzing harness for every rule (@react-doctor/fuzz) (#1022)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-07-02 15:09:02 -07:00
Ray Arayilakath e2393c4a6b feat(cli): add ci command for managing CI (#955)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:17:10 -04:00
Skosh 03b7a5f79e fix: exclude TypeScript 6.x to fix bunx installation crash (#963)
* fix: exclude TypeScript 6.x to fix bunx installation crash

TypeScript 6.0.3 has an internal circular dependency with its Comparison
enum that triggers a known Bun module loader bug, causing
`bunx react-doctor install` to crash with "ReferenceError: Cannot access
'Comparison' before initialization".

Narrow the dependency range from `>=5.0.4 <7` to `>=5.0.4 <6` until Bun
fixes enum initialization order (see oven-sh/bun#12805).

`npx` continues to work because npm's resolver handles the circular
dependency correctly. TypeScript 5.9.3 is stable and tested; TypeScript
6.x support will return once the upstream bug is resolved.

Closes #962

Co-authored-by: Skosh <skoshx@users.noreply.github.com>

* fix(deslop-js): pin typescript <6, drop no-op core pin

The bunx install crash is react-doctor's own startup `import typescript` (already
pinned <6); the residual vector is the dead-code scan loading deslop-js, which
still declared `typescript@^6.0.3`. Pin deslop-js to `>=5.0.4 <6` too — 487
deslop-js tests pass under 5.9.3. Revert the @react-doctor/core hunk: core is
private and never published, so narrowing its range reached no consumer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Skosh <skoshx@users.noreply.github.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:53:24 -07:00
Aiden Bai 8bbcca87da chore: vendor deslop-js + deslop-cli into the monorepo (#880) 2026-06-19 01:02:54 -07:00
Ray Arayilakath 350a6edc59 fix(core): support TypeScript 5 alongside 6 (#890)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 03:14:38 -04:00
devin-ai-integration[bot] b08ca1c919 chore(deps): upgrade oxc-parser to 0.135.0 (#835)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-15 16:35:03 -07:00
devin-ai-integration[bot] 0a9d583109 chore: bump deslop-js to ^0.0.24 (#802)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 19:17:45 -07:00
Ray Arayilakath 22268f70ac fix: cap oxlint below 1.67 to stop duplicate Vitest instances in pnpm repos (#791)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:33:38 -04:00
devin-ai-integration[bot] f63ed9dd11 chore: bump deslop-js to ^0.0.23 (#785)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-10 19:28:55 -07:00
Aiden Bai 1ca6f0ead3 Fix react-doctor npx engine warning (#731) 2026-06-09 18:23:20 -07:00
Nisarg Patel 963eaf53db feat(core): flag React Server Components security advisories by version (#741)
* feat(core): add concrete-semver parsing and comparison util

Adds parseConcreteSemver/compareConcreteSemver/formatConcreteSemver for
exact major.minor.patch versions, rejecting ambiguous range specs so a
security check never guesses a resolved version. Exposes PackageJson.version
for reading installed manifests under node_modules.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* feat(core): flag React Server Components security advisories by version

Adds a no-vulnerable-react-server-components environment check that detects
projects running RSC on a version with a known advisory: the critical
unauthenticated RCE (CVE-2025-55182, CVSS 10.0) and the later high-severity
DoS (CVE-2026-23870).

- Cross-framework path (Vite, Parcel, React Router, Waku, RedwoodSDK):
  resolves the installed react-server-dom-{webpack,parcel,turbopack} version
  and compares against the per-minor patched releases (19.0.6/19.1.7/19.2.6).
- Next.js special plumbing: Next vendors its own RSC runtime, so a Next
  project is checked by its next version (15.x->15.5.18, 16.x->16.2.6, 13/14
  unsupported) and the fix points at a Next.js bump, not a React bump.
- Stays quiet for pure client-side React apps and never flags off an
  ambiguous declared range whose lockfile may resolve to a patched version.

Wired into the run-inspect environment phase alongside checkPnpmHardening.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* refactor(core): address review on RSC advisory check

- Use the `semver` library instead of a hand-rolled version parser/comparator
  (removes packages/core/src/utils/concrete-semver.ts and its test).
- Resolve installed versions across every workspace package's node_modules in
  addition to the scan root, so a monorepo whose `next`/`react-server-dom-*`
  is installed only under e.g. apps/web is still detected (fixes Bugbot
  'Misses workspace node_modules installs').
- Add committed test fixtures under
  tests/fixtures/check-react-server-components-advisory and drive the
  version-matrix suite off them; keep programmatic tests for node_modules
  resolution, the monorepo regression, and canary handling.
- Changeset bumped to patch; drop the redundant PackageJson.version comment.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* fix(core): dispatch RSC advisory on resolved next, not root framework

A monorepo root classified as Vite (or unknown) with Next.js installed only
in a workspace previously skipped the Next.js advisory check, missing the
vendored RSC runtime. Dispatch now keys on whether `next` resolves in any
candidate directory. Fixes Bugbot 'Non-Next framework skips Next check'.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* fix(core): check every workspace install for RSC advisories

Replaces single first-match resolution with a per-directory scan so:
- An inert/safe Next at the monorepo root no longer hides a vulnerable Next
  in a workspace (Bugbot 'First next wins over workspace').
- A pre-13 Next install no longer suppresses the standalone react-server-dom
  check, since pre-13 is not an affected line (Bugbot 'Pre-13 next skips RSC
  check').

Diagnostics are deduplicated by message across directories.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* fix(core): walk to true monorepo root for RSC advisory candidates

When scanning a nested workspace package, deps may be hoisted to the real
monorepo root. Walk up via findMonorepoRoot so that root (and its
node_modules) and every sibling workspace are probed, instead of only the
scanned directory. Fixes Bugbot 'Workspace scan misses monorepo root'.

Fixture tests are copied into an isolated temp dir so the walk-up does not
reach the react-doctor repo root they live under.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* fix(core): don't let an unparseable catalog spec shadow resolved next version

resolveVersionInDirectory now falls through to the first spec that is a
concrete version, so a `catalog:` (or other unparseable) manifest spec no
longer shadows discovery's already-resolved `project.nextjsVersion` pin.
Fixes Bugbot 'Catalog spec blocks version override'.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

* fix(core): probe all workspaces, not just React-bearing ones

Enumerate every workspace package directory for candidate node_modules
probing instead of reusing the React-filtered listWorkspacePackages, so a
workspace declaring only react-server-dom-* (or next under optionalDependencies)
is still evaluated. Fixes Bugbot 'Skips non-React workspace packages'.

Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Nisarg Patel <NisargIO@users.noreply.github.com>
2026-06-08 22:39:39 -07:00
devin-ai-integration[bot] f61adc4b66 chore: bump deslop-js from ^0.0.20 to ^0.0.21 (#719)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-07 00:24:42 -07:00
devin-ai-integration[bot] ee980d98e0 chore: bump deslop-js from ^0.0.19 to ^0.0.20 (#717)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-06 19:46:04 -07:00
Ray Arayilakath 915745ef7b feat(language-server): editor language server behind react-doctor experimental-lsp (#681)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 17:43:53 -04:00
devin-ai-integration[bot] 67be206087 chore: bump deslop-js to ^0.0.19 (#679)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-04 03:49:32 -07:00
Aiden Bai 6851a786e5 chore: bump deslop-js to 0.0.17 (#674) 2026-06-03 17:13:50 -07:00
Aiden Bai 3c05fc4d63 chore: bump deslop-js (#668) 2026-06-03 03:10:32 -07:00
Aiden Bai 19b39c0e0d chore: bump deslop-js to 0.0.15 (#659)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-02 17:23:01 -07:00
Ray Arayilakath 75c1f99e06 fix(oxlint-plugin-react-doctor): declare oxc-parser as a runtime dependency (#630)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 07:02:17 -04:00
Ray Arayilakath e9e71bbc2f feat(cli): deepen sentry observability -- source maps, tracing, anonymization, crash refs (#628)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 06:19:25 -04:00
Ray Arayilakath 9777f1ac45 feat(cli): add rules management commands and doctor-explain skill (#617)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 05:55:47 -04:00
Nisarg Patel 24425b113a feat(cli): add Sentry crash reporting (#621)
* feat(cli): add Sentry crash reporting

Capture uncaught CLI errors via @sentry/node, flushed before the process
exits and enriched with a run-context snapshot (version, node/platform/
arch, invocation command/argv, cwd, CI provider, coding agent,
interactivity, JSON mode). Initialized as the first statement of the CLI
entry and scoped to the CLI only — the @react-doctor/api library never
initializes Sentry. Opt out via --no-score (also skipped under tests).

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

* refactor(cli): consolidate CI/agent detection into is-ci-environment

build-run-context re-declared CI provider and coding-agent env-var maps
that mirrored is-ci-environment. Move the label maps and the
detectCiProvider/detectCodingAgent resolvers into is-ci-environment as the
single source of truth, derive the flat agent env-var list from the brand
map, and have isCodingAgentEnvironment derive from detectCodingAgent.
Behavior is unchanged (env-detection tests still green).

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 21:51:18 -07:00
Ray Arayilakath f1913f27f5 chore(skills): add truffler symbol-search tooling and deslop skill (#618)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 21:45:11 -04:00
Aiden Bai 6e59f10ef8 feat: new onboarding (#596) 2026-05-31 02:24:23 -07:00
Ray Arayilakath 4861f37a55 chore(deps): bump deslop-js to 0.0.14 (#605)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 19:18:59 -04:00
Ray Arayilakath 5f7cc7c36e feat: publish JSON Schema for react-doctor.config.json (#601)
Co-authored-by: materwelonDhruv <materwelondhruv@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 18:27:08 -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
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
Ray Arayilakath e9a752974d feat: add onboarding on first run (#467)
* Prompt setup after scored scans

* Add React Doctor setup prompt

* Add React Doctor dev dependency setup

* Handle setup prompt failures

* Handle setup prompt edge cases

* Format setup prompt changes

* Avoid repeated setup prompts after acceptance

* Preserve scan exit code on setup cancel

* Handle setup prompt review feedback
2026-05-24 22:21:08 -04:00
Aiden Bai 6ac928383d Fix Node 20 runtime dependency support (#469) 2026-05-24 18:44:44 -07:00
Aiden Bai 523696940c Revert "feat(action): React Doctor Review composite action (#307)" (#443)
This reverts commit 30f05ef532.
2026-05-23 01:35:12 -07:00
Aiden Bai aa61efae28 refactor: collapse @react-doctor/types and @react-doctor/project-info into core (#440)
* refactor: collapse @react-doctor/types and @react-doctor/project-info into core

Eliminates two private workspace packages whose only role was to
namespace shared TS types and project-discovery helpers — neither
was a real consumer boundary, and the indirection cost a `workspace:*`
edge per leaf package without saving any code.

**Layout**

- `packages/types/` → `packages/core/src/types/` (10 files, pure TS types)
- `packages/project-info/` → `packages/core/src/project-info/`
  (27 files, discoverProject + framework detection + monorepo helpers)
- `packages/types/src/react-native-dependency-names.ts` →
  `packages/oxlint-plugin-react-doctor/src/react-native-dependency-names.ts`
  (the canonical RN-aware-package list lives next to its heaviest
  consumer — the rule gate — and is re-exported from core to avoid
  the rule-plugin ↔ core dependency cycle the previous types package
  was specifically designed to break).

The two packages are deleted from the workspace; every consumer
(`react-doctor`, `api`, `oxlint-plugin-react-doctor`, `actions/review`,
+130 source/test files) now imports from `@react-doctor/core` directly.

**Errors cleanup**

Dropped the legacy plain-class `ReactDoctorError` and `isReactDoctorError`
from `project-info`. The four narrow errors (`ProjectNotFoundError`,
`NoReactDependencyError`, `PackageJsonNotFoundError`,
`AmbiguousProjectError`) now extend `Error` directly — the only valid
hierarchy is the tagged `Schema.TaggedErrorClass` `ReactDoctorError`
from `core/errors.ts`, which has been the canonical one since the
Effect v4 refactor. Added `isProjectDiscoveryError` as a narrow type
guard for the four leaves.

The discovery errors are thrown synchronously BEFORE the Effect
runtime takes over (at `diagnose()` / CLI entry points); inside the
runtime, the Project service's `translateProjectInfoError` converts
each one to its tagged-reason equivalent.

**Schema vs type name collisions**

`schemas.ts` exports `Diagnostic` / `JsonReport` / `JsonReportMode` /
… as Schema.Class values, while `types/` exports the same names as
TS types. The core barrel re-exports the TS-type versions
(broad-strokes API) and exposes the Schema classes via a new
`@react-doctor/core/schemas` subpath export for the two callers
that need them (`Reporter` service, smoke validator, schema tests).

**Validation**

- `pnpm typecheck` ✓
- `pnpm lint` ✓
- `pnpm format` ✓
- `pnpm test` ✓ (1449 passing, 3 skipped — no regressions)
- `pnpm smoke:json-report` ✓

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

* fix(core): keep RN-dependency constants out of types barrel to avoid pulling oxlint plugin into discovery

Bugbot caught (medium severity): re-exporting `isReactNativeDependencyName` from
`oxlint-plugin-react-doctor` via the core types barrel meant every consumer of
`@react-doctor/core` (including `discoverProject` / `discoverReactSubprojects`)
would load the entire 286-rule plugin at module-init.

Adds a tiny standalone leaf at `core/src/project-info/internal-rn-dependency-names.ts`
(zero imports, just the constants the workspace-discovery gate needs) and switches
`is-package-json-react-native-aware.ts` to use it. The types barrel no longer
re-exports the plugin-side constants — rule consumers import them directly from
`oxlint-plugin-react-doctor`.

The duplication is intentional and documented at both files; the two lists are
short enough that a future regression test in the plugin can observe the union.

Validated: typecheck + test (1449 pass) + lint + format all green.
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 01:32:44 -07:00