Commit Graph

767 Commits

Author SHA1 Message Date
github-actions[bot] f229c75d4b chore: version packages (#806) react-doctor@0.5.4 oxlint-plugin-react-doctor@0.5.4 eslint-plugin-react-doctor@0.5.4 2026-06-13 04:00:14 -07:00
Aiden Bai eacdcf2e65 Add project-level security scan rules (#744)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-06-13 03:57:25 -07:00
github-actions[bot] 0b30023ac6 chore: version packages (#805) react-doctor@0.5.3 oxlint-plugin-react-doctor@0.5.3 eslint-plugin-react-doctor@0.5.3 2026-06-13 03:22:47 -07:00
Nisarg Patel 022790bf9e feat: name Socket alerts and give axis-aware help in supply-chain diagnostics (#804)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-13 03:21:42 -07:00
github-actions[bot] 094d470d13 chore: version packages (#764) react-doctor@0.5.2 oxlint-plugin-react-doctor@0.5.2 eslint-plugin-react-doctor@0.5.2 2026-06-12 20:24:27 -07:00
devin-ai-integration[bot] 3de910612d fix: resolve react-doctor/api imports in doctor.config.ts without local node_modules (#800)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 19:58:18 -07:00
devin-ai-integration[bot] 0f91fa36b8 feat: rn-no-metro-babel-runtime-version — flag RN babel preset missing enableBabelRuntime (#801)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
Co-authored-by: D N <4661784+retyui@users.noreply.github.com>
2026-06-12 19:29:04 -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
devin-ai-integration[bot] 9cc655591e feat: carry the React Compiler bail-out reason in the primary diagnostic message (#793)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 15:41:40 -07:00
devin-ai-integration[bot] 04e72a4d56 feat: label test/story file context on diagnostic sites (#795)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 03:50:35 -07:00
devin-ai-integration[bot] 7c8816575a fix: rules-of-hooks FP on forwardRef/memo callbacks under non-PascalCase bindings (#794)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 01:29:56 -07:00
devin-ai-integration[bot] fee3fc436e fix(no-barrel-import): framework-aware wording for React Native targets (#796)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 00:28:34 -07:00
devin-ai-integration[bot] 19d99eee1e fix: title react-hooks-js/todo diagnostics as unsupported syntax (#792)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-12 00:17:14 -07:00
devin-ai-integration[bot] d48e7f1695 feat: per-module scoring via diagnose({ projects }), CLI --project paths, and config projects (#771)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-06-11 21:55:48 -07:00
devin-ai-integration[bot] f52bd07375 fix: rn-no-raw-text false positives for nested-Text wrappers and test files (#790)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-11 21:05:01 -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] a48fb06ffb feat: add --output-dir flag for the full diagnostics dump (#783)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
Co-authored-by: Rayhan Noufal Arayilakath <me@rayhanadev.com>
2026-06-11 00:36:56 -07: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
Ray Arayilakath 038aaf78c1 fix(nextjs-missing-metadata): stop flagging pages that inherit layout metadata (#784)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 18:20:32 -04:00
Ray Arayilakath c4f0e607b6 fix(only-export-components): skip framework route/special files (#776) (#782)
* fix(only-export-components): skip framework route/special files (#776)

Recognize the route/special files of every file-routing framework
react-doctor covers (Next.js, Expo Router, TanStack Router, Remix /
React Router) via a single `isFrameworkRouteOrSpecialFilename` helper,
so the documented "co-export config/metadata next to the default
component" shape no longer triggers false-positive non-component-export
warnings. Fixes the `alt` / `size` / `contentType` / `revalidate`
exports in `opengraph-image.tsx`.

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

* fix: change variable name

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: update usages as well

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-06-10 18:14:37 -04:00
Ray Arayilakath f5f539a1a3 fix: gate the Socket supply-chain check on security axes, not the overall score (#780)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 17:46:34 -04:00
Ray Arayilakath 2f26228e36 feat: consolidate scan scope into one --scope flag (#769)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 02:51:42 -04:00
Ray Arayilakath a64093c8a1 fix: resolve the repo's default branch for CI onboarding instead of assuming main (#768)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 00:56:01 -04:00
Ray Arayilakath 486c68f655 feat(action): default the blocking gate to advisory (#767)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 23:58:17 -04:00
devin-ai-integration[bot] 94f9f4fe98 fix: bump engines.node to ^20.19.0 || >=22.13.0 (#766) 2026-06-09 20:14:30 -07:00
Aiden Bai 1ca6f0ead3 Fix react-doctor npx engine warning (#731) 2026-06-09 18:23:20 -07:00
Ray Arayilakath d75654be09 ci: pin internal actions to commit SHAs (#754)
Pin actions/setup-node and actions/github-script (referenced inside the
composite action.yml) to full-length commit SHAs, with a trailing version
comment, so the action is consumable under orgs that enforce GitHub's
"actions pinned to a full-length commit SHA" ruleset. Also updates the
github-action contract test to accept SHA-pinned refs (either a floating
major tag or a SHA-pin), keeping the major-version floor.

Supersedes #751.

Co-authored-by: pauldambra <paul@posthog.com>
2026-06-09 15:18:13 -07:00
github-actions[bot] b819e5f170 chore: version packages (#762) react-doctor@0.5.1 oxlint-plugin-react-doctor@0.5.1 eslint-plugin-react-doctor@0.5.1 2026-06-09 15:02:13 -07:00
devin-ai-integration[bot] 4aba728274 fix: stop flagging navigate() in onXxx options and handler-named functions (#760)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-09 14:09:38 -07:00
devin-ai-integration[bot] 77a70ab8a7 fix(only-export-components): stop flagging framework route modules (#761)
Co-authored-by: Aiden Bai <aiden.bai05@gmail.com>
2026-06-09 13:55:12 -07:00
github-actions[bot] cbb7975570 chore: version packages (#727) react-doctor@0.5.0 oxlint-plugin-react-doctor@0.5.0 eslint-plugin-react-doctor@0.5.0 2026-06-09 02:07:26 -07:00
Nisarg Patel a254414666 feat: Socket.dev supply-chain score check (#747)
* feat(core): add Socket.dev supply-chain score check

New SupplyChain service + checkSupplyChain that score each direct dependency against Socket's free, keyless PURL endpoint (the same lookup sfw's free tier uses) and emit a Security diagnostic for any package below the configured minScore. Implemented with Effect (Effect.forEach bounded concurrency, Effect.tryPromise + Effect.timeout for cancellable fetches, fail-open per package).

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

* feat: wire SupplyChain into the inspect pipeline

Run the supply-chain check as a scan phase in runInspect (skipped in diff/staged mode), and provide its layer at every composition site: gated on supplyChain.enabled in the CLI (build-runtime-layers) and api (diagnose), and a no-op layerOf([]) for editor scans and the run-inspect tests.

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

* chore: add changeset for Socket supply-chain score check

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

* feat: run Socket supply-chain check by default

Flip the default so the supply-chain score gate runs out of the box; users opt out with `supplyChain: { enabled: false }`. Editor scans and --diff/--staged runs remain off regardless.

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

* feat(cli): add --sfw demo flag to list Socket scores for all dependencies

New collectSupplyChainScores core helper fetches the Socket score of every direct dependency (reusing the free-tier fetch internals). The CLI's --sfw flag short-circuits before the scan, prints a color-coded worst-first table via renderSupplyChainScores, and exits. Mutually exclusive with --json/--score.

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

* fix(core): anchor supply-chain diagnostic to the declared package.json entry

The diagnostic now points at the exact line/column where the dependency is declared in package.json (instead of line 0) and names the declared spec plus the entry to edit, so a finding like next@16.2.4 traces directly to its `"next": "16.2.4"` entry. Records the declared spec + key location while collecting dependencies.

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

* fix(cli): drop the free-API subtitle from --sfw header

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

* feat(cli): scan every workspace package.json for --sfw in a monorepo

collectSupplyChainScores now aggregates direct dependencies across the workspace root and every workspace package (pnpm/npm/yarn/nx globs via the shared project-info resolvers), deduped by name@version and anchored at the true monorepo root even when invoked from a sub-package. The in-scan check stays per-project (the scan loop already visits each workspace).

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

* feat(core): exclude next from the supply-chain check

next's framework-specific risks are already covered by react-doctor's Next.js / server-components rules, so a low Socket score is redundant noise. Add a SUPPLY_CHAIN_IGNORED_PACKAGES set and filter it in the shared dependency collector so both the gate and the --sfw listing skip it.

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

* refactor(core): drop unused breakdown field and trim Socket artifact schema

The --sfw renderer only reads name/version/overall, so the per-axis breakdown on DependencyScore was speculative dead code — remove it and its construction. Also trim SocketArtifactSchema to the only field read (score); Schema.Struct already ignores the artifact's other fields.

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

* fix(core): anchor supply-chain diagnostic within its dependency section

locateDependencyKey previously returned the first `"name":` match anywhere in package.json, so a same-named entry under overrides / resolutions / pnpm.overrides could win over the real dependencies/devDependencies line. Scope the search to the declaring section via its `"<section>": {` header + brace-depth tracking. Fixes Cursor Bugbot finding.

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

* refactor(api): derive supplyChain enablement from config in buildDiagnoseLayer

Drop the standalone supplyChainEnabled parameter; buildDiagnoseLayer now takes the effective config (and optional override directory), builds the config layer from it, and reads supplyChain.enabled from that same config. One config input drives both the Config service and the supply-chain gate.

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

* feat(core): emit a per-package OTel span for each Socket score lookup

Wrap fetchSocketScore in a SupplyChain.fetchScore span carrying socket.package / socket.version / socket.purl, and annotate the resolved axis scores (socket.score.overall + one per SCORE_AXES dimension, 0-100) plus socket.scored. Lets a trace backend group by package and query score distributions across a scan. No-op without a tracer.

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

* refactor(core): inline buildScoreSpanAttributes into its single call site

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

* feat(core): run supply-chain in diff mode when the manifest changed

Add supplyChainManifestChanged to InspectInput/InspectOptions and gate the supply-chain phase on (!isDiffMode || supplyChainManifestChanged), so a diff/PR scan that edits package.json still scores its dependencies instead of skipping the check like the other whole-project passes.

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

* feat(cli): scan a workspace whose package.json changed in a PR diff

Detect per-project package.json changes (projectManifestChanged, monorepo-aware via the same prefix logic as the include-path resolver). A manifest-only-changed workspace is no longer skipped from the diff loop: it enters the scan with the manifest as the sole include (stays in diff mode, lints nothing) and supplyChainManifestChanged set, so its dependencies get scored. Threaded the flag through the inspect wrapper + scan-result cache key.

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

* refactor(cli): share project-relative-directory boundary logic across diff helpers

projectManifestChanged duplicated resolveProjectDiffIncludePaths's project-relative + ..-boundary handling. Extract resolveProjectRelativeDirectory and repoint both so the monorepo prefix rule lives in one place and can't drift.

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

* docs(changeset): reflect diff-mode manifest scoring, monorepo --sfw, and next exclusion

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

* fix(cli): make --sfw exclusive with diff/staged and score the base manifest in baseline mode

Bugbot triage: (1) --sfw now errors when combined with --staged/--diff (was silently ignored). (2) Baseline diff scans now forward supplyChainManifestChanged to the base pass and include package.json in the diff include set, so the base manifest is scored and computeDiagnosticDelta filters pre-existing low-score deps instead of reporting them as newly introduced. Verified e2e: pre-existing low dep filtered, newly-added one reported.

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

* feat(core): list all axis scores in the supply-chain diagnostic message

Replace the single 'Lowest area' summary with the full per-axis breakdown (supply chain / vulnerability / maintenance / quality / license, 0-100) so the message shows exactly which dimensions dragged the score down. Drops the now-redundant findLowestAxis.

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:45 -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
Nisarg Patel 93d4eecdb8 feat: run React Doctor on TypeScript repos without React (#756)
* feat(core): gate React-specific rules behind a `react` capability

Add a `react` capability (set when React or Preact is detected) and use
it to gate every React-runtime rule family so they stay off on a project
without React. The codegen injects the requirement for the React-runtime
buckets (hooks, JSX, a11y, render performance, React state), and
`shouldEnableRule` treats the `react-jsx-only` tag as implying it. Two
bare-name migration rules that matched class-member names without a React
guard (`no-legacy-class-lifecycles`, `no-legacy-context-api`) now require
it explicitly. Without this, hook/component-name heuristics would
false-fire on ordinary TypeScript once non-React scanning is enabled.

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

* feat: scan TypeScript projects that don't depend on React

A project is now analyzable when it has source files, not only when React
or Preact is present, so a plain TypeScript/JavaScript codebase runs the
framework-agnostic rules instead of hard-failing with 'No React project
found'. `discoverProject` tolerates a directory with no package.json (a
monorepo's `packages/` subfolder, a loose tree of files) by synthesizing a
ProjectInfo, inheriting dependency/framework detection from the enclosing
workspace root so a React monorepo subdirectory still gets its React
capabilities. Only a directory with neither source files nor an enclosing
project still reports nothing-to-scan.

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

* refactor(core): clarify discoverProject's no-package.json branches

Split the synthesized ProjectInfo into its two real cases — a workspace
subfolder (spread the enclosing root's detection, scope the directory-
specific fields) and a standalone source tree (explicit all-null,
framework-agnostic) — replacing the noisy `inherited?.x ?? null` chain
repeated across every field. Behavior is unchanged.

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:33 -07:00
devin-ai-integration[bot] 48e61bcf42 fix: gate ES2023-method rules by tsconfig ES target (#753) 2026-06-08 19:04:16 -07:00
Ray Arayilakath 5b06a865fa fix: name every unused dependency in the verbose warning tail (#752)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 20:37:17 -04:00
Ray Arayilakath 571ca9c802 feat(skills): add product-thinking runbook for public-surface changes (#748)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 16:30:21 -04:00
Aiden Bai 773e23535b Cache scan results for clean HEAD rerenders (#738) 2026-06-08 04:03:15 -07:00
Aiden Bai 1044e29d9b Improve diagnostic what and why copy (#737) 2026-06-08 03:50:07 -07:00
Aiden Bai a59499b594 Add CLI diagnostic category filtering (#736) 2026-06-08 03:45:40 -07:00
Aiden Bai 98066c2e67 Fix Next middleware and proxy scan coverage (#734) 2026-06-08 03:45:11 -07:00
Aiden Bai 5e9cc3bf1b Fix baseline scans for catalog workspaces (#746) 2026-06-08 01:00:07 -07:00
Aiden Bai 547e1e4ecd fix: reduce placeholder secret false positives (#732) v2.1.0 2026-06-07 23:19:31 -07:00
Aiden Bai 772385fea4 Fix generated image a11y false positives (#733) 2026-06-07 22:56:36 -07:00
Nisarg Patel 829655c404 chore(ci): compress comments in generated workflow template (#739)
* chore(ci): compress comments in generated workflow template

Collapses the multi-line YAML comments in the generated
`.github/workflows/react-doctor.yml` to a single sentence per block
(triggers, permissions, concurrency), so a new user sees what each block
does without scrolling past five-line explanations.

No behavior change: same triggers, same permissions (`contents: read`,
`pull-requests: write`, `issues: write`, `statuses: write`), same
`millionco/react-doctor@v2` ref, same concurrency group, same
configuration-knobs reference under the `with:` block.

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

* chore(ci): drop redundant permissions comment in template

Per PR review (#739) — the four `permissions:` keys (`contents: read`,
`pull-requests: write`, `issues: write`, `statuses: write`) are
self-explanatory, so the leading sentence was just noise. Removes the
comment from the generated workflow and tightens the matching
buildWorkflowContent docstring.

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

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-07 22:30:34 -07:00
Aiden Bai af98f83614 Remove jsx-no-target-blank rule (#735)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
2026-06-07 21:20:48 -07:00
Aiden Bai 25cc69bd8f refactor(skill): fold doctor-explain into react-doctor references/explain.md (#729) 2026-06-07 20:39:56 -07:00
Aiden Bai 155cde2849 fix 2026-06-07 19:29:32 -07:00
Aiden Bai 6bfc03a60c fix 2026-06-07 19:29:20 -07:00
Aiden Bai 0db5979060 fix 2026-06-07 19:28:14 -07:00