Reduces cyclomatic complexity of functions and methods through extraction, simplification, and restructuring without changing behavior.
Refactor complex functions to reduce cyclomatic complexity through method extraction, guard clauses, and logic simplification. Use when functions exceed complexity of 10 to improve maintainability without changing behavior.
/plugin marketplace add avovello/cc-plugins/plugin install refactor@cc-pluginsReduces cyclomatic complexity of functions and methods through extraction, simplification, and restructuring without changing behavior.
✅ DOES:
❌ DOES NOT:
| Complexity | Rating | Action |
|---|---|---|
| 1-5 | Simple | No action needed ✅ |
| 6-10 | Moderate | Consider simplifying |
| 11-20 | Complex | Should refactor ⚠️ |
| 21-50 | Very Complex | Must refactor 🔴 |
| 50+ | Extremely Complex | Critical refactoring needed 🚨 |
Pattern: Long function or complex logic block
Technique: Extract into well-named function
Example:
// ❌ Complex (Complexity: 12)
function processOrder(order) {
if (!order.id) throw new Error('Missing ID');
if (!order.items || order.items.length === 0) throw new Error('No items');
if (!order.customer) throw new Error('No customer');
let total = 0;
for (let item of order.items) {
if (item.price < 0) throw new Error('Invalid price');
if (item.quantity < 1) throw new Error('Invalid quantity');
total += item.price * item.quantity;
if (item.discount) {
if (item.discount < 0 || item.discount > 100) throw new Error('Invalid discount');
total -= (item.price * item.quantity * item.discount / 100);
}
}
order.total = total;
return order;
}
// ✅ Simplified (Complexity: 3)
function processOrder(order) {
validateOrder(order);
order.total = calculateTotal(order.items);
return order;
}
function validateOrder(order) {
if (!order.id) throw new Error('Missing ID');
if (!order.items || order.items.length === 0) throw new Error('No items');
if (!order.customer) throw new Error('No customer');
}
function calculateTotal(items) {
return items.reduce((total, item) => {
validateItem(item);
return total + calculateItemTotal(item);
}, 0);
}
function validateItem(item) {
if (item.price < 0) throw new Error('Invalid price');
if (item.quantity < 1) throw new Error('Invalid quantity');
if (item.discount && (item.discount < 0 || item.discount > 100)) {
throw new Error('Invalid discount');
}
}
function calculateItemTotal(item) {
let total = item.price * item.quantity;
if (item.discount) {
total -= (total * item.discount / 100);
}
return total;
}
Impact: Complexity 12 → 3 (75% reduction)
Pattern: Deep nesting of if statements
Technique: Use early returns (guard clauses)
Example:
// ❌ Complex (Complexity: 8, Nesting: 4)
function processPayment(payment) {
if (payment) {
if (payment.amount > 0) {
if (payment.method) {
if (payment.method === 'credit_card') {
if (payment.cardNumber) {
return chargeCreditCard(payment);
} else {
throw new Error('Missing card number');
}
} else {
return processAlternativePayment(payment);
}
} else {
throw new Error('Missing payment method');
}
} else {
throw new Error('Invalid amount');
}
} else {
throw new Error('Missing payment');
}
}
// ✅ Simplified (Complexity: 5, Nesting: 1)
function processPayment(payment) {
// Guard clauses
if (!payment) throw new Error('Missing payment');
if (payment.amount <= 0) throw new Error('Invalid amount');
if (!payment.method) throw new Error('Missing payment method');
// Main logic
if (payment.method === 'credit_card') {
if (!payment.cardNumber) throw new Error('Missing card number');
return chargeCreditCard(payment);
}
return processAlternativePayment(payment);
}
Impact: Nesting 4 → 1, Complexity 8 → 5
Pattern: Complex conditional expressions
Technique: Extract conditions into well-named functions
Example:
// ❌ Complex
if (user.age >= 18 && user.country === 'US' && user.verified && !user.banned &&
(user.subscription === 'premium' || user.credits > 10)) {
allowAccess();
}
// ✅ Simplified
if (canAccessPremiumFeature(user)) {
allowAccess();
}
function canAccessPremiumFeature(user) {
return isEligibleUser(user) && hasActiveSubscription(user);
}
function isEligibleUser(user) {
return user.age >= 18 &&
user.country === 'US' &&
user.verified &&
!user.banned;
}
function hasActiveSubscription(user) {
return user.subscription === 'premium' || user.credits > 10;
}
Pattern: Complex loops with multiple operations
Technique: Use map/filter/reduce pipeline
Example:
// ❌ Complex (Complexity: 7)
function getActiveUserEmails(users) {
let emails = [];
for (let i = 0; i < users.length; i++) {
if (users[i].active) {
if (users[i].email) {
if (users[i].email.includes('@')) {
emails.push(users[i].email.toLowerCase());
}
}
}
}
return emails;
}
// ✅ Simplified (Complexity: 2)
function getActiveUserEmails(users) {
return users
.filter(user => user.active)
.map(user => user.email)
.filter(email => email && email.includes('@'))
.map(email => email.toLowerCase());
}
Pattern: Same condition checked multiple times
Technique: Check once, use result
Example:
// ❌ Complex
function formatUser(user) {
let name = user.firstName && user.lastName
? `${user.firstName} ${user.lastName}`
: 'Anonymous';
let greeting = user.firstName && user.lastName
? `Hello, ${user.firstName}!`
: 'Hello!';
let initial = user.firstName && user.lastName
? user.firstName[0]
: '?';
return { name, greeting, initial };
}
// ✅ Simplified
function formatUser(user) {
const hasFullName = user.firstName && user.lastName;
return {
name: hasFullName ? `${user.firstName} ${user.lastName}` : 'Anonymous',
greeting: hasFullName ? `Hello, ${user.firstName}!` : 'Hello!',
initial: hasFullName ? user.firstName[0] : '?'
};
}
Run complexity analysis:
# JavaScript
npx eslint --plugin complexity --rule 'complexity: [2, 10]' src/
# Python
radon cc src/ -a
# PHP
phpmd src/ text codesize,unusedcode
# Java
mvn pmd:pmd
Identify functions with complexity > 10.
For each complex function:
## Function: processOrder
**Location**: src/services/OrderService.js:45
**Current Complexity**: 15
**Complexity Breakdown**:
- Conditionals: 8 (if statements)
- Loops: 2 (for loops)
- Boolean operators: 5 (&&, ||)
- Case statements: 0
- Nesting depth: 4 levels
**Causes of Complexity**:
1. Validation logic mixed with business logic
2. Nested loops and conditionals
3. Complex boolean expressions
4. Multiple responsibilities (validate + calculate + save)
## Refactoring Plan
**Goal**: Reduce complexity from 15 to ≤ 5
**Steps**:
1. Extract validation logic → validateOrder() (saves 4 complexity)
2. Extract calculation logic → calculateTotal() (saves 3 complexity)
3. Replace nested conditionals with guard clauses (saves 2 complexity)
4. Simplify boolean expressions (saves 1 complexity)
**Expected Final Complexity**: 5 ✅
**Step 1**: Extract validation logic
- Before: Complexity 15
- After: Complexity 11
- Test: ✅ All tests pass
- Commit: "refactor: extract validation from processOrder"
**Step 2**: Extract calculation logic
- Before: Complexity 11
- After: Complexity 8
- Test: ✅ All tests pass
- Commit: "refactor: extract calculation from processOrder"
**Step 3**: Apply guard clauses
- Before: Complexity 8
- After: Complexity 6
- Test: ✅ All tests pass
- Commit: "refactor: simplify conditionals in processOrder"
**Step 4**: Simplify boolean expressions
- Before: Complexity 6
- After: Complexity 5
- Test: ✅ All tests pass
- Commit: "refactor: simplify expressions in processOrder"
## Results
**Before**: Complexity 15 (Very Complex 🔴)
**After**: Complexity 5 (Simple ✅)
**Improvement**: 67% reduction
**Tests**: All 23 tests pass ✅
**Behavior**: No changes (verified)
**Code Coverage**: 85% → 87% (improved)
# Complexity Reduction Report
## Summary
- **Functions Analyzed**: 45
- **Complex Functions Found**: 8 (complexity > 10)
- **Functions Refactored**: 8
- **Average Complexity Before**: 14.3
- **Average Complexity After**: 5.1
- **Average Reduction**: 64%
## Detailed Results
### Function 1: processOrder
**Location**: `src/services/OrderService.js:45`
**Before**:
- Complexity: 15
- Lines: 87
- Nesting: 4 levels
**After**:
- Complexity: 5
- Lines: 12 (main) + 35 (extracted functions)
- Nesting: 1 level
**Refactorings Applied**:
1. ✅ Extracted validateOrder() function
2. ✅ Extracted calculateTotal() function
3. ✅ Applied guard clauses
4. ✅ Simplified boolean expressions
**Improvement**: 67% complexity reduction
**Tests**: All 23 tests pass ✅
---
### Function 2: authenticateUser
[Similar breakdown]
---
## Commits Created
1. `refactor: extract validation from processOrder`
2. `refactor: extract calculation from processOrder`
3. `refactor: simplify conditionals in processOrder`
4. `refactor: simplify expressions in processOrder`
5. `refactor: reduce complexity in authenticateUser`
...
## Overall Impact
- **Code Maintainability**: Significantly improved
- **Test Coverage**: 82% → 87%
- **Average Function Length**: 45 lines → 18 lines
- **Maximum Complexity**: 24 → 7
- **Developer Experience**: Functions easier to understand and modify
Before completing:
Use this agent when analyzing conversation transcripts to find behaviors worth preventing with hooks. Examples: <example>Context: User is running /hookify command without arguments user: "/hookify" assistant: "I'll analyze the conversation to find behaviors you want to prevent" <commentary>The /hookify command without arguments triggers conversation analysis to find unwanted behaviors.</commentary></example><example>Context: User wants to create hooks from recent frustrations user: "Can you look back at this conversation and help me create hooks for the mistakes you made?" assistant: "I'll use the conversation-analyzer agent to identify the issues and suggest hooks." <commentary>User explicitly asks to analyze conversation for mistakes that should be prevented.</commentary></example>