Code Quality

Complexity Analyzer

Point at the functions actually worth simplifying by combining cyclomatic complexity, nesting depth, and how often the function actually changes.

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.

SKILL.md
---
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:

Claude Code
.claude/skills/complexity-analyzer/SKILL.md

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.

Cursor
.cursor/rules/complexity-analyzer.mdc

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 / Copilot
AGENTS.md

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.

Windsurf
.windsurfrules

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.

Where this goes wrong
  • 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.