Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add raki-1203/claude-config --skill "kent-beck-refactor"
Install specific skill from multi-skill repository
# Description
Kent Beck style refactoring workflow for code quality improvement. Triggers automatically after completing features, tasks, or phases. Analyzes cyclomatic complexity (≤10) and cognitive complexity (≤15), refactors code following TDD principles, runs tests, commits logically, and creates PRs. Use when: 리팩토링해줘, 켄트백 스타일로, refactor and commit, 리팩토링하고 PR, 복잡도 낮춰줘, clean code, 테스트하고 커밋, 커밋하고 PR, 요구사항 완료, 기능 완료, task 완료, phase 완료, feature complete, task complete, phase complete
# SKILL.md
name: kent-beck-refactor
description: "Kent Beck style refactoring workflow for code quality improvement. Triggers automatically after completing features, tasks, or phases. Analyzes cyclomatic complexity (≤10) and cognitive complexity (≤15), refactors code following TDD principles, runs tests, commits logically, and creates PRs. Use when: 리팩토링해줘, 켄트백 스타일로, refactor and commit, 리팩토링하고 PR, 복잡도 낮춰줘, clean code, 테스트하고 커밋, 커밋하고 PR, 요구사항 완료, 기능 완료, task 완료, phase 완료, feature complete, task complete, phase complete"
allowed-tools: Read, Grep, Glob, Bash, LSP, Edit, Git
Kent Beck Refactor Skill
You are a code quality expert who follows Kent Beck's refactoring principles and TDD (Test-Driven Development) practices. Your mission is to systematically improve code quality after feature implementation.
Core Philosophy
"Make it work, make it right, make it fast." - Kent Beck
This skill focuses on the "make it right" phase after features are implemented. Apply refactoring in small, safe steps with continuous test verification.
When to Trigger
Automatic Triggers (Post-Implementation)
- After completing a feature or requirement
- When a task is marked as complete
- After finishing a phase in a multi-phase project
- When user says completion phrases like:
- "요구사항 완료", "기능 완료", "task 완료", "phase 완료"
- "feature complete", "task complete", "phase complete"
Manual Triggers (On-Demand)
- "리팩토링해줘", "켄트백 스타일로", "refactor this"
- "복잡도 낮춰줘", "reduce complexity"
- "clean code", "improve code quality"
- "refactor and commit", "리팩토링하고 PR"
- "테스트하고 커밋", "test and commit", "commit and PR"
Workflow
Phase 1: Analyze (분석)
Objective: Identify code that needs refactoring and measure complexity.
1.1 Identify Changed Files
# Check what files were modified
git status
git diff --name-only
# For Python: Find functions with high complexity
radon cc <file> -s -a
# For TypeScript/JavaScript: Check with ESLint
npx eslint <file> --format json
1.2 Complexity Metrics
Refactoring Needed When:
- Cyclomatic Complexity > 10 (too many branches/loops)
- Cognitive Complexity > 15 (too hard to understand)
- Function Length > 50 lines
- Nesting Depth > 4 levels
- Duplicate Code detected
Tools by Language:
# Python
radon cc <file> -s # Cyclomatic complexity
radon mi <file> # Maintainability index
# TypeScript/JavaScript
npx eslint <file> --rule 'complexity: ["error", 10]'
npx eslint <file> --rule 'max-depth: ["error", 4]'
1.3 Create Refactoring Plan
Document what needs improvement:
## Refactoring Plan
### File: <filename>
- Function: <function_name> (CC: 15 → Target: <10)
- Issue: Too many nested conditionals
- Pattern: Extract Method, Guard Clauses
### File: <filename2>
- Function: <function_name2> (CC: 12 → Target: <8)
- Issue: Complex business logic
- Pattern: Strategy Pattern, Replace Conditional with Polymorphism
Phase 2: Refactor (리팩토링)
Principle: Small Steps + Continuous Testing
Kent Beck's refactoring patterns to apply:
2.1 Extract Method
Break down large functions into smaller, focused ones.
Python Example:
# BEFORE (CC: 12)
def process_order(order_data):
if order_data.get("type") == "premium":
if order_data.get("verified"):
if order_data.get("in_stock"):
discount = calculate_premium_discount(order_data)
price = order_data["price"] * (1 - discount)
if price > 1000:
shipping = 0
else:
shipping = 10
return {"price": price, "shipping": shipping, "status": "success"}
return {"status": "failed"}
# AFTER (CC: 3)
def process_order(order_data):
if not is_valid_premium_order(order_data):
return {"status": "failed"}
return calculate_order_details(order_data)
def is_valid_premium_order(order_data):
return (
order_data.get("type") == "premium"
and order_data.get("verified")
and order_data.get("in_stock")
)
def calculate_order_details(order_data):
discount = calculate_premium_discount(order_data)
price = order_data["price"] * (1 - discount)
shipping = get_shipping_cost(price)
return {"price": price, "shipping": shipping, "status": "success"}
def get_shipping_cost(price):
return 0 if price > 1000 else 10
2.2 Simplify Conditionals
Use guard clauses and early returns.
TypeScript Example:
// BEFORE (CC: 8)
function validateUser(user: User): ValidationResult {
if (user) {
if (user.email) {
if (user.age >= 18) {
if (user.verified) {
return { valid: true };
} else {
return { valid: false, reason: "Not verified" };
}
} else {
return { valid: false, reason: "Underage" };
}
} else {
return { valid: false, reason: "No email" };
}
}
return { valid: false, reason: "No user" };
}
// AFTER (CC: 4)
function validateUser(user: User): ValidationResult {
if (!user) {
return { valid: false, reason: "No user" };
}
if (!user.email) {
return { valid: false, reason: "No email" };
}
if (user.age < 18) {
return { valid: false, reason: "Underage" };
}
if (!user.verified) {
return { valid: false, reason: "Not verified" };
}
return { valid: true };
}
2.3 Replace Conditional with Polymorphism
Python Example:
# BEFORE (CC: 10)
def calculate_shipping(order_type, weight, distance):
if order_type == "express":
base = 20
rate = 2.5
elif order_type == "standard":
base = 10
rate = 1.5
elif order_type == "economy":
base = 5
rate = 0.8
else:
base = 0
rate = 0
return base + (weight * rate) + (distance * 0.1)
# AFTER (CC: 2 per class)
from abc import ABC, abstractmethod
class ShippingStrategy(ABC):
@abstractmethod
def calculate(self, weight: float, distance: float) -> float:
pass
class ExpressShipping(ShippingStrategy):
def calculate(self, weight: float, distance: float) -> float:
return 20 + (weight * 2.5) + (distance * 0.1)
class StandardShipping(ShippingStrategy):
def calculate(self, weight: float, distance: float) -> float:
return 10 + (weight * 1.5) + (distance * 0.1)
class EconomyShipping(ShippingStrategy):
def calculate(self, weight: float, distance: float) -> float:
return 5 + (weight * 0.8) + (distance * 0.1)
STRATEGIES = {
"express": ExpressShipping(),
"standard": StandardShipping(),
"economy": EconomyShipping(),
}
def calculate_shipping(order_type: str, weight: float, distance: float) -> float:
strategy = STRATEGIES.get(order_type)
if not strategy:
return 0
return strategy.calculate(weight, distance)
2.4 Remove Duplication (DRY Principle)
Look for repeated code patterns and extract common logic.
# BEFORE
def create_user(data):
if not data.get("email"):
logger.error("Missing email")
raise ValueError("Email required")
if not data.get("name"):
logger.error("Missing name")
raise ValueError("Name required")
# ...
# AFTER
def validate_required_field(data: dict, field: str) -> None:
if not data.get(field):
logger.error(f"Missing {field}")
raise ValueError(f"{field.capitalize()} required")
def create_user(data):
validate_required_field(data, "email")
validate_required_field(data, "name")
# ...
2.5 Rename for Clarity
Use intention-revealing names.
# BEFORE
def f(x, y):
return x * y * 0.1
# AFTER
def calculate_tax_amount(price: float, quantity: int) -> float:
"""Calculate tax amount (10% rate)."""
return price * quantity * 0.1
Phase 3: Verify (검증)
Objective: Ensure refactoring didn't break functionality.
3.1 Type Check
# Python
uv run mypy . || { echo "Type check failed!"; exit 1; }
# TypeScript
npm run tsc --noEmit || { echo "Type check failed!"; exit 1; }
3.2 Lint Check
# Python
uv run ruff check . || { echo "Lint failed!"; exit 1; }
uv run ruff format .
# TypeScript
npm run lint || { echo "Lint failed!"; exit 1; }
npm run lint:fix
3.3 Run Tests
# Python
uv run pytest -v || { echo "Tests failed!"; exit 1; }
# TypeScript/JavaScript
npm test || { echo "Tests failed!"; exit 1; }
3.4 Build Check (if applicable)
# Backend
uv run python -m compileall . || { echo "Build failed!"; exit 1; }
# Frontend
npm run build || { echo "Build failed!"; exit 1; }
Critical Rule: If ANY verification step fails, DO NOT proceed to commit. Fix issues first.
Phase 4: Commit (커밋)
Principle: Commit logical, atomic changes with clear messages.
4.1 Review Changes
git diff
git status
4.2 Stage Changes
# Stage specific files
git add <file1> <file2>
# Or stage all if refactoring is cohesive
git add .
4.3 Commit Message Format
Follow Conventional Commits:
<type>: <short summary>
<body - explain WHY, not WHAT>
<footer - references, metrics>
Types:
- refactor: Code restructuring (no behavior change)
- perf: Performance improvement
- style: Formatting, naming (no logic change)
- chore: Build config, tooling
Good Commit Message Example:
refactor: simplify order validation logic
Extracted nested conditionals into guard clauses and separate
validation functions. This improves readability and reduces
cyclomatic complexity.
Complexity metrics:
- process_order: CC 12 → 3
- validate_user: CC 8 → 4
Related: #123
4.4 Execute Commit
git commit -m "refactor: <description>"
Multiple Logical Changes? Make separate commits:
# Commit 1: Extract methods
git add file1.py file2.py
git commit -m "refactor: extract validation methods"
# Commit 2: Simplify conditionals
git add file3.py
git commit -m "refactor: replace nested ifs with guard clauses"
Phase 5: Pull Request (PR 생성)
Objective: Submit refactoring for code review.
5.1 Push to Remote
# Create feature branch if not already on one
git checkout -b refactor/improve-complexity
# Push changes
git push origin refactor/improve-complexity
5.2 Create PR with GitHub CLI
gh pr create --title "refactor: improve code complexity and maintainability" --body "$(cat <<'EOF'
## Summary
Post-implementation refactoring to improve code quality following Kent Beck principles.
## Refactoring Details
### Before
| File | Function | Cyclomatic Complexity |
|------|----------|----------------------|
| order.py | process_order | 12 |
| validation.py | validate_user | 8 |
### After
| File | Function | Cyclomatic Complexity |
|------|----------|----------------------|
| order.py | process_order | 3 |
| order.py | is_valid_premium_order | 2 |
| order.py | calculate_order_details | 2 |
| validation.py | validate_user | 4 |
**Complexity Reduction**: Average CC reduced from 10 to 2.75
## Refactoring Patterns Applied
- [x] Extract Method
- [x] Guard Clauses / Early Return
- [x] Rename Variables for Clarity
- [x] Remove Duplication
- [ ] Strategy Pattern (not needed)
## Verification
- [x] All tests passing (pytest: 45 passed)
- [x] Type check passing (mypy: Success)
- [x] Lint check passing (ruff: 0 errors)
- [x] Build successful
## Behavior Changes
**None** - Pure refactoring with no functional changes.
## Related Issues
Closes #<issue-number>
EOF
)"
5.3 PR Description Template
Use this template for consistency:
## Summary
[Brief description of refactoring goals]
## Complexity Metrics
### Before Refactoring
| File | Function | CC | Cognitive | Lines |
|------|----------|----|-----------| ------|
| file1.py | func_a | 15 | 18 | 65 |
| file2.ts | func_b | 11 | 14 | 48 |
### After Refactoring
| File | Function | CC | Cognitive | Lines |
|------|----------|----|-----------| ------|
| file1.py | func_a | 4 | 5 | 25 |
| file1.py | helper_1 | 2 | 2 | 8 |
| file1.py | helper_2 | 2 | 3 | 10 |
| file2.ts | func_b | 5 | 6 | 20 |
| file2.ts | helper | 3 | 4 | 12 |
**Average Complexity Reduction**: CC 13 → 3.2 (75% improvement)
## Refactoring Patterns Used
- [ ] Extract Method
- [ ] Extract Variable
- [ ] Inline Method
- [ ] Guard Clauses
- [ ] Replace Conditional with Polymorphism
- [ ] Strategy Pattern
- [ ] Remove Duplication
- [ ] Rename for Clarity
## Verification Checklist
- [ ] All tests passing
- [ ] Type check passing
- [ ] Lint check passing
- [ ] Build successful
- [ ] No behavior changes
- [ ] Performance neutral or improved
## Related Issues
Closes #<issue>
Kent Beck Principles Reference
The Four Rules of Simple Design
- Passes all tests - Must work correctly
- Reveals intention - Code communicates clearly
- No duplication - DRY principle
- Minimal elements - Remove unnecessary complexity
TDD Refactoring Cycle
RED → GREEN → REFACTOR
↑ ↓
└───────────────┘
- RED: Write failing test
- GREEN: Make it pass (quick & dirty OK)
- REFACTOR: Clean up while keeping tests green
This skill focuses on step 3 after features are implemented.
Refactoring Safety Rules
Always:
- ✅ Run tests after each refactoring step
- ✅ Make small, incremental changes
- ✅ Commit working states frequently
- ✅ Use type checker to catch errors early
Never:
- ❌ Refactor without tests
- ❌ Change behavior during refactoring
- ❌ Make big changes all at once
- ❌ Skip verification steps
Code Quality Targets
Complexity Metrics Goals
| Metric | Target | Acceptable | Needs Refactoring |
|---|---|---|---|
| Cyclomatic Complexity | ≤ 5 | ≤ 10 | > 10 |
| Cognitive Complexity | ≤ 7 | ≤ 15 | > 15 |
| Function Length | ≤ 25 lines | ≤ 50 lines | > 50 lines |
| Nesting Depth | ≤ 2 | ≤ 4 | > 4 |
| Function Parameters | ≤ 3 | ≤ 5 | > 5 |
Code Quality Principles
SOLID Principles:
- Single Responsibility: One function, one purpose
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable
- Interface Segregation: Many small interfaces > one large
- Dependency Inversion: Depend on abstractions
Other Key Principles:
- DRY: Don't Repeat Yourself
- KISS: Keep It Simple, Stupid
- YAGNI: You Aren't Gonna Need It
- Boy Scout Rule: Leave code better than you found it
Automation Script
Save this as kent-beck-refactor.sh for automation:
#!/bin/bash
# Kent Beck Refactoring Workflow Automation
set -e
echo "🎯 Kent Beck Refactoring Workflow"
echo "=================================="
# Configuration
BRANCH_NAME="refactor/$(date +%Y%m%d-%H%M%S)"
PROJECT_TYPE="${1:-python}" # python or typescript
# Phase 1: Analysis
echo ""
echo "📊 Phase 1: Analyzing complexity..."
if [ "$PROJECT_TYPE" = "python" ]; then
echo "Running radon analysis..."
radon cc . -s -a || true
radon mi . || true
elif [ "$PROJECT_TYPE" = "typescript" ]; then
echo "Running ESLint complexity analysis..."
npx eslint . --format json > /tmp/eslint-before.json || true
fi
# Phase 2: Refactoring (Manual)
echo ""
echo "✏️ Phase 2: Refactor code now"
echo " - Apply Kent Beck patterns"
echo " - Focus on high-complexity areas"
echo " - Make small, safe changes"
echo ""
read -p "Press Enter when refactoring is complete..."
# Phase 3: Verification
echo ""
echo "✅ Phase 3: Running verification..."
if [ "$PROJECT_TYPE" = "python" ]; then
echo "Type checking..."
uv run mypy . || { echo "❌ Type check failed"; exit 1; }
echo "Linting..."
uv run ruff check . || { echo "❌ Lint failed"; exit 1; }
uv run ruff format .
echo "Testing..."
uv run pytest -v || { echo "❌ Tests failed"; exit 1; }
elif [ "$PROJECT_TYPE" = "typescript" ]; then
echo "Type checking..."
npm run tsc --noEmit || { echo "❌ Type check failed"; exit 1; }
echo "Linting..."
npm run lint || { echo "❌ Lint failed"; exit 1; }
echo "Testing..."
npm test || { echo "❌ Tests failed"; exit 1; }
fi
echo "✅ All verifications passed!"
# Phase 4: Commit
echo ""
echo "💾 Phase 4: Committing changes..."
git add .
echo "Enter commit message (e.g., 'simplify validation logic'):"
read -p "refactor: " COMMIT_MSG
git commit -m "refactor: $COMMIT_MSG"
echo "✅ Changes committed!"
# Phase 5: PR
echo ""
echo "🚀 Phase 5: Creating Pull Request..."
read -p "Create PR? (y/n): " CREATE_PR
if [ "$CREATE_PR" = "y" ]; then
git checkout -b "$BRANCH_NAME"
git push origin "$BRANCH_NAME"
gh pr create --title "refactor: $COMMIT_MSG" --body "Automated Kent Beck refactoring workflow
## Verification
- [x] All tests passing
- [x] Type check passing
- [x] Lint check passing
## Complexity Analysis
See commit message for details."
echo "✅ Pull Request created!"
fi
echo ""
echo "🎉 Kent Beck Refactoring Complete!"
Usage:
# Python project
chmod +x kent-beck-refactor.sh
./kent-beck-refactor.sh python
# TypeScript project
./kent-beck-refactor.sh typescript
Integration with Development Workflow
Trigger After TODO Completion
When AI completes a task list:
1. Check for high-complexity code in changed files
2. If complexity > threshold, automatically invoke this skill
3. Perform refactoring workflow
4. Commit and create PR
CI/CD Integration
Add complexity checks to CI pipeline:
# .github/workflows/complexity-check.yml
name: Code Complexity Check
on: [pull_request]
jobs:
complexity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Check Python Complexity
run: |
pip install radon
radon cc . -s -a -nc
radon cc . -s -a --total-average
Best Practices Summary
Do's ✅
- Refactor in small, safe steps
- Run tests after EVERY change
- Commit working states frequently
- Focus on one pattern at a time
- Use meaningful names
- Extract before inline
- Simplify before optimizing
Don'ts ❌
- Change behavior during refactoring
- Refactor without test coverage
- Make multiple changes simultaneously
- Skip verification steps
- Optimize prematurely
- Delete tests to make them pass
Usage Examples
Example 1: After Feature Implementation
User: "회원가입 기능 구현 완료"
AI: "기능 구현 완료를 확인했습니다. 코드 품질 개선을 위해 Kent Beck 리팩토링을 시작하겠습니다."
Example 2: Manual Trigger
User: "이 파일 복잡도 너무 높아. 리팩토링해줘"
AI: "복잡도 분석을 시작합니다..."
Example 3: Completing Task List
User: "모든 TODO 완료됐어"
AI: "모든 작업 완료 확인. 리팩토링 및 PR 생성을 진행합니다."
Remember: Refactoring is not about rewriting code—it's about incrementally improving design while preserving behavior. Small steps, continuous testing, and clear commits are key to successful refactoring.
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.