Code Simplifier Skill Review — Cleaning Up Code Without Breaking Things
The code-simplifier is one of those skills that sounds trivial — "make code cleaner" — but gets fiendishly complex the moment you try to mechanize it. How do you teach an AI agent to simplify code without breaking it? Which patterns should it catch, and which should it leave alone? And most importantly: when you already have a working skill, is it worth looking at someone else's version?
We set out to answer these questions by comparing two implementations: the original Anthropic Claude Code plugin and our adapted Hermes version. The results were both reassuring and surprising.
The Source Material
Two implementations, same goal:
Anthropic's Claude Code Plugin — Lives at anthropics/claude-plugins-official. It's a system prompt for Claude Opus, roughly 80 lines, designed to run autonomously after every code change. The prompt defines five principles: preserve behavior, apply project standards, enhance clarity, maintain balance, and focus scope. It's terse, imperative, and assumes the agent already knows the codebase conventions through CLAUDE.md.
Our Hermes Adaptation — A full skill document (~300 lines) that expands each principle into concrete patterns with code examples in TypeScript, Python, and React. It adds Chesterton's Fence as an explicit pre-step, provides pattern tables for structural complexity and naming issues, defines a step-by-step process (Understand → Identify → Apply → Verify), and includes a "Common Rationalizations" section that preempts the excuses developers make for skipping simplification.
What the Claude Version Does Better
The Anthropic version has one trick we don't: autonomous triggering. It's designed to run as a post-write hook — every time Claude Code modifies a file, the simplifier immediately reviews and refines it. This tight feedback loop means complexity never accumulates; it's removed in the same session it was introduced.
Our version, by contrast, is a skill you have to invoke explicitly. That's fine for planned refactoring sessions but misses the "clean as you go" philosophy. If you write 200 lines of working-but-messy code, nobody's going to stop and say "let me load the code-simplification skill now." The mess ships with the feature.
What to borrow: A lightweight post-task simplification pass. Not a separate skill invocation, but a built-in behavior after any code generation task of non-trivial size. The agent should ask itself: "Did I just add complexity that could be simplified before calling this done?"
What Our Version Does Better
Our skill is just more useful in practice. The Anthropic prompt is elegant but under-specified — it tells the model what to do but not how. "Reduce unnecessary complexity" is a good principle but a terrible instruction. Our version provides pattern tables with concrete examples:
- "Deep nesting (3+ levels) → extract conditions into guard clauses"
- "Generic names like
dataorresult→ rename to describe content" - "Function named
getthat also mutates → rename to reflect behavior"
These aren't just heuristics; they're decision shortcuts. The agent doesn't have to reason from first principles every time — it pattern-matches against a known catalog.
The Chesterton's Fence pre-step is also genuinely novel (neither implementation had it originally — we added it during adaptation). Before touching anything: check git blame, read the original PR, understand why this code exists in this shape. This prevents the single most common simplification failure mode: removing complexity that was there for a reason you didn't understand.
Testing Both Against Real Code
We tested both implementations against a real codebase — a FastAPI service with accumulated complexity from six months of feature work. The patterns we fed in:
| Pattern | Claude Version | Our Version |
|---|---|---|
| Nested if-else with 4 levels of depth | Caught, flattened to guard clauses | Caught, plus suggested specific error types |
| Magic string used in 7 places | Suggested constant, kept old naming | Extracted to enum with descriptive names |
data variable used for 4 different types |
Missed (pattern too vague) | Caught, split into typed variables |
Redundant await in return statement |
Caught, removed | Caught, removed |
| Over-engineered strategy pattern with one strategy | Missed entirely | Flagged for review, suggested inlining |
The difference comes down to specificity. Our version's pattern tables give the agent concrete things to look for, not just abstract principles to apply.
Should We Adopt the External Version?
No — but we should borrow one thing.
Our skill already covers everything the Anthropic version covers and more. The pattern tables, Chesterton's Fence, and language-specific examples make it more actionable. What we're missing is the autonomous trigger: the habit of asking "can this be simpler?" as a built-in post-task reflex, not a separate skill invocation.
The simplest path: add a "simplification check" to our existing coding skill pipeline. After any code generation task of 50+ lines, the agent does a one-minute scan for the top three simplification patterns (deep nesting, generic names, redundant constructs). If it finds nothing, great. If it finds something, it flags it — not as a separate refactoring pass, but as a "one more thing before we call this done."
Verdict
Keep our version. It's objectively better for our use case — more specific, more actionable, better documented. Borrow the autonomous trigger pattern from Anthropic and bake it into the coding workflow. A good simplification habit beats a great simplification skill that nobody remembers to invoke.