When to use this
- Before a refactor sprint, to prioritize which files/functions to touch first.
- When "this file feels like a mess" needs a concrete ranking instead of a vibe.
- Not a replacement for a real static-analysis tool (radon, eslint complexity rule, gocyclo) where one is already configured -- use those numbers if they exist, this skill for repos without one.
The skill file
Copy this verbatim. It's written in the SKILL.md format (YAML frontmatter + markdown instructions) that Claude Code, and increasingly other agent tools, read directly.
--- name: complexity-analyzer description: Rank functions/files by structural complexity (branching, nesting, length) combined with churn (how often they change) to prioritize refactoring effort. Use when asked to find "the worst code" or prioritize cleanup, not for a single-file review. --- # Complexity Analyzer ## Signal 1: structural complexity For each function, estimate (don't need to be exact): - Branch count (if/else, switch/match, ternary, loop conditions, `&&`/`||` short-circuits used as control flow). - Max nesting depth. - Length in lines, as a tiebreaker only -- a long function with no branching (e.g. a data literal) is not complex. ## Signal 2: churn `git log --format=%H -- <path>` (or per-function if the tool supports it) to count how many commits touched the file in a recent window (e.g. last 6 months). A complex function nobody touches is stable risk; a complex function that changes every week is where bugs are actually born. ## Combine and rank Complexity x churn, roughly -- a function that's both tangled and frequently edited outranks one that's tangled but frozen. Present as a ranked list, top 10-15, not an exhaustive audit of the whole repo. ## Output format Table: function/file, complexity estimate, recent commit count, one-line reason it made the list. End with which 2-3 are worth tackling first and why (usually: highest churn among the high-complexity set).
Installing it elsewhere
The frontmatter/body split above is Claude Code's convention. Here's how to carry the same instructions into other tools:
Save the file below verbatim (frontmatter included) at that path, project-local or in ~/.claude/skills/ for a user-level skill. Claude Code loads the name/description pair to decide when to pull it in, or you invoke it directly as /complexity-analyzer.
Convert the YAML frontmatter to Cursor's rule format (description, globs, alwaysApply: false) and keep the markdown body as the rule content. Cursor surfaces it by description match, same idea as Claude Code's auto-load.
Codex CLI (and increasingly other agentic CLIs) read AGENTS.md at the repo root as always-on instructions. Paste the markdown body under a heading like ## {title}; for GitHub Copilot's coding agent, the equivalent file is .github/copilot-instructions.md.
Append the markdown body to .windsurfrules at the repo root. Windsurf treats the whole file as always-on context, so keep only the instructions you want applied on every request.
- Ranking by complexity alone and surfacing dead, never-touched legacy code as the top priority -- churn is what makes it worth fixing now.
- Counting generated code or vendored files in the ranking.
- Treating a long switch statement that maps one enum to one string as "complex" -- it has branches but no actual decision-making risk.