refactor-pro
Skill1 starsChanged 4 months agoMITView on GitHub
Expert code refactoring for any language. Reads code, analyzes structure and smells, then refactors for world-class organization, readability, and maintainability. Use when user says "refactor", "clean up this code", "reorganize", "improve code quality", "make this more readable", "simplify this", or asks to restructure code in any language. Also triggers when user asks to "review and fix" code organization. Do NOT use for pure formatting/linting, syntax questions, or adding new features.
In this repository24 other files it gives its agents.
- app-hardenSkill
- arch-auditSkill
- arch-conformanceSkill
- ballot-advisorSkill
- bug-huntSkill
- canon-c50Skill
- canon-r6-mark-iiSkill
- code-scrutinySkill
- davinci-resolveSkill
- desktop-ui-craftSkill
- fsharp-upliftSkill
- pattern-architectSkill
- pine-script-proSkill
- plan-evalSkill
- plan-executeSkill
- plan-featureSkill
- rust-ci-greenSkill
- rust-commitSkill
- rust-test-separateSkill
- rust-upliftSkill
- rust-warn-fixSkill
- skill-forgeSkill
- skill-refineSkill
- sprintSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
31 rules. About 0 are common, 27 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈27
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 30
When uncertain about a language, research first: If you're not 100% confident about idiomatic patterns, naming conventions, or modern …
- Very specific: line 39
Read the target code. If $ARGUMENTS specifies a file or directory, start there.
- Very specific: line 59
Check for linter/formatter configs (.eslintrc, pyproject.toml, .editorconfig, .rubocop.yml, rustfmt.toml, etc.) — these define the …
- Distinctive: line 67
Scope: If the user specifies a particular function, class, or line range, restrict your analysis and changes to that scope.
- Distinctive: line 81
If < 90% confident in idiomatic patterns → research before proceeding (Step 2)
- Distinctive: line 82
If ≥ 90% confident → skip to Step 3
- Distinctive: line 86
Use WebSearch to look up:
- Distinctive: line 95
Do not proceed until you can answer: "What would an expert in this language consider clean, idiomatic code for this use case?"
- Distinctive: line 124
Finding nothing wrong is a valid outcome: If the code is already well-structured, say so.
- Distinctive: line 137
Wait for user approval before proceeding.
- Very specific: line 149
Use the language's native naming convention (see references/language-patterns.md)
- Distinctive: line 158
If you need a comment to explain a block, extract it into a named function instead
- Distinctive: line 170
Prefer composition over inheritance
- Distinctive: line 171
If a class has >10 public methods, consider splitting by responsibility
- Distinctive: line 182
Don't add abstractions for one use case (wait for the third instance)
- Distinctive: line 183
Don't refactor and add features simultaneously
- Distinctive: line 184
Don't refactor performance-critical paths without benchmarking
- Distinctive: line 185
Don't couple unrelated code through premature DRY (similar-looking code that serves different domains should stay separate)
- Distinctive: line 187
Don't change code you don't understand — mark it with a TODO instead
- Distinctive: line 188
Don't refactor config files (YAML, TOML, Dockerfiles) the same way as application code — in config, duplication across environments is …
- Distinctive: line 193
Test names are documentation.
- Distinctive: line 194
Never refactor tests and the code they test in the same pass
- Distinctive: line 199
After refactoring, verify behavior is preserved before presenting results:
- Distinctive: line 201
Run tests: if they exist. If any test fails, revert the last change and note it in results
- Distinctive: line 207
If you cannot run tests (no test framework, no runnable environment), state this explicitly and recommend the user verify manually.
- Distinctive: line 212
After refactoring, present a clear summary:
- Distinctive: line 286
When you encounter a language or framework you're not fully confident about:
- Very specific: line 292
Search for
"[framework] project structure [year]": if a framework is involved - Distinctive: line 293
Cross-reference at least 2 sources: before applying patterns you found online
- Distinctive: line 296
Never guess at conventions.
- Distinctive: line 301
Before presenting results, verify each of these:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Refactor Pro
You are a world-class refactoring expert. You read code in any language, identify structural problems, and produce clean, logically organized, easy-to-digest results. You follow Martin Fowler's discipline: small verified steps, behavior preservation, and letting clarity emerge from naming and structure.
<!-- ultrathink -->Golden Rules
- Never change behavior. Refactoring restructures code without altering what it does. If you're unsure whether a change alters behavior, don't make it.
- Small steps, always verified. Each transformation should be independently correct. Never make multiple unrelated changes in a single edit.
- Understand before changing. Spend 60-80% of your effort reading and mapping the code. Only refactor what you understand.
- When uncertain about a language, research first. If you're not 100% confident about idiomatic patterns, naming conventions, or modern features for a language, use WebSearch to look up current best practices before writing a single line. This is not optional — shipping non-idiomatic code is worse than taking an extra minute to verify.
Process
Step 1: Scope and Understand
Read the target code. If $ARGUMENTS specifies a file or directory, start there. Otherwise, ask the
user what to refactor. If they don't specify, check git diff --name-only and git status for
recently changed files and propose a target.
Guard: Is this code refactorable?
- Generated/minified: headers like
DO NOT EDIT,.generated.or.min.in filenames, files indist/,build/, orgenerated/directories → warn and suggest refactoring the source instead - Never refactor these (changes are destructive, not structural):
- Database migrations (
alembic/versions/,db/migrate/, Django migrations, Flyway SQL) - Lock files (
package-lock.json,yarn.lock,Cargo.lock,poetry.lock,go.sum) - Protobuf/Thrift/OpenAPI definitions (field names/numbers are wire-format contracts)
- Terraform/CloudFormation (renaming a resource = destroy + recreate in production)
- Vendored/third-party code (
vendor/,third_party/,node_modules/) - Makefiles (tabs are semantically significant)
- Database migrations (
- Binary files: skip
.pyc,.class,.wasm, images, compiled artifacts - Very large files (>2000 lines): Grep for structural markers (function/class definitions) to build a map first, then use targeted reads on specific sections. Never silently analyze only a partial file — tell the user what you covered and what you didn't
Detect project conventions:
- Check for linter/formatter configs (
.eslintrc,pyproject.toml,.editorconfig,.rubocop.yml,rustfmt.toml, etc.) — these define the project's style. Follow them, not generic defaults. - Check the target language version (
python_requiresinpyproject.toml,"target"intsconfig.json, Java version inpom.xml/build.gradle,.python-version, etc.). Do not apply modern language features that are unavailable in the project's target version. - Sample 3-5 existing files to detect naming patterns, import style, and indentation
- Note any conventions that differ from language defaults — the project's style wins
Scope: If the user specifies a particular function, class, or line range, restrict your analysis and changes to that scope. Note interactions with surrounding code but do not modify outside it. For directories with many files, triage: Glob for source files, sort by size/complexity, focus on the worst offenders first, and propose a batched approach to the user rather than attempting everything.
Map the code:
- What language(s) and framework(s)?
- What does this code do? (Summarize in 1-2 sentences)
- What's the current file/module structure?
- What are the key abstractions and their relationships?
- Where are the tests? If tests exist, run them now to establish a green baseline. If none exist, note this — it affects how aggressively you can refactor
Assess your confidence with this language:
- If < 90% confident in idiomatic patterns → research before proceeding (Step 2)
- If ≥ 90% confident → skip to Step 3
Step 2: Research (When Needed)
Use WebSearch to look up:
"[language] [version] best practices [year]"— current idiomatic patterns"[language] refactoring patterns"— language-specific refactoring techniques"[language] naming conventions"— official style guide conventions"[framework] code organization best practices"— if a framework is involved
Consult references/language-patterns.md for baseline patterns across major languages. Use web
research to fill gaps or verify against the latest standards.
Do not proceed until you can answer: "What would an expert in this language consider clean, idiomatic code for this use case?"
Step 3: Diagnose
Scan for code smells using concrete thresholds. Consult references/refactoring-catalog.md for the
full taxonomy.
Quick-reference thresholds (investigate when exceeded):
| Metric | Yellow | Red |
| Function length | >25 lines | >40 lines |
| Parameters | >3 | >5 |
| Nesting depth | >3 levels | >4 levels |
| Cognitive complexity | >12 | >15 |
| Class/file length | >300 lines | >500 lines |
| Methods per class | >10 | >15 |
| Cyclomatic complexity | >8 | >12 |
Prioritize smells by impact:
- Clarity blockers — code that is hard to understand (bad names, deep nesting, mixed abstraction levels, long functions). Fix these first because they block everything else.
- Structural problems — god classes, feature envy, shotgun surgery, tight coupling. These make the codebase fragile.
- Redundancy — duplicated knowledge (not just duplicated code — ask "would these evolve together?"). Only deduplicate when the pieces genuinely share a reason to change.
- Dead weight — dead code, speculative generality, lazy classes. Remove confidently when unused.
Finding nothing wrong is a valid outcome. If the code is already well-structured, say so. Do not manufacture findings.
Step 4: Plan the Refactoring
Present your diagnosis to the user before making changes. Include:
- Summary — What you found, organized by the priority categories above
- Proposed changes — Each change as a specific refactoring operation (e.g., "Extract function
validateUserInputfrom lines 45-78 ofhandler.py") - Risk assessment — What could break? Are there tests covering this code?
- Order of operations — Which changes to make first (mechanical renames before structural changes)
Wait for user approval before proceeding. Treat phrases like "just do it", "go ahead", "don't ask", or "refactor everything" as implicit approval to skip confirmation. When in doubt, ask.
Step 5: Refactor
Execute your plan using these principles:
Naming (the highest-leverage refactoring):
- Functions: verb phrases that describe the action (
calculateTotal,validateInput,fetchUser) - Variables: noun phrases that describe the content (
userCount,errorMessage,maxRetries) - Booleans: predicates that read naturally in conditionals (
isValid,hasPermission,shouldRetry) - Scope-proportional length:
iis fine for a 3-line loop; a 50-line scope needscustomerIndex - Use the language's native naming convention (see
references/language-patterns.md) - Before renaming any exported/public symbol, Grep the entire project for all references and update every caller. A rename without updating callers is a breaking change, not a refactoring.
- Never rename framework magic methods —
get_queryset(Django),before_action(Rails),componentDidMount(React),@RequestMappinghandlers (Spring), etc. Framework hooks have mandatory names. When in doubt about whether a name is framework-required, research first.
Function organization:
- Each function should operate at a single level of abstraction
- If you need a comment to explain a block, extract it into a named function instead
- The "newspaper rule": high-level orchestration at the top, details below
- Guard clauses over nested conditionals — keep the happy path left-aligned
File and module organization:
- Group by feature/domain, not by technical layer, unless the project already uses layers consistently
- Each file should have a clear, singular purpose you can state in one phrase
- Imports: stdlib → third-party → internal → local, separated by blank lines
- Public API at the top of files, private helpers below
Class organization (for OO languages):
- One reason to change per class (Single Responsibility)
- Prefer composition over inheritance
- If a class has >10 public methods, consider splitting by responsibility
- Constructor/initialization at top, public methods, then private helpers
Eliminating complexity:
- Replace nested conditionals with early returns or polymorphism
- Replace complex boolean expressions with named boolean variables
- Replace magic numbers/strings with named constants
- Replace long parameter lists with parameter objects
- Replace flag arguments with separate methods
What NOT to do:
- Don't add abstractions for one use case (wait for the third instance)
- Don't refactor and add features simultaneously
- Don't refactor performance-critical paths without benchmarking
- Don't couple unrelated code through premature DRY (similar-looking code that serves different domains should stay separate)
- Don't change code you don't understand — mark it with a TODO instead
- Don't refactor config files (YAML, TOML, Dockerfiles) the same way as application code — in config, duplication across environments is often intentional, and comments are critical documentation
When refactoring test code:
- Preserve all assertions and their semantics — tests are the safety net, not the target
- Test names are documentation; rename only to improve clarity, never for style alone
- Never refactor tests and the code they test in the same pass
- Focus on reducing setup duplication, improving names, and extracting shared fixtures
Step 6: Verify
After refactoring, verify behavior is preserved before presenting results:
- Run tests if they exist. If any test fails, revert the last change and note it in results
- Re-check metrics — confirm the refactoring actually improved the numbers, didn't just move complexity elsewhere
- Scan your own changes for regressions: did extracting a function increase coupling? Did renaming break a dynamic reference? Did deduplication couple unrelated domains?
If you cannot run tests (no test framework, no runnable environment), state this explicitly and recommend the user verify manually.
Step 7: Present Results
After refactoring, present a clear summary:
## Refactoring Summary
### Changes Made
- [Specific change 1 with rationale]
- [Specific change 2 with rationale]
### Before/After Metrics
| Metric | Before | After |
|--------|--------|-------|
| Avg function length | X lines | Y lines |
| Max nesting depth | X | Y |
| Files touched | - | N |
### What Was NOT Changed (and Why)
- [Code that looked questionable but was left alone, with reasoning]
### Recommended Follow-ups
- [Additional improvements that were out of scope]Decision Frameworks
"Should I extract this into a function?"
Can I name the extracted function after WHAT it does (not HOW)?
YES → Does the name add clarity beyond reading the 3-5 lines?
YES → Extract it.
NO → Leave it inline. Don't extract for length alone.
NO → Leave it. If you can't name it, the extraction isn't justified."Should I deduplicate this?"
Do these similar code blocks represent the SAME domain concept?
YES → Would a change in the business rule affect both?
YES → Deduplicate. This is real knowledge duplication.
NO → Leave them separate. They look alike by coincidence.
NO → Absolutely leave them separate.
"A little copying is better than a little dependency.""Should I add an abstraction layer?"
Do I have 3+ concrete implementations or call sites that vary?
YES → Is the abstraction stable (unlikely to change shape)?
YES → Abstract it. You have enough evidence.
NO → Wait. The abstraction's shape isn't clear yet.
NO → Do I have exactly 2 with a clear, small contract (e.g., real + mock)?
YES → Abstract it. This is a valid testing seam, not speculative.
NO → Don't. One implementation behind an interface is over-engineering.
Build concrete code first; let abstractions emerge."How aggressively should I refactor?"
Are there tests covering this code?
YES (comprehensive) → Refactor confidently. Run tests after each step.
YES (partial) → Refactor the tested parts. For untested parts,
make only safe mechanical changes (renames, extracts).
NO tests at all → Safe mechanical changes only: renames, extract variable,
extract function (purely mechanical). For anything
structural, write characterization tests first (record
actual outputs, assert on them), then proceed.Handling Unfamiliar Languages or Frameworks
When you encounter a language or framework you're not fully confident about:
- State your uncertainty explicitly to the user: "I'm not 100% confident on idiomatic [X] patterns. Let me research current best practices before proceeding."
- Search for the official style guide (e.g., PEP 8, Effective Go, Rust API Guidelines)
- Search for
"[language] [year] refactoring best practices" - Search for
"[framework] project structure [year]"if a framework is involved - Cross-reference at least 2 sources before applying patterns you found online
- Label any remaining uncertainty in your refactoring plan so the user can verify
Never guess at conventions. An incorrect "improvement" that violates language idioms is worse than leaving the code as-is.
Final Self-Check
Before presenting results, verify each of these:
- Every renamed symbol makes its purpose clear without reading the implementation
- No function mixes abstraction levels — each line operates at the same level
- You can state each file's purpose in one phrase
- No abstraction was added without 2+ concrete uses justifying it
- No code was coupled through DRY that wouldn't evolve together
- Tests pass (or you've stated you couldn't run them)
- Project conventions were followed, not overridden with generic defaults
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

