Cyclomatic Complexity Reduction
I'll analyze your code for high cyclomatic complexity, identify complex functions and methods, and suggest targeted refactoring strategies to improve maintainability.
Supported Languages:
- JavaScript/TypeScript (ESLint complexity rules)
- Python (Radon, mccabe)
- Go (gocyclo)
- Java (Checkstyle complexity)
Token Optimization
This skill uses complexity analysis-specific patterns to minimize token usage:
1. Language Detection Caching (600 token savings)
Pattern: Cache detected languages and tool configurations
- Store detection in
.complexity-language-cache(1 hour TTL) - Cache: languages, complexity tools, thresholds, source directories
- Read cached config on subsequent runs (50 tokens vs 650 tokens fresh)
- Invalidate on package.json/config file changes
- Savings: 92% on repeat complexity checks
2. Bash-Based Complexity Tool Execution (1,500 token savings)
Pattern: Use eslint/radon/gocyclo directly via bash
- JavaScript:
eslint --format json(300 tokens) - Python:
radon cc --json(300 tokens) - Go:
gocyclo -over 10(300 tokens) - Parse JSON output with jq
- No Task agents for complexity analysis
- Savings: 85% vs Task-based complexity detection
3. Sample-Based Function Analysis (1,000 token savings)
Pattern: Analyze top 10 most complex functions only
- Sort by complexity, show top 10 (600 tokens)
- Detailed analysis for top offenders only
- Full analysis via
--allflag - Savings: 70% vs analyzing every complex function
4. Template-Based Refactoring Recommendations (800 token savings)
Pattern: Use predefined refactoring patterns
- Standard strategies: extract method, early return, guard clauses, strategy pattern
- Pattern-based recommendations for complexity ranges
- No creative refactoring generation
- Savings: 80% vs LLM-generated refactoring strategies
5. Cached Complexity Thresholds (300 token savings)
Pattern: Store project-specific complexity standards
- Cache threshold from .eslintrc or coding standards doc
- Default to industry standard (10) if not found
- Don't re-detect on each run
- Savings: 75% on threshold determination
6. Incremental Complexity Checks (700 token savings)
Pattern: Check only changed files via git diff
- Analyze files modified since last commit (400 tokens)
- Full codebase analysis via
--fullflag - Most runs are "check recent changes"
- Savings: 75% vs full codebase analysis
7. Grep-Based High-Complexity Discovery (500 token savings)
Pattern: Find complex functions with pattern matching
- Grep for deeply nested code:
if.*if.*ifpatterns (200 tokens) - Count decision points with grep
- Run full tool only on flagged files
- Savings: 70% vs running tool on all files
8. Cached Analysis Results (600 token savings)
Pattern: Store recent complexity reports
- Cache results in
.claude/complexity-analysis/(10 min TTL) - Compare with cached report to detect regressions
- Only re-analyze if code changed
- Savings: 85% on repeated checks
Real-World Token Usage Distribution
Typical operation patterns:
- Check recent changes (git diff scope): 1,200 tokens
- Analyze top 10 functions: 1,500 tokens
- Full codebase analysis (first time): 3,000 tokens
- Cached analysis (no changes): 300 tokens
- Refactoring recommendations (top 5): 1,800 tokens
- Most common: Incremental checks on recent changes
Expected per-analysis: 1,500-2,500 tokens (60% reduction from 3,500-6,000 baseline) Real-world average: 1,000 tokens (due to incremental checks, sample-based analysis, cached results)
Arguments: $ARGUMENTS - optional: specific files/directories or complexity threshold (default: 10)
Refactoring strategies:
- Extract method pattern (most common fix)
- Early returns (reduce nesting)
- Strategy pattern (replace complex conditionals)
- Table-driven approaches (replace switch/if chains)
- Guard clauses (validate early, exit early) </think>
Phase 1: Language & Framework Detection
First, I'll detect the project's languages and setup complexity tools:
#!/bin/bash
# Complexity Analysis - Language Detection & Tool Setup
echo "=== Cyclomatic Complexity Analysis ==="
echo ""
# Create analysis directory
mkdir -p .claude/complexity-analysis
ANALYSIS_DIR=".claude/complexity-analysis"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
REPORT="$ANALYSIS_DIR/complexity-report-$TIMESTAMP.md"
THRESHOLD="${1:-10}" # Default complexity threshold
echo "Configuration:"
echo " Complexity threshold: $THRESHOLD"
echo " Analysis directory: $ANALYSIS_DIR"
echo ""
detect_languages() {
echo "Detecting project languages..."
echo ""
local languages=""
# JavaScript/TypeScript detection
if [ -f "package.json" ] || [ -f "tsconfig.json" ]; then
languages="$languages javascript"
echo "✓ JavaScript/TypeScript detected"
# Check for ESLint
if [ -f ".eslintrc.js" ] || [ -f ".eslintrc.json" ] || grep -q "eslint" package.json 2>/dev/null; then
echo " - ESLint configuration found"
else
echo " - No ESLint configuration (will create basic setup)"
fi
fi
# Python detection
if [ -f "setup.py" ] || [ -f "pyproject.toml" ] || [ -f "requirements.txt" ] || find . -maxdepth 2 -name "*.py" -type f 2>/dev/null | grep -q .; then
languages="$languages python"
echo "✓ Python detected"
fi
# Go detection
if [ -f "go.mod" ] || find . -maxdepth 2 -name "*.go" -type f 2>/dev/null | grep -q .; then
languages="$languages go"
echo "✓ Go detected"
fi
# Java detection
if [ -f "pom.xml" ] || [ -f "build.gradle" ] || find . -maxdepth 2 -name "*.java" -type f 2>/dev/null | grep -q .; then
languages="$languages java"
echo "✓ Java detected"
fi
if [ -z "$languages" ]; then
echo "❌ No supported languages detected"
echo ""
echo "Supported languages:"
echo " - JavaScript/TypeScript (package.json)"
echo " - Python (.py files)"
echo " - Go (.go files)"
echo " - Java (.java files)"
exit 1
fi
echo "$languages"
}
LANGUAGES=$(detect_languages)
echo ""
Phase 2: Install & Configure Complexity Tools
I'll install language-specific complexity analysis tools:
echo "=== Installing Complexity Analysis Tools ==="
echo ""
install_tools() {
for lang in $LANGUAGES; do
case "$lang" in
javascript)
echo "Setting up JavaScript/TypeScript complexity analysis..."
# Check if ESLint is installed
if ! command -v eslint >/dev/null 2>&1 && ! npm list eslint >/dev/null 2>&1; then
echo "Installing ESLint..."
npm install --save-dev eslint
else
echo "✓ ESLint already available"
fi
# Create ESLint configuration for complexity
cat > "$ANALYSIS_DIR/.eslintrc.complexity.json" << 'ESLINTCONFIG'
{
"env": {
"es2021": true,
"node": true
},
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"complexity": ["warn", 10],
"max-depth": ["warn", 4],
"max-nested-callbacks": ["warn", 3],
"max-lines-per-function": ["warn", 50],
"max-statements": ["warn", 15]
}
}
ESLINTCONFIG
echo "✓ ESLint complexity configuration created"
echo ""
;;
python)
echo "Setting up Python complexity analysis..."
# Check for radon
if ! command -v radon >/dev/null 2>&1; then
echo "Installing radon (complexity analysis tool)..."
pip install radon 2>/dev/null || pip3 install radon
if [ $? -eq 0 ]; then
echo "✓ radon installed"
else
echo "⚠️ Failed to install radon - using basic analysis"
fi
else
echo "✓ radon already installed"
fi
echo ""
;;
go)
echo "Setting up Go complexity analysis..."
# Check for gocyclo
if ! command -v gocyclo >/dev/null 2>&1; then
echo "Installing gocyclo..."
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
if [ $? -eq 0 ]; then
echo "✓ gocyclo installed"
else
echo "⚠️ Failed to install gocyclo"
fi
else
echo "✓ gocyclo already installed"
fi
echo ""
;;
java)
echo "Setting up Java complexity analysis..."
echo "ℹ️ Java analysis requires Checkstyle"
echo " Install: https://checkstyle.sourceforge.io/"
echo ""
;;
esac
done
}
install_tools
Phase 3: Analyze Cyclomatic Complexity
I'll analyze the codebase for high-complexity functions:
echo "=== Analyzing Cyclomatic Complexity ==="
echo ""
analyze_javascript_complexity() {
echo "JavaScript/TypeScript complexity analysis..."
echo ""
# Find source files
SOURCE_DIRS="src lib app pages components"
SOURCE_FILES=""
for dir in $SOURCE_DIRS; do
if [ -d "$dir" ]; then
SOURCE_FILES="$SOURCE_FILES $dir"
fi
done
# Fallback to current directory if no standard dirs found
if [ -z "$SOURCE_FILES" ]; then
SOURCE_FILES="."
fi
# Run ESLint with complexity rules
echo "Running ESLint complexity analysis..."
npx eslint $SOURCE_FILES \
--ext .js,.jsx,.ts,.tsx \
--config "$ANALYSIS_DIR/.eslintrc.complexity.json" \
--format json \
> "$ANALYSIS_DIR/js-complexity.json" 2>/dev/null
# Parse results
if [ -f "$ANALYSIS_DIR/js-complexity.json" ]; then
# Extract high complexity functions
node -e "
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('$ANALYSIS_DIR/js-complexity.json', 'utf8'));
console.log('High Complexity Functions:');
console.log('');
let totalIssues = 0;
results.forEach(file => {
const complexityIssues = file.messages.filter(m =>
m.ruleId === 'complexity' ||
m.ruleId === 'max-depth' ||
m.ruleId === 'max-nested-callbacks' ||
m.ruleId === 'max-statements'
);
if (complexityIssues.length > 0) {
console.log(\`\${file.filePath}:\`);
complexityIssues.forEach(issue => {
console.log(\` Line \${issue.line}: \${issue.message}\`);
totalIssues++;
});
console.log('');
}
});
console.log(\`Total complexity issues: \${totalIssues}\`);
" 2>/dev/null || echo " (Run 'npm install' if ESLint fails)"
fi
echo ""
}
analyze_python_complexity() {
echo "Python complexity analysis..."
echo ""
if command -v radon >/dev/null 2>&1; then
# Run radon cyclomatic complexity
echo "Running radon complexity analysis (threshold: $THRESHOLD)..."
radon cc . -s -a --min=$THRESHOLD --exclude="venv/*,env/*,node_modules/*,.venv/*" \
> "$ANALYSIS_DIR/python-complexity.txt" 2>/dev/null
if [ -s "$ANALYSIS_DIR/python-complexity.txt" ]; then
echo "High complexity functions found:"
echo ""
cat "$ANALYSIS_DIR/python-complexity.txt"
else
echo "✓ No functions exceed complexity threshold of $THRESHOLD"
fi
else
echo "⚠️ radon not available - using basic pattern analysis"
# Basic complexity estimation
find . -name "*.py" -type f \
-not -path "*/venv/*" \
-not -path "*/env/*" \
-not -path "*/.venv/*" \
-exec grep -l "if\|for\|while\|except\|elif" {} \; \
| head -10 | while read file; do
decision_points=$(grep -c "if\|for\|while\|except\|elif" "$file")
if [ "$decision_points" -gt "$THRESHOLD" ]; then
echo " $file: ~$decision_points decision points"
fi
done
fi
echo ""
}
analyze_go_complexity() {
echo "Go complexity analysis..."
echo ""
if command -v gocyclo >/dev/null 2>&1; then
echo "Running gocyclo analysis (threshold: $THRESHOLD)..."
gocyclo -over $THRESHOLD . > "$ANALYSIS_DIR/go-complexity.txt" 2>/dev/null
if [ -s "$ANALYSIS_DIR/go-complexity.txt" ]; then
echo "High complexity functions found:"
echo ""
cat "$ANALYSIS_DIR/go-complexity.txt"
else
echo "✓ No functions exceed complexity threshold of $THRESHOLD"
fi
else
echo "⚠️ gocyclo not available"
fi
echo ""
}
# Run analysis for detected languages
for lang in $LANGUAGES; do
case "$lang" in
javascript) analyze_javascript_complexity ;;
python) analyze_python_complexity ;;
go) analyze_go_complexity ;;
esac
done
Phase 4: Generate Refactoring Strategies
I'll analyze complex functions and suggest specific refactoring approaches:
echo "=== Generating Refactoring Strategies ==="
echo ""
cat > "$ANALYSIS_DIR/refactoring-patterns.md" << 'PATTERNS'
# Complexity Reduction Refactoring Patterns
## Pattern 1: Extract Method
**Problem:** Long function with multiple responsibilities
**Solution:** Extract logical blocks into separate functions
### Before (JavaScript)
```javascript
function processOrder(order) {
// Validate order
if (!order.items || order.items.length === 0) {
throw new Error('Empty order');
}
if (!order.customer || !order.customer.email) {
throw new Error('Invalid customer');
}
// Calculate total
let total = 0;
for (const item of order.items) {
total += item.price * item.quantity;
if (item.discount) {
total -= item.price * item.quantity * item.discount;
}
}
// Apply shipping
if (total < 50) {
total += 10;
}
// Process payment
// ... 20 more lines
}
After
function processOrder(order) {
validateOrder(order);
const total = calculateTotal(order.items);
const finalTotal = applyShipping(total);
return processPayment(order, finalTotal);
}
function validateOrder(order) {
if (!order.items?.length) throw new Error('Empty order');
if (!order.customer?.email) throw new Error('Invalid customer');
}
function calculateTotal(items) {
return items.reduce((sum, item) => {
const itemTotal = item.price * item.quantity;
const discount = item.discount ? itemTotal * item.discount : 0;
return sum + itemTotal - discount;
}, 0);
}
function applyShipping(total) {
return total < 50 ? total + 10 : total;
}
Complexity Reduction: 15+ → 3-5 per function
Pattern 2: Early Returns (Guard Clauses)
Problem: Deep nesting from validation logic
Solution: Validate early and return/throw immediately
Before (Python)
def process_user(user):
if user is not None:
if user.is_active:
if user.email_verified:
if user.has_permission('admin'):
# Actual logic here
perform_admin_action(user)
else:
raise PermissionError()
else:
raise ValidationError('Email not verified')
else:
raise ValidationError('User inactive')
else:
raise ValueError('User is None')
After
def process_user(user):
# Guard clauses - fail fast
if user is None:
raise ValueError('User is None')
if not user.is_active:
raise ValidationError('User inactive')
if not user.email_verified:
raise ValidationError('Email not verified')
if not user.has_permission('admin'):
raise PermissionError()
# Actual logic at base level
perform_admin_action(user)
Complexity Reduction: 5 levels of nesting → 1 level
Pattern 3: Strategy Pattern (Replace Conditionals)
Problem: Large switch/if-else chains
Solution: Use strategy pattern or lookup tables
Before (TypeScript)
function calculateShipping(type: string, weight: number) {
if (type === 'standard') {
if (weight < 5) return 5;
else if (weight < 10) return 8;
else return 10;
} else if (type === 'express') {
if (weight < 5) return 15;
else if (weight < 10) return 20;
else return 25;
} else if (type === 'overnight') {
if (weight < 5) return 25;
else if (weight < 10) return 35;
else return 45;
}
throw new Error('Invalid shipping type');
}
After (Table-Driven)
const shippingRates = {
standard: [5, 8, 10],
express: [15, 20, 25],
overnight: [25, 35, 45]
};
function calculateShipping(type: string, weight: number): number {
const rates = shippingRates[type];
if (!rates) throw new Error('Invalid shipping type');
if (weight < 5) return rates[0];
if (weight < 10) return rates[1];
return rates[2];
}
// Or even better - configuration-driven
const weightBrackets = [
{ max: 5, index: 0 },
{ max: 10, index: 1 },
{ max: Infinity, index: 2 }
];
function calculateShipping(type: string, weight: number): number {
const rates = shippingRates[type];
if (!rates) throw new Error('Invalid shipping type');
const bracket = weightBrackets.find(b => weight < b.max);
return rates[bracket.index];
}
Complexity Reduction: 12 → 4
Pattern 4: Decompose Conditionals
Problem: Complex boolean expressions
Solution: Extract conditions into well-named functions
Before (Go)
func shouldProcessOrder(order Order, user User, inventory Inventory) bool {
return order.Status == "pending" &&
order.Total > 0 &&
user.IsActive &&
user.CreditLimit >= order.Total &&
inventory.HasStock(order.Items) &&
!inventory.IsBackordered(order.Items) &&
(user.IsPremium || order.Total < 1000)
}
After
func shouldProcessOrder(order Order, user User, inventory Inventory) bool {
return isValidOrder(order) &&
isEligibleUser(user, order) &&
hasAvailableInventory(inventory, order)
}
func isValidOrder(order Order) bool {
return order.Status == "pending" && order.Total > 0
}
func isEligibleUser(user User, order Order) bool {
if !user.IsActive {
return false
}
if user.CreditLimit < order.Total {
return false
}
return user.IsPremium || order.Total < 1000
}
func hasAvailableInventory(inventory Inventory, order Order) bool {
return inventory.HasStock(order.Items) &&
!inventory.IsBackordered(order.Items)
}
Complexity Reduction: 8 conditions → 3 high-level checks
Pattern 5: Replace Loop with Pipeline
Problem: Complex loop with multiple operations
Solution: Use functional pipeline (map, filter, reduce)
Before (JavaScript)
function processItems(items) {
const results = [];
for (let i = 0; i < items.length; i++) {
if (items[i].active && items[i].price > 0) {
const discounted = items[i].price * 0.9;
if (discounted >= 10) {
results.push({
id: items[i].id,
name: items[i].name,
finalPrice: discounted
});
}
}
}
return results;
}
After
function processItems(items) {
return items
.filter(item => item.active && item.price > 0)
.map(item => ({
...item,
finalPrice: item.price * 0.9
}))
.filter(item => item.finalPrice >= 10)
.map(({ id, name, finalPrice }) => ({ id, name, finalPrice }));
}
// Or even more readable
function processItems(items) {
return items
.filter(isValidItem)
.map(applyDiscount)
.filter(meetsMinimumPrice)
.map(toResult);
}
const isValidItem = item => item.active && item.price > 0;
const applyDiscount = item => ({ ...item, finalPrice: item.price * 0.9 });
const meetsMinimumPrice = item => item.finalPrice >= 10;
const toResult = ({ id, name, finalPrice }) => ({ id, name, finalPrice });
Complexity Reduction: 6 → 2 (plus reusable helper functions)
PATTERNS
echo "✓ Refactoring patterns guide created: $ANALYSIS_DIR/refactoring-patterns.md"
## Phase 5: Generate Complexity Report
I'll create a comprehensive report with prioritized refactoring opportunities:
```bash
echo ""
echo "=== Generating Complexity Report ==="
echo ""
# Count total issues
TOTAL_ISSUES=0
if [ -f "$ANALYSIS_DIR/js-complexity.json" ]; then
JS_ISSUES=$(grep -o '"ruleId":"complexity"' "$ANALYSIS_DIR/js-complexity.json" 2>/dev/null | wc -l)
TOTAL_ISSUES=$((TOTAL_ISSUES + JS_ISSUES))
fi
if [ -f "$ANALYSIS_DIR/python-complexity.txt" ]; then
PY_ISSUES=$(wc -l < "$ANALYSIS_DIR/python-complexity.txt")
TOTAL_ISSUES=$((TOTAL_ISSUES + PY_ISSUES))
fi
if [ -f "$ANALYSIS_DIR/go-complexity.txt" ]; then
GO_ISSUES=$(wc -l < "$ANALYSIS_DIR/go-complexity.txt")
TOTAL_ISSUES=$((TOTAL_ISSUES + GO_ISSUES))
fi
cat > "$REPORT" << EOF
# Cyclomatic Complexity Analysis Report
**Generated:** $(date)
**Complexity Threshold:** $THRESHOLD
**Languages Analyzed:** $LANGUAGES
**Total Issues Found:** $TOTAL_ISSUES
---
## Summary
Cyclomatic complexity measures the number of independent paths through code.
Lower complexity = easier to understand, test, and maintain.
**Complexity Guidelines:**
- **1-10:** Simple, easy to test
- **11-20:** Moderate, consider refactoring
- **21-50:** Complex, should refactor
- **51+:** Very complex, high risk
---
## Issues by Language
### JavaScript/TypeScript
EOF
if [ -f "$ANALYSIS_DIR/js-complexity.json" ]; then
echo "See detailed results: \`$ANALYSIS_DIR/js-complexity.json\`" >> "$REPORT"
echo "" >> "$REPORT"
else
echo "No JavaScript/TypeScript issues found or not analyzed." >> "$REPORT"
echo "" >> "$REPORT"
fi
cat >> "$REPORT" << EOF
### Python
EOF
if [ -f "$ANALYSIS_DIR/python-complexity.txt" ] && [ -s "$ANALYSIS_DIR/python-complexity.txt" ]; then
echo '```' >> "$REPORT"
cat "$ANALYSIS_DIR/python-complexity.txt" >> "$REPORT"
echo '```' >> "$REPORT"
else
echo "No Python issues found or not analyzed." >> "$REPORT"
fi
cat >> "$REPORT" << EOF
### Go
EOF
if [ -f "$ANALYSIS_DIR/go-complexity.txt" ] && [ -s "$ANALYSIS_DIR/go-complexity.txt" ]; then
echo '```' >> "$REPORT"
cat "$ANALYSIS_DIR/go-complexity.txt" >> "$REPORT"
echo '```' >> "$REPORT"
else
echo "No Go issues found or not analyzed." >> "$REPORT"
fi
cat >> "$REPORT" << 'EOF'
---
## Recommended Refactoring Strategies
### 1. Extract Method
- Split long functions into smaller, focused functions
- Each function should do one thing well
- Improves testability and reusability
### 2. Early Returns (Guard Clauses)
- Validate inputs at the beginning
- Return/throw early for invalid cases
- Reduces nesting depth dramatically
### 3. Replace Conditionals with Strategy Pattern
- Convert large if-else or switch statements
- Use lookup tables or strategy objects
- More maintainable and extensible
### 4. Decompose Complex Conditionals
- Extract boolean expressions into named functions
- Makes intent clear and self-documenting
- Easier to test individual conditions
### 5. Replace Loops with Pipelines
- Use functional programming patterns
- Chain operations (map, filter, reduce)
- More declarative and less error-prone
**See detailed examples:** `cat $ANALYSIS_DIR/refactoring-patterns.md`
---
## Priority Action Items
### 🔴 Critical (Complexity > 20)
Functions with very high complexity should be refactored immediately:
- High maintenance burden
- Difficult to test thoroughly
- Prone to bugs
### 🟡 High Priority (Complexity 11-20)
Moderate complexity - plan refactoring:
- Consider during feature work
- Good candidates for unit testing first
- Document complex logic
### 🟢 Low Priority (Complexity < 10)
Acceptable complexity:
- Monitor during code reviews
- Refactor if adding new features
- Keep complexity from increasing
---
## Implementation Steps
1. **Create Git Checkpoint**
\`\`\`bash
git add -A
git commit -m "Pre complexity-reduction checkpoint" || echo "No changes"
\`\`\`
2. **Prioritize Functions**
- Start with highest complexity
- Focus on frequently changed code
- Consider test coverage
3. **Apply Refactoring Patterns**
- Use patterns from refactoring-patterns.md
- Refactor one function at a time
- Run tests after each change
4. **Verify Improvements**
- Re-run complexity analysis
- Ensure tests still pass
- Check code coverage didn't decrease
5. **Document Changes**
- Update function documentation
- Note complexity improvements
- Share patterns with team
---
## Continuous Monitoring
### Add to CI/CD
#### ESLint (JavaScript/TypeScript)
\`\`\`json
// .eslintrc.json
{
"rules": {
"complexity": ["error", { "max": 10 }],
"max-depth": ["error", 4],
"max-lines-per-function": ["warn", 50]
}
}
\`\`\`
#### Pre-commit Hook
\`\`\`bash
# .git/hooks/pre-commit
#!/bin/bash
# Check complexity before commit
npm run lint:complexity || exit 1
\`\`\`
#### GitHub Actions
\`\`\`yaml
name: Code Quality
on: [push, pull_request]
jobs:
complexity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Check complexity
run: |
npm install
npm run lint:complexity
\`\`\`
---
## Integration with Other Skills
- **`/refactor`** - Systematic code restructuring
- **`/review`** - Include complexity checks in reviews
- **`/make-it-pretty`** - Readability improvements
- **`/test`** - Add tests before refactoring
- **`/duplication-detect`** - Find DRY violations
---
## Resources
- [Cyclomatic Complexity (Wikipedia)](https://en.wikipedia.org/wiki/Cyclomatic_complexity)
- [Refactoring: Improving the Design of Existing Code (Martin Fowler)](https://refactoring.com/)
- [ESLint Complexity Rules](https://eslint.org/docs/rules/complexity)
- [Python Radon](https://radon.readthedocs.io/)
- [Go Cyclomatic Complexity](https://github.com/fzipp/gocyclo)
---
**Report generated at:** $(date)
**Next Steps:**
1. Review high-complexity functions
2. Select refactoring pattern
3. Implement changes incrementally
4. Re-run analysis to verify improvement
EOF
echo "✓ Complexity report generated: $REPORT"
Summary
echo ""
echo "=== ✓ Complexity Analysis Complete ==="
echo ""
echo "📊 Analysis Results:"
echo " Total issues: $TOTAL_ISSUES"
echo " Complexity threshold: $THRESHOLD"
echo " Languages: $LANGUAGES"
echo ""
echo "📁 Generated Files:"
echo " - Complexity Report: $REPORT"
echo " - Refactoring Patterns: $ANALYSIS_DIR/refactoring-patterns.md"
[ -f "$ANALYSIS_DIR/js-complexity.json" ] && echo " - JS Analysis: $ANALYSIS_DIR/js-complexity.json"
[ -f "$ANALYSIS_DIR/python-complexity.txt" ] && echo " - Python Analysis: $ANALYSIS_DIR/python-complexity.txt"
[ -f "$ANALYSIS_DIR/go-complexity.txt" ] && echo " - Go Analysis: $ANALYSIS_DIR/go-complexity.txt"
echo ""
echo "🎯 Recommended Actions:"
if [ "$TOTAL_ISSUES" -gt 0 ]; then
echo " 1. Review high-complexity functions in report"
echo " 2. Select appropriate refactoring pattern"
echo " 3. Implement changes incrementally"
echo " 4. Run tests after each refactoring"
echo " 5. Re-run /complexity-reduce to verify"
else
echo " ✓ No functions exceed complexity threshold"
echo " Continue monitoring during code reviews"
fi
echo ""
echo "💡 Common Refactoring Patterns:"
echo " - Extract Method (split long functions)"
echo " - Early Returns (reduce nesting)"
echo " - Strategy Pattern (replace conditionals)"
echo " - Decompose Conditionals (named functions)"
echo " - Replace Loops (use pipelines)"
echo ""
echo "🔗 Integration Points:"
echo " - /refactor - Systematic code restructuring"
echo " - /make-it-pretty - Improve readability"
echo " - /test - Add tests before refactoring"
echo " - /review - Include complexity in reviews"
echo ""
echo "View report: cat $REPORT"
echo "View patterns: cat $ANALYSIS_DIR/refactoring-patterns.md"
Safety Guarantees
What I'll NEVER do:
- Automatically refactor without analysis
- Remove logic without understanding
- Skip testing after refactoring
- Break existing functionality
- Add AI attribution to commits
What I WILL do:
- Identify high-complexity functions
- Suggest proven refactoring patterns
- Provide clear examples
- Recommend incremental changes
- Preserve functionality
- Create clear documentation
Credits
This skill is based on:
- Thomas J. McCabe - Cyclomatic complexity metric (1976)
- Martin Fowler - Refactoring patterns and principles
- ESLint - JavaScript complexity rules
- Radon - Python complexity analysis
- gocyclo - Go cyclomatic complexity
- Code quality research - Industry best practices
Token Budget
Target: 2,500-4,000 tokens per execution
- Phase 1-2: ~800 tokens (detection + tool setup)
- Phase 3: ~1,200 tokens (complexity analysis)
- Phase 4-5: ~1,500 tokens (patterns + reporting)
Optimization Strategy:
- Use Grep for language detection
- Leverage existing tools (ESLint, radon, gocyclo)
- Template-based pattern generation
- Focused analysis on high-complexity functions
- Clear, actionable recommendations
This ensures thorough complexity analysis with practical refactoring guidance while respecting token limits and maintaining code quality.