chore: publish from staged

This commit is contained in:
github-actions[bot]
2026-04-10 04:45:41 +00:00
parent 10fda505b7
commit 8395dce14c
467 changed files with 97526 additions and 276 deletions

View File

@@ -0,0 +1,36 @@
---
name: react-audit-grep-patterns
description: 'Provides the complete, verified grep scan command library for auditing React codebases before a React 18.3.1 or React 19 upgrade. Use this skill whenever running a migration audit - for both the react18-auditor and react19-auditor agents. Contains every grep pattern needed to find deprecated APIs, removed APIs, unsafe lifecycle methods, batching vulnerabilities, test file issues, dependency conflicts, and React 19 specific removals. Always use this skill when writing audit scan commands - do not rely on memory for grep syntax, especially for the multi-line async setState patterns which require context flags.'
---
# React Audit Grep Patterns
Complete scan command library for React 18.3.1 and React 19 migration audits.
## Usage
Read the relevant section for your target:
- **`references/react18-scans.md`** - all scans for React 16/17 → 18.3.1 audit
- **`references/react19-scans.md`** - all scans for React 18 → 19 audit
- **`references/test-scans.md`** - test file specific scans (used by both auditors)
- **`references/dep-scans.md`** - dependency and peer conflict scans
## Base Patterns Used Across All Scans
```bash
# Standard flags used throughout:
# -r = recursive
# -n = show line numbers
# -l = show filenames only (for counting affected files)
# --include="*.js" --include="*.jsx" = JS/JSX files only
# | grep -v "\.test\.\|\.spec\.\|__tests__" = exclude test files
# | grep -v "node_modules" = safety (usually handled by not scanning node_modules)
# 2>/dev/null = suppress "no files found" errors
# Source files only (exclude tests):
SRC_FLAGS='--include="*.js" --include="*.jsx"'
EXCLUDE_TESTS='grep -v "\.test\.\|\.spec\.\|__tests__"'
# Test files only:
TEST_FLAGS='--include="*.test.js" --include="*.test.jsx" --include="*.spec.js" --include="*.spec.jsx"'
```

View File

@@ -0,0 +1,94 @@
# Dependency Scans - Both Auditors
Scans for dependency compatibility and peer conflicts. Run during both R18 and R19 audits.
---
## Current Versions
```bash
# All react-related package versions in one shot
cat package.json | python3 -c "
import sys, json
d = json.load(sys.stdin)
deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})}
keys = ['react', 'react-dom', 'react-router', 'react-router-dom',
'@testing-library/react', '@testing-library/jest-dom',
'@testing-library/user-event', '@apollo/client', 'graphql',
'@emotion/react', '@emotion/styled', 'jest', 'enzyme',
'react-redux', '@reduxjs/toolkit', 'prop-types']
for k in keys:
if k in deps:
print(f'{k}: {deps[k]}')
" 2>/dev/null
```
---
## Peer Dependency Conflicts
```bash
# All peer dep warnings (must be 0 before migration completes)
npm ls 2>&1 | grep -E "WARN|ERR|peer|invalid|unmet"
# Count of peer errors
npm ls 2>&1 | grep -E "WARN|ERR|peer|invalid|unmet" | wc -l
# Specific package peer dep requirements
npm info @testing-library/react peerDependencies 2>/dev/null
npm info @apollo/client peerDependencies 2>/dev/null
npm info @emotion/react peerDependencies 2>/dev/null
npm info react-router-dom peerDependencies 2>/dev/null
```
---
## Enzyme Detection (R18 Blocker)
```bash
# In package.json
cat package.json | python3 -c "
import sys, json
d = json.load(sys.stdin)
deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})}
enzyme = {k: v for k, v in deps.items() if 'enzyme' in k.lower()}
if enzyme:
print('BLOCKER - Enzyme found:', enzyme)
else:
print('No Enzyme - OK')
" 2>/dev/null
# Enzyme adapter files
find . -name "enzyme-adapter*" -not -path "*/node_modules/*" 2>/dev/null
```
---
## React Router Version Check
```bash
ROUTER=$(node -e "console.log(require('./node_modules/react-router-dom/package.json').version)" 2>/dev/null)
echo "react-router-dom version: $ROUTER"
# If v5 - flag for assessment
if [[ $ROUTER == 5* ]]; then
echo "WARNING: react-router v5 found - requires scope assessment before upgrade"
echo "Run router migration scope scan:"
echo " Routes: $(grep -rn "<Route\|<Switch\|<Redirect" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l) hits"
echo " useHistory: $(grep -rn "useHistory()" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l) hits"
fi
```
---
## Lock File Consistency
```bash
# Check lockfile is in sync with package.json
npm ls --depth=0 2>&1 | head -20
# Check for duplicate react installs (can cause hooks errors)
find node_modules -name "package.json" -path "*/react/package.json" 2>/dev/null \
| grep -v "node_modules/node_modules" \
| xargs grep '"version"' | sort -u
```

