| name | brokk-code-smells |
| description | Use when asked to find code quality problems, anti-patterns, or technical debt in a codebase - performs systematic smell detection using ripgrep patterns and available language linters |
brokk-code-smells
Overview
Systematically scan a codebase for severe code quality problems using two passes: (1) universal ripgrep pattern matching that works on any language, (2) language-specific linter invocation where tools are available. Report findings ranked by severity.
Prerequisites
rg --version 2>/dev/null || echo "rg MISSING — install before continuing"
If missing: pip install ripgrep / cargo install ripgrep / winget install BurntSushi.ripgrep
Pass 1 — Universal Ripgrep Patterns
Run all of these regardless of language. Pipe through rg --count first to gauge volume, then read samples.
Dead & Abandoned Code
rg -n "TODO|FIXME|HACK|XXX|TEMP|BUG|BROKEN" --count-matches
rg -n "TODO|FIXME|HACK|XXX|TEMP|BUG|BROKEN" -l
Commented-Out Code (heuristic: lines starting with // or # then code-like content)
rg -n "^\s*(//|#)\s*(if |for |while |def |function |class |var |let |const |return )" --count-matches
Magic Numbers (bare numeric literals outside of obvious contexts)
rg -n "\b(0x[0-9a-fA-F]+|[2-9][0-9]{2,})\b" --count-matches
Deeply Nested Code (4+ levels of indentation — 16+ spaces or 4+ tabs)
rg -n "^(\t{4,}| {4,})" --count-matches
Long Files (report files over 500 lines)
rg -c "" | awk -F: '$2 > 500 {print $2, $1}' | sort -rn | head -20
(Windows: pipe to findstr or read output and sort manually)
God Functions (functions longer than ~60 lines — heuristic via line ranges)
rg -n "^(def |function |func |public |private |protected |static )" -l | head -20
Duplicate String Literals (same string appearing 5+ times)
rg -oh '"[^"]{8,}"' | sort | uniq -c | sort -rn | awk '$1>=5' | head -20
Exception Swallowing
rg -n "catch\s*\([^)]*\)\s*\{\s*\}" --type js
rg -n "except\s*:\s*pass" --type py
rg -n "catch\s*\(.*\)\s*\{\s*(//.*\n)?\s*\}" --type java
rg -n "catch\s*\{?\s*_\s*\}" --type go
Hard-Coded Config (URLs, ports, IPs in non-config files)
rg -n "(https?://[a-zA-Z0-9./:-]{10,}|localhost:[0-9]+|127\.0\.0\.1|192\.168\.[0-9]+\.[0-9]+)" \
--glob "!*.{json,yaml,yml,env,config,toml,ini,md}" --count-matches
Copy-Paste Duplication (identical long lines repeated)
rg -oh ".{80,}" | sort | uniq -d | head -20
Pass 2 — Language-Specific Linters
Detect language first:
rg --files | rg -o "\.[^.]+$" | sort | uniq -c | sort -rn | head -10
Then run available tools. Check each with --version before using; skip if absent.
Python
ruff check . --output-format=text 2>/dev/null
pylint **/*.py --output-format=text 2>/dev/null
bandit -r . -ll 2>/dev/null
JavaScript / TypeScript
npx eslint . --format=compact 2>/dev/null
eslint . --format=compact 2>/dev/null
Java
pmd check -d src -R rulesets/java/quickstart.xml -f text 2>/dev/null
java -jar checkstyle.jar -c /google_checks.xml src/ 2>/dev/null
Go
golangci-lint run ./... 2>/dev/null
staticcheck ./... 2>/dev/null
go vet ./... 2>/dev/null
Ruby
rubocop --format=simple 2>/dev/null
PHP
phpstan analyse src --level=5 2>/dev/null
psalm --output-format=compact 2>/dev/null
C# / .NET
dotnet build --verbosity=normal 2>/dev/null | rg -i "warning|error"
dotnet-sonarscanner 2>/dev/null
Rust
cargo clippy -- -W clippy::all 2>/dev/null
C / C++
cppcheck --enable=all --quiet src/ 2>/dev/null
clang-tidy **/*.cpp -- 2>/dev/null
Severity Ranking
Rank findings into three tiers:
Critical (fix soon — runtime risk or high maintenance cost):
- Exception swallowing / empty catch blocks
- Hard-coded credentials or URLs (see also brokk-security-scan)
- God classes/functions (>300 lines / >10 responsibilities)
- Circular dependencies
High (plan to fix — impairs maintainability):
- Deeply nested logic (4+ levels)
- TODO/FIXME blocks in critical paths
- Duplicate code blocks >20 lines
- Magic numbers in business logic
Medium (track — accumulating debt):
- Long files (>500 lines)
- Commented-out code
- Inconsistent naming (see brokk-modeling-inconsistencies)
Output Format
## Code Smells Report
### Critical
| Smell | Location | Detail |
|-------|----------|--------|
| Empty catch | src/auth.py:88 | Swallows all exceptions silently |
### High
| Smell | Location | Detail |
|-------|----------|--------|
### Medium
| Smell | Location | Detail |
|-------|----------|--------|
### Linter Summary
- eslint: 42 warnings, 7 errors
- (tool not found): ruff, pylint
### Top Files by Smell Density
| File | Smell Count |
|------|-------------|
Windows Notes
rg works natively; avoid awk, wc, grep
- Replace
awk -F: '$2 > 500' with: read rg output and filter in your head or use rg -c "" | findstr manually
npx eslint works on Windows as-is
- PowerShell alternative for long files:
rg -c "" | ForEach-Object { $p,$c=$_ -split ":"; if([int]$c -gt 500){$_} }
Common Mistakes
| Mistake | Fix |
|---|
| Running linter on wrong directory | Always run from repo root |
| Reporting every minor warning | Only surface High/Critical; summarise counts for Medium |
| Missing empty catch variations | Run all language variants of the pattern |
| Stopping after Pass 1 | Always attempt Pass 2 even if tools aren't installed — report what's missing |