// Expert system for identifying deprecated patterns, suggesting refactoring to modern standards (Python 3.12+, ES2024+), checking test coverage, and leveraging AI-powered tools. Proactively applied when users request refactoring, updates, or analysis of legacy codebases.
| name | Legacy Code Reviewer |
| description | Expert system for identifying deprecated patterns, suggesting refactoring to modern standards (Python 3.12+, ES2024+), checking test coverage, and leveraging AI-powered tools. Proactively applied when users request refactoring, updates, or analysis of legacy codebases. |
| allowed-tools | Read, Grep, Glob, Web Search |
| last-updated | "2025-12-15T00:00:00.000Z" |
Legacy code review is not just about finding bugs—it's about understanding the original intent, reducing technical debt, and incrementally modernizing while maintaining stability. Apply the principle: "Make it work, make it right, make it fast" in that order.
Use Read, Grep, and Glob tools to:
collections.MutableMapping → collections.abc.MutableMapping)Python Legacy Code (2024-2025 Best Practices):
| Tool | Purpose | Usage |
|---|---|---|
| Ruff | Ultra-fast linter + formatter (replaces Flake8, Black, isort) | ruff check --fix . |
| Vulture | Dead code detection | vulture src/ |
| Refurb | Suggests modern Python idioms | refurb check src/ |
| mypy | Static type checking | mypy --strict src/ |
| Bandit | Security vulnerability scanner | bandit -r src/ |
| Radon | Complexity metrics | radon cc -s src/ |
| pytest + coverage | Test coverage analysis | pytest --cov=src tests/ |
JavaScript/TypeScript Legacy Code:
| Tool | Purpose | Usage |
|---|---|---|
ESLint (with eslint-plugin-deprecation) | Detect deprecated APIs | eslint --fix . |
| Prettier | Code formatting | prettier --write . |
| TypeScript Compiler | Type checking for TS/JS | tsc --noEmit |
| ts-prune | Dead code detection | ts-prune |
| SonarQube | Multi-language code quality | CI/CD integration |
AI-Powered Code Review (GitHub Integration):
| Tool | Key Feature |
|---|---|
| GitHub Copilot | Suggests refactorings, generates tests, explains legacy functions |
| CodeRabbit | Full codebase context-aware reviews in PRs |
| Qodo.ai (Codium) | AI test generation and quality checks |
| DeepSource | Security + performance analysis |
| Greptile | Semantic code search across large repos |
[!IMPORTANT] Always write tests BEFORE refactoring. If no tests exist, create characterization tests first.
Understand the Intent
git log --follow <file> and git blame <file>Establish Safety Nets
pytest tests/ (Python) or npm test (JS)pytest --cov → target 80%+ for critical pathsIncremental Refactoring (Layer by Layer)
Verification Gates
pytest, npm test)ruff check, eslint)pytest --cov)bandit, npm audit)Documentation
| Deprecated | Modern Replacement | Reason |
|---|---|---|
from collections import MutableMapping | from collections.abc import MutableMapping | Moved in Python 3.3+ |
os.path.join(a, b) | pathlib.Path(a) / b | Type-safe, cleaner API |
% formatting | f"{variable}" or str.format() | More readable, faster |
try/except without context | with contextlib.suppress(Exception): | Cleaner error handling |
dict.has_key(k) | k in dict | Pythonic, removed in Py3 |
| No type hints | def func(x: int) -> str: | Catches bugs at dev time |
[!TIP] Keep PRs small (<400 lines) for faster, more accurate reviews.
Summary of Findings
Recommended Tooling
ruff check --fix src/)Refactoring Plan (Phased)
Example Code Block
User Request:
"Can you review
@src/legacy/old_database_connector.pyand suggest how to update it for better performance and maintainability?"
Agent Response:
collections.MutableMapping (should be collections.abc.MutableMapping)# Run modern linters
ruff check --fix src/legacy/old_database_connector.py
mypy src/legacy/old_database_connector.py
bandit -r src/legacy/
# Check complexity
radon cc -s src/legacy/old_database_connector.py
Phase 1 (Low Risk):
collections.MutableMapping → collections.abc.MutableMappingPhase 2 (Medium Risk):
_get_db_connection() helperPhase 3 (High Risk):
Before (Legacy):
from collections import MutableMapping # DEPRECATED
def connect_db(host, port):
conn = psycopg2.connect(host=host, port=port) # Duplicated 3 times
return conn
After (Modern):
from collections.abc import MutableMapping
from typing import Optional
import psycopg2
from psycopg2 import pool
# Connection pool (shared resource)
_connection_pool: Optional[pool.SimpleConnectionPool] = None
def get_db_connection(host: str, port: int) -> psycopg2.extensions.connection:
"""
Get a database connection from the pool.
Args:
host: Database host (e.g., 'localhost')
port: Database port (e.g., 5432)
Returns:
Active database connection
Raises:
psycopg2.OperationalError: If connection fails
"""
global _connection_pool
if _connection_pool is None:
_connection_pool = pool.SimpleConnectionPool(
minconn=1, maxconn=10, host=host, port=port
)
return _connection_pool.getconn()
Key Improvements:
str, int, psycopg2.extensions.connection)Before marking refactoring complete:
ruff check, eslint)mypy, tsc)bandit, npm audit)