View File

@@ -0,0 +1,231 @@
# React 18.3.1 Audit - Complete Scan Commands
Run in this order. Each section maps to a phase in the react18-auditor.
---
## Phase 0 - Codebase Profile
```bash
# Total source files (excluding tests)
find src/ \( -name "*.js" -o -name "*.jsx" \) \
| grep -v "\.test\.\|\.spec\.\|__tests__\|node_modules" \
| wc -l
# Class component count
grep -rl "extends React\.Component\|extends Component\|extends PureComponent" \
src/ --include="*.js" --include="*.jsx" \
| grep -v "\.test\." | wc -l
# Function component rough count
grep -rl "const [A-Z][a-zA-Z]* = \|function [A-Z][a-zA-Z]*(" \
src/ --include="*.js" --include="*.jsx" \
| grep -v "\.test\." | wc -l
# Current React version
node -e "console.log(require('./node_modules/react/package.json').version)" 2>/dev/null
# StrictMode in use? (affects how many lifecycle warnings were already seen)
grep -rn "StrictMode\|React\.StrictMode" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
```
---
## Phase 1 - Unsafe Lifecycle Methods
```bash
# componentWillMount (without UNSAFE_ prefix)
grep -rn "componentWillMount\b" \
src/ --include="*.js" --include="*.jsx" \
| grep -v "UNSAFE_componentWillMount\|\.test\."
# componentWillReceiveProps (without UNSAFE_ prefix)
grep -rn "componentWillReceiveProps\b" \
src/ --include="*.js" --include="*.jsx" \
| grep -v "UNSAFE_componentWillReceiveProps\|\.test\."
# componentWillUpdate (without UNSAFE_ prefix)
grep -rn "componentWillUpdate\b" \
src/ --include="*.js" --include="*.jsx" \
| grep -v "UNSAFE_componentWillUpdate\|\.test\."
# Already partially migrated with UNSAFE_ prefix? (check if team already did partial work)
grep -rn "UNSAFE_component" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Quick count summary:
echo "=== Lifecycle Issue Summary ==="
echo "componentWillMount: $(grep -rn "componentWillMount\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l)"
echo "componentWillReceiveProps: $(grep -rn "componentWillReceiveProps\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l)"
echo "componentWillUpdate: $(grep -rn "componentWillUpdate\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l)"
```
---
## Phase 2 - Automatic Batching Vulnerabilities
```bash
# Async class methods (primary risk zone)
grep -rn "^\s*async [a-zA-Z]" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Arrow function async methods
grep -rn "=\s*async\s*(" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# setState inside .then() callbacks
grep -rn "\.then\s*(" \
src/ --include="*.js" --include="*.jsx" -A 3 \
| grep "setState" | grep -v "\.test\."
# setState inside .catch() callbacks
grep -rn "\.catch\s*(" \
src/ --include="*.js" --include="*.jsx" -A 3 \
| grep "setState" | grep -v "\.test\."
# setState inside setTimeout
grep -rn "setTimeout" \
src/ --include="*.js" --include="*.jsx" -A 5 \
| grep "setState" | grep -v "\.test\."
# this.state reads that follow an await (most dangerous pattern)
grep -rn "this\.state\." \
src/ --include="*.js" --include="*.jsx" -B 3 \
| grep "await" | grep -v "\.test\."
# document/window event handlers with setState
grep -rn "addEventListener" \
src/ --include="*.js" --include="*.jsx" -A 5 \
| grep "setState" | grep -v "\.test\."
```
---
## Phase 3 - Legacy Context API
```bash
# Provider side
grep -rn "childContextTypes\s*=" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
grep -rn "getChildContext\s*(" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Consumer side
grep -rn "contextTypes\s*=" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# this.context usage (may indicate legacy or modern - verify per hit)
grep -rn "this\.context\." \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Count of distinct legacy contexts (by counting childContextTypes blocks)
grep -rn "childContextTypes" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l
```
---
## Phase 4 - String Refs
```bash
# String ref assignments in JSX
grep -rn 'ref="[^"]*"' \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Alternative quote style
grep -rn "ref='[^']*'" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# this.refs accessor usage
grep -rn "this\.refs\." \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
```
---
## Phase 5 - findDOMNode
```bash
grep -rn "findDOMNode\|ReactDOM\.findDOMNode" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
```
---
## Phase 6 - Root API (ReactDOM.render)
```bash
grep -rn "ReactDOM\.render\s*(" \
src/ --include="*.js" --include="*.jsx"
grep -rn "ReactDOM\.hydrate\s*(" \
src/ --include="*.js" --include="*.jsx"
grep -rn "unmountComponentAtNode" \
src/ --include="*.js" --include="*.jsx"
```
---
## Phase 7 - Event Delegation (React 16 Carry-Over)
```bash
# document-level event listeners (may miss React events after React 17 delegation change)
grep -rn "document\.addEventListener\|document\.removeEventListener" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# window event listeners
grep -rn "window\.addEventListener" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
```
---
## Phase 8 - Enzyme Detection (Hard Blocker)
```bash
# Enzyme in package.json
cat package.json | python3 -c "
import sys, json
d = json.load(sys.stdin)
deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})}
enzyme_pkgs = [k for k in deps if 'enzyme' in k.lower()]
print('Enzyme packages found:', enzyme_pkgs if enzyme_pkgs else 'NONE')
"
# Enzyme imports in test files
grep -rn "from 'enzyme'\|require.*enzyme" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null | wc -l
```
---
## Full Summary Script
Run this for a quick overview before detailed scanning:
```bash
#!/bin/bash
echo "=============================="
echo "React 18 Migration Audit Summary"
echo "=============================="
echo ""
echo "LIFECYCLE METHODS:"
echo " componentWillMount: $(grep -rn "componentWillMount\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l | tr -d ' ') hits"
echo " componentWillReceiveProps: $(grep -rn "componentWillReceiveProps\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l | tr -d ' ') hits"
echo " componentWillUpdate: $(grep -rn "componentWillUpdate\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l | tr -d ' ') hits"
echo ""
echo "LEGACY APIS:"
echo " Legacy context (providers): $(grep -rn "childContextTypes" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo " String refs (this.refs): $(grep -rn "this\.refs\." src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo " findDOMNode: $(grep -rn "findDOMNode" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo " ReactDOM.render: $(grep -rn "ReactDOM\.render\s*(" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo ""
echo "ENZYME (BLOCKER):"
echo " Enzyme test files: $(grep -rl "from 'enzyme'" src/ --include="*.test.*" 2>/dev/null | wc -l | tr -d ' ') files"
echo ""
echo "ASYNC BATCHING RISK:"
echo " Async class methods: $(grep -rn "^\s*async [a-zA-Z]" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
```

View File

@@ -0,0 +1,141 @@
# React 19 Audit - Complete Scan Commands
Run in this order. Each section maps to a phase in the react19-auditor.
---
## Phase 1 - Removed APIs (Breaking - Must Fix)
```bash
# 1. ReactDOM.render - REMOVED
grep -rn "ReactDOM\.render\s*(" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# 2. ReactDOM.hydrate - REMOVED
grep -rn "ReactDOM\.hydrate\s*(" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# 3. unmountComponentAtNode - REMOVED
grep -rn "unmountComponentAtNode" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# 4. findDOMNode - REMOVED
grep -rn "findDOMNode\|ReactDOM\.findDOMNode" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# 5. createFactory - REMOVED
grep -rn "createFactory\|React\.createFactory" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# 6. react-dom/test-utils imports - most exports REMOVED
grep -rn "from 'react-dom/test-utils'\|from \"react-dom/test-utils\"\|require.*react-dom/test-utils" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# 7. Legacy Context API - REMOVED
grep -rn "contextTypes\|childContextTypes\|getChildContext" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
# 8. String refs - REMOVED
grep -rn "this\.refs\." \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
```
---
## Phase 2 - Deprecated APIs (Should Migrate)
```bash
# 9. forwardRef - deprecated (ref now direct prop)
grep -rn "forwardRef\|React\.forwardRef" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
# 10. defaultProps on function components - REMOVED for function components
grep -rn "\.defaultProps\s*=" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
# 11. useRef() without initial value
grep -rn "useRef()\|useRef( )" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
# 12. propTypes (runtime validation silently dropped)
grep -rn "\.propTypes\s*=" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l
# 13. react-test-renderer - deprecated
grep -rn "react-test-renderer\|TestRenderer" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
# 14. Unnecessary React default imports (new JSX transform)
grep -rn "^import React from 'react'" \
src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." 2>/dev/null
```
---
## Phase 3 - Test File Scans
```bash
# act() from wrong location
grep -rn "from 'react-dom/test-utils'" \
src/ --include="*.test.js" --include="*.test.jsx" \
--include="*.spec.js" --include="*.spec.jsx" 2>/dev/null
# Simulate usage - REMOVED
grep -rn "Simulate\." \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# react-test-renderer in tests
grep -rn "from 'react-test-renderer'" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# Spy call count assertions (may need StrictMode delta updates)
grep -rn "toHaveBeenCalledTimes" \
src/ --include="*.test.*" --include="*.spec.*" | head -20 2>/dev/null
# console.error call count assertions (React 19 error reporting change)
grep -rn "console\.error.*toHaveBeenCalledTimes\|toHaveBeenCalledTimes.*console\.error" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
```
---
## Phase 4 - StrictMode Behavioral Changes
```bash
# StrictMode usage
grep -rn "StrictMode\|React\.StrictMode" \
src/ --include="*.js" --include="*.jsx" 2>/dev/null
# Spy assertions that may be affected by StrictMode double-invoke change
grep -rn "toHaveBeenCalledTimes\|\.mock\.calls\.length" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
```
---
## Full Summary Script
```bash
#!/bin/bash
echo "=============================="
echo "React 19 Migration Audit Summary"
echo "=============================="
echo ""
echo "REMOVED APIs (Critical):"
echo " ReactDOM.render: $(grep -rn "ReactDOM\.render\s*(" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo " ReactDOM.hydrate: $(grep -rn "ReactDOM\.hydrate\s*(" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo " unmountComponentAtNode: $(grep -rn "unmountComponentAtNode" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo " findDOMNode: $(grep -rn "findDOMNode" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo " react-dom/test-utils: $(grep -rn "from 'react-dom/test-utils'" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo " Legacy context: $(grep -rn "contextTypes\|childContextTypes\|getChildContext" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo " String refs: $(grep -rn "this\.refs\." src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo ""
echo "DEPRECATED APIs:"
echo " forwardRef: $(grep -rn "forwardRef" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo " defaultProps (fn comps): $(grep -rn "\.defaultProps\s*=" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo " useRef() no arg: $(grep -rn "useRef()" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo ""
echo "TEST FILE ISSUES:"
echo " react-dom/test-utils: $(grep -rn "from 'react-dom/test-utils'" src/ --include="*.test.*" --include="*.spec.*" | wc -l | tr -d ' ') hits"
echo " Simulate usage: $(grep -rn "Simulate\." src/ --include="*.test.*" | wc -l | tr -d ' ') hits"
```

View File

@@ -0,0 +1,94 @@
# Test File Scans - Both Auditors
Scans specifically for test file issues. Run during both R18 and R19 audits.
---
## Setup Files
```bash
# Find test setup files
find src/ -name "setupTests*" -o -name "jest.setup*" 2>/dev/null
find . -name "jest.config.js" -o -name "jest.config.ts" 2>/dev/null | grep -v "node_modules"
# Check setup file for legacy patterns
grep -n "ReactDOM\|react-dom/test-utils\|Enzyme\|configure\|Adapter" \
src/setupTests.js 2>/dev/null
```
---
## Import Scans
```bash
# All react-dom/test-utils imports in tests
grep -rn "from 'react-dom/test-utils'\|require.*react-dom/test-utils" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# Enzyme imports
grep -rn "from 'enzyme'\|require.*enzyme" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# react-test-renderer
grep -rn "from 'react-test-renderer'" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# Old act location
grep -rn "act.*from 'react-dom'" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
```
---
## Render Pattern Scans
```bash
# ReactDOM.render in tests (should use RTL render)
grep -rn "ReactDOM\.render\s*(" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# Enzyme shallow/mount
grep -rn "shallow(\|mount(" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# Custom render helpers
find src/ -name "test-utils.js" -o -name "renderWithProviders*" \
-o -name "customRender*" -o -name "render-helpers*" 2>/dev/null
```
---
## Assertion Scans
```bash
# Call count assertions (StrictMode sensitive)
grep -rn "toHaveBeenCalledTimes" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# console.error assertions (React error logging changed in R19)
grep -rn "console\.error" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# Intermediate state assertions (batching sensitive)
grep -rn "fireEvent\|userEvent" \
src/ --include="*.test.*" --include="*.spec.*" -A 1 \
| grep "expect\|getBy\|queryBy" | head -20 2>/dev/null
```
---
## Async Scans
```bash
# act() usage
grep -rn "\bact(" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
# waitFor usage (good - check these are properly async)
grep -rn "waitFor\|findBy" \
src/ --include="*.test.*" --include="*.spec.*" | wc -l
# setTimeout in tests (may be batching-sensitive)
grep -rn "setTimeout\|setInterval" \
src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null
```