docs: sync to Claude Code v2.1.150 (#127)
* docs: sync to Claude Code v2.1.150 * fix(README): bump stale version prose to v2.1.150
This commit is contained in:
79
03-skills/code-review-specialist/SKILL.md
Normal file
79
03-skills/code-review-specialist/SKILL.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
name: code-review-specialist
|
||||
description: Comprehensive code review with security, performance, and quality analysis. Use when users ask to review code, analyze code quality, evaluate pull requests, or mention code review, security analysis, or performance optimization.
|
||||
---
|
||||
|
||||
# Code Review Skill
|
||||
|
||||
This skill provides comprehensive code review capabilities focusing on:
|
||||
|
||||
1. **Security Analysis**
|
||||
- Authentication/authorization issues
|
||||
- Data exposure risks
|
||||
- Injection vulnerabilities
|
||||
- Cryptographic weaknesses
|
||||
- Sensitive data logging
|
||||
|
||||
2. **Performance Review**
|
||||
- Algorithm efficiency (Big O analysis)
|
||||
- Memory optimization
|
||||
- Database query optimization
|
||||
- Caching opportunities
|
||||
- Concurrency issues
|
||||
|
||||
3. **Code Quality**
|
||||
- SOLID principles
|
||||
- Design patterns
|
||||
- Naming conventions
|
||||
- Documentation
|
||||
- Test coverage
|
||||
|
||||
4. **Maintainability**
|
||||
- Code readability
|
||||
- Function size (should be < 50 lines)
|
||||
- Cyclomatic complexity
|
||||
- Dependency management
|
||||
- Type safety
|
||||
|
||||
## Reference Files
|
||||
|
||||
This skill includes supporting files that you should read when performing reviews:
|
||||
|
||||
- **`templates/review-checklist.md`** — Structured checklist covering security, performance, quality, and testing. Read this file and use it as a guide to ensure no category is missed during review.
|
||||
- **`templates/finding-template.md`** — Standard template for documenting individual findings with severity, location, code examples, and impact analysis. Read this file and use its format when reporting issues.
|
||||
- **`scripts/analyze-metrics.py`** — Python script that calculates code metrics (function count, class count, average line length, complexity score). Run this on the file under review to gather quantitative data.
|
||||
- **`scripts/compare-complexity.py`** — Python script that compares cyclomatic and cognitive complexity between two versions of a file. Run this with the before and after versions when reviewing refactoring changes.
|
||||
|
||||
## Review Template
|
||||
|
||||
For each piece of code reviewed, provide:
|
||||
|
||||
### Summary
|
||||
- Overall quality assessment (1-5)
|
||||
- Key findings count
|
||||
- Recommended priority areas
|
||||
|
||||
### Critical Issues (if any)
|
||||
- **Issue**: Clear description
|
||||
- **Location**: File and line number
|
||||
- **Impact**: Why this matters
|
||||
- **Severity**: Critical/High/Medium
|
||||
- **Fix**: Code example
|
||||
|
||||
### Findings by Category
|
||||
|
||||
#### Security (if issues found)
|
||||
List security vulnerabilities with examples
|
||||
|
||||
#### Performance (if issues found)
|
||||
List performance problems with complexity analysis
|
||||
|
||||
#### Quality (if issues found)
|
||||
List code quality issues with refactoring suggestions
|
||||
|
||||
#### Maintainability (if issues found)
|
||||
List maintainability problems with improvements
|
||||
|
||||
## Version History
|
||||
|
||||
- v1.0.0 (2024-12-10): Initial release with security, performance, quality, and maintainability analysis
|
||||
35
03-skills/code-review-specialist/scripts/analyze-metrics.py
Normal file
35
03-skills/code-review-specialist/scripts/analyze-metrics.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def analyze_code_metrics(code):
|
||||
"""Analyze code for common metrics."""
|
||||
|
||||
# Count functions
|
||||
functions = len(re.findall(r"^def\s+\w+", code, re.MULTILINE))
|
||||
|
||||
# Count classes
|
||||
classes = len(re.findall(r"^class\s+\w+", code, re.MULTILINE))
|
||||
|
||||
# Average line length
|
||||
lines = code.split("\n")
|
||||
avg_length = sum(len(l) for l in lines) / len(lines) if lines else 0
|
||||
|
||||
# Estimate complexity
|
||||
complexity = len(re.findall(r"\b(if|elif|else|for|while|and|or)\b", code))
|
||||
|
||||
return {
|
||||
"functions": functions,
|
||||
"classes": classes,
|
||||
"avg_line_length": avg_length,
|
||||
"complexity_score": complexity,
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open(sys.argv[1]) as f:
|
||||
code = f.read()
|
||||
metrics = analyze_code_metrics(code)
|
||||
for key, value in metrics.items():
|
||||
print(f"{key}: {value:.2f}")
|
||||
174
03-skills/code-review-specialist/scripts/compare-complexity.py
Normal file
174
03-skills/code-review-specialist/scripts/compare-complexity.py
Normal file
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Compare cyclomatic complexity of code before and after changes.
|
||||
Helps identify if refactoring actually simplifies code structure.
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
class ComplexityAnalyzer:
|
||||
"""Analyze code complexity metrics."""
|
||||
|
||||
def __init__(self, code: str):
|
||||
self.code = code
|
||||
self.lines = code.split("\n")
|
||||
|
||||
def calculate_cyclomatic_complexity(self) -> int:
|
||||
"""
|
||||
Calculate cyclomatic complexity using McCabe's method.
|
||||
Count decision points: if, elif, else, for, while, except, and, or
|
||||
"""
|
||||
complexity = 1 # Base complexity
|
||||
|
||||
# Count decision points
|
||||
decision_patterns = [
|
||||
r"\bif\b",
|
||||
r"\belif\b",
|
||||
r"\bfor\b",
|
||||
r"\bwhile\b",
|
||||
r"\bexcept\b",
|
||||
r"\band\b(?!$)",
|
||||
r"\bor\b(?!$)",
|
||||
]
|
||||
|
||||
for pattern in decision_patterns:
|
||||
matches = re.findall(pattern, self.code)
|
||||
complexity += len(matches)
|
||||
|
||||
return complexity
|
||||
|
||||
def calculate_cognitive_complexity(self) -> int:
|
||||
"""
|
||||
Calculate cognitive complexity - how hard is it to understand?
|
||||
Based on nesting depth and control flow.
|
||||
"""
|
||||
cognitive = 0
|
||||
nesting_depth = 0
|
||||
|
||||
for line in self.lines:
|
||||
# Track nesting depth
|
||||
if re.search(r"^\s*(if|for|while|def|class|try)\b", line):
|
||||
nesting_depth += 1
|
||||
cognitive += nesting_depth
|
||||
elif re.search(r"^\s*(elif|else|except|finally)\b", line):
|
||||
cognitive += nesting_depth
|
||||
|
||||
# Reduce nesting when unindenting
|
||||
if line and not line[0].isspace():
|
||||
nesting_depth = 0
|
||||
|
||||
return cognitive
|
||||
|
||||
def calculate_maintainability_index(self) -> float:
|
||||
"""
|
||||
Maintainability Index ranges from 0-100.
|
||||
> 85: Excellent
|
||||
> 65: Good
|
||||
> 50: Fair
|
||||
< 50: Poor
|
||||
"""
|
||||
lines = len(self.lines)
|
||||
cyclomatic = self.calculate_cyclomatic_complexity()
|
||||
cognitive = self.calculate_cognitive_complexity()
|
||||
|
||||
# Simplified MI calculation
|
||||
mi = (
|
||||
171
|
||||
- 5.2 * (cyclomatic / lines)
|
||||
- 0.23 * (cognitive)
|
||||
- 16.2 * (lines / 1000)
|
||||
)
|
||||
|
||||
return max(0, min(100, mi))
|
||||
|
||||
def get_complexity_report(self) -> dict:
|
||||
"""Generate comprehensive complexity report."""
|
||||
return {
|
||||
"cyclomatic_complexity": self.calculate_cyclomatic_complexity(),
|
||||
"cognitive_complexity": self.calculate_cognitive_complexity(),
|
||||
"maintainability_index": round(self.calculate_maintainability_index(), 2),
|
||||
"lines_of_code": len(self.lines),
|
||||
"avg_line_length": round(
|
||||
sum(len(l) for l in self.lines) / len(self.lines), 2
|
||||
)
|
||||
if self.lines
|
||||
else 0,
|
||||
}
|
||||
|
||||
|
||||
def compare_files(before_file: str, after_file: str) -> None:
|
||||
"""Compare complexity metrics between two code versions."""
|
||||
|
||||
with open(before_file) as f:
|
||||
before_code = f.read()
|
||||
|
||||
with open(after_file) as f:
|
||||
after_code = f.read()
|
||||
|
||||
before_analyzer = ComplexityAnalyzer(before_code)
|
||||
after_analyzer = ComplexityAnalyzer(after_code)
|
||||
|
||||
before_metrics = before_analyzer.get_complexity_report()
|
||||
after_metrics = after_analyzer.get_complexity_report()
|
||||
|
||||
print("=" * 60)
|
||||
print("CODE COMPLEXITY COMPARISON")
|
||||
print("=" * 60)
|
||||
|
||||
print("\nBEFORE:")
|
||||
print(f" Cyclomatic Complexity: {before_metrics['cyclomatic_complexity']}")
|
||||
print(f" Cognitive Complexity: {before_metrics['cognitive_complexity']}")
|
||||
print(f" Maintainability Index: {before_metrics['maintainability_index']}")
|
||||
print(f" Lines of Code: {before_metrics['lines_of_code']}")
|
||||
print(f" Avg Line Length: {before_metrics['avg_line_length']}")
|
||||
|
||||
print("\nAFTER:")
|
||||
print(f" Cyclomatic Complexity: {after_metrics['cyclomatic_complexity']}")
|
||||
print(f" Cognitive Complexity: {after_metrics['cognitive_complexity']}")
|
||||
print(f" Maintainability Index: {after_metrics['maintainability_index']}")
|
||||
print(f" Lines of Code: {after_metrics['lines_of_code']}")
|
||||
print(f" Avg Line Length: {after_metrics['avg_line_length']}")
|
||||
|
||||
print("\nCHANGES:")
|
||||
cyclomatic_change = (
|
||||
after_metrics["cyclomatic_complexity"] - before_metrics["cyclomatic_complexity"]
|
||||
)
|
||||
cognitive_change = (
|
||||
after_metrics["cognitive_complexity"] - before_metrics["cognitive_complexity"]
|
||||
)
|
||||
mi_change = (
|
||||
after_metrics["maintainability_index"] - before_metrics["maintainability_index"]
|
||||
)
|
||||
loc_change = after_metrics["lines_of_code"] - before_metrics["lines_of_code"]
|
||||
|
||||
print(f" Cyclomatic Complexity: {cyclomatic_change:+d}")
|
||||
print(f" Cognitive Complexity: {cognitive_change:+d}")
|
||||
print(f" Maintainability Index: {mi_change:+.2f}")
|
||||
print(f" Lines of Code: {loc_change:+d}")
|
||||
|
||||
print("\nASSESSMENT:")
|
||||
if mi_change > 0:
|
||||
print(" ✅ Code is MORE maintainable")
|
||||
elif mi_change < 0:
|
||||
print(" ⚠️ Code is LESS maintainable")
|
||||
else:
|
||||
print(" ➡️ Maintainability unchanged")
|
||||
|
||||
if cyclomatic_change < 0:
|
||||
print(" ✅ Complexity DECREASED")
|
||||
elif cyclomatic_change > 0:
|
||||
print(" ⚠️ Complexity INCREASED")
|
||||
else:
|
||||
print(" ➡️ Complexity unchanged")
|
||||
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 3:
|
||||
print("Usage: python compare-complexity.py <before_file> <after_file>")
|
||||
sys.exit(1)
|
||||
|
||||
compare_files(sys.argv[1], sys.argv[2])
|
||||
112
03-skills/code-review-specialist/templates/finding-template.md
Normal file
112
03-skills/code-review-specialist/templates/finding-template.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Code Review Finding Template
|
||||
|
||||
Use this template when documenting each issue found during code review.
|
||||
|
||||
---
|
||||
|
||||
## Issue: [TITLE]
|
||||
|
||||
### Severity
|
||||
- [ ] Critical (blocks deployment)
|
||||
- [ ] High (should fix before merge)
|
||||
- [ ] Medium (should fix soon)
|
||||
- [ ] Low (nice to have)
|
||||
|
||||
### Category
|
||||
- [ ] Security
|
||||
- [ ] Performance
|
||||
- [ ] Code Quality
|
||||
- [ ] Maintainability
|
||||
- [ ] Testing
|
||||
- [ ] Design Pattern
|
||||
- [ ] Documentation
|
||||
|
||||
### Location
|
||||
**File:** `src/components/UserCard.tsx`
|
||||
|
||||
**Lines:** 45-52
|
||||
|
||||
**Function/Method:** `renderUserDetails()`
|
||||
|
||||
### Issue Description
|
||||
|
||||
**What:** Describe what the issue is.
|
||||
|
||||
**Why it matters:** Explain the impact and why this needs to be fixed.
|
||||
|
||||
**Current behavior:** Show the problematic code or behavior.
|
||||
|
||||
**Expected behavior:** Describe what should happen instead.
|
||||
|
||||
### Code Example
|
||||
|
||||
#### Current (Problematic)
|
||||
|
||||
```typescript
|
||||
// Shows the N+1 query problem
|
||||
const users = fetchUsers();
|
||||
users.forEach(user => {
|
||||
const posts = fetchUserPosts(user.id); // Query per user!
|
||||
renderUserPosts(posts);
|
||||
});
|
||||
```
|
||||
|
||||
#### Suggested Fix
|
||||
|
||||
```typescript
|
||||
// Optimized with JOIN query
|
||||
const usersWithPosts = fetchUsersWithPosts();
|
||||
usersWithPosts.forEach(({ user, posts }) => {
|
||||
renderUserPosts(posts);
|
||||
});
|
||||
```
|
||||
|
||||
### Impact Analysis
|
||||
|
||||
| Aspect | Impact | Severity |
|
||||
|--------|--------|----------|
|
||||
| Performance | 100+ queries for 20 users | High |
|
||||
| User Experience | Slow page load | High |
|
||||
| Scalability | Breaks at scale | Critical |
|
||||
| Maintainability | Hard to debug | Medium |
|
||||
|
||||
### Related Issues
|
||||
|
||||
- Similar issue in `AdminUserList.tsx` line 120
|
||||
- Related PR: #456
|
||||
- Related issue: #789
|
||||
|
||||
### Additional Resources
|
||||
|
||||
- [N+1 Query Problem](https://en.wikipedia.org/wiki/N%2B1_problem)
|
||||
- [Database Join Documentation](https://docs.example.com/joins)
|
||||
|
||||
### Reviewer Notes
|
||||
|
||||
- This is a common pattern in this codebase
|
||||
- Consider adding this to the code style guide
|
||||
- Might be worth creating a helper function
|
||||
|
||||
### Author Response (for feedback)
|
||||
|
||||
*To be filled by the code author:*
|
||||
|
||||
- [ ] Fix implemented in commit: `abc123`
|
||||
- [ ] Fix status: Complete / In Progress / Needs Discussion
|
||||
- [ ] Questions or concerns: (describe)
|
||||
|
||||
---
|
||||
|
||||
## Finding Statistics (for Reviewer)
|
||||
|
||||
When reviewing multiple findings, track:
|
||||
|
||||
- **Total Issues Found:** X
|
||||
- **Critical:** X
|
||||
- **High:** X
|
||||
- **Medium:** X
|
||||
- **Low:** X
|
||||
|
||||
**Recommendation:** ✅ Approve / ⚠️ Request Changes / 🔄 Needs Discussion
|
||||
|
||||
**Overall Code Quality:** 1-5 stars
|
||||
@@ -0,0 +1,47 @@
|
||||
# Code Review Checklist
|
||||
|
||||
## Security Checklist
|
||||
- [ ] No hardcoded credentials or secrets
|
||||
- [ ] Input validation on all user inputs
|
||||
- [ ] SQL injection prevention (parameterized queries)
|
||||
- [ ] CSRF protection on state-changing operations
|
||||
- [ ] XSS prevention with proper escaping
|
||||
- [ ] Authentication checks on protected endpoints
|
||||
- [ ] Authorization checks on resources
|
||||
- [ ] Secure password hashing (bcrypt, argon2)
|
||||
- [ ] No sensitive data in logs
|
||||
- [ ] HTTPS enforced
|
||||
|
||||
## Performance Checklist
|
||||
- [ ] No N+1 queries
|
||||
- [ ] Appropriate use of indexes
|
||||
- [ ] Caching implemented where beneficial
|
||||
- [ ] No blocking operations on main thread
|
||||
- [ ] Async/await used correctly
|
||||
- [ ] Large datasets paginated
|
||||
- [ ] Database connections pooled
|
||||
- [ ] Regular expressions optimized
|
||||
- [ ] No unnecessary object creation
|
||||
- [ ] Memory leaks prevented
|
||||
|
||||
## Quality Checklist
|
||||
- [ ] Functions < 50 lines
|
||||
- [ ] Clear variable naming
|
||||
- [ ] No duplicate code
|
||||
- [ ] Proper error handling
|
||||
- [ ] Comments explain WHY, not WHAT
|
||||
- [ ] No console.logs in production
|
||||
- [ ] Type checking (TypeScript/JSDoc)
|
||||
- [ ] SOLID principles followed
|
||||
- [ ] Design patterns applied correctly
|
||||
- [ ] Self-documenting code
|
||||
|
||||
## Testing Checklist
|
||||
- [ ] Unit tests written
|
||||
- [ ] Edge cases covered
|
||||
- [ ] Error scenarios tested
|
||||
- [ ] Integration tests present
|
||||
- [ ] Coverage > 80%
|
||||
- [ ] No flaky tests
|
||||
- [ ] Mock external dependencies
|
||||
- [ ] Clear test names
|
||||
Reference in New Issue
Block a user