refactor-clean
Use when code has grown complex, duplicated, or cluttered — clean up structure and remove dead code without changing observable behavior
Best use case
refactor-clean is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when code has grown complex, duplicated, or cluttered — clean up structure and remove dead code without changing observable behavior
Teams using refactor-clean should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/refactor-clean/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How refactor-clean Compares
| Feature / Agent | refactor-clean | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when code has grown complex, duplicated, or cluttered — clean up structure and remove dead code without changing observable behavior
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Refactor & Clean Code
## When to Use
- Code is correct but hard to read, modify, or extend
- Duplicated logic exists across multiple files
- Functions or classes have grown too large
- Preparing code for a new feature that requires structural changes
- After a rapid prototype that needs production-quality cleanup
## Prerequisites
- Existing tests that cover the code to refactor (add tests first if missing)
- All tests passing before starting
- Code committed so you can revert if needed
## Workflow
### 1. Identify Code Smells
```powershell
# Find long files (likely doing too much)
Get-ChildItem -Recurse -Include *.ts,*.js,*.py,*.go | Where-Object { (Get-Content $_.FullName | Measure-Object -Line).Lines -gt 300 } | Select-Object FullName, @{N='Lines';E={(Get-Content $_.FullName | Measure-Object -Line).Lines}}
# Find duplicated string patterns
grep -rn "pattern-you-suspect-is-duplicated" src/ --include="*.ts"
# Find functions with too many parameters (>4 is a smell)
grep -n "function.*,.*,.*,.*," src/**/*.ts
```
Common smells to look for:
- **Long functions** (>40 lines) — extract smaller functions
- **Duplicate code** — extract shared utility
- **Deep nesting** (>3 levels) — use early returns or extract
- **God objects** — split into focused classes/modules
- **Primitive obsession** — introduce domain types
- **Feature envy** — move logic to the class that owns the data
### 2. Establish a Safety Net
```powershell
# Run existing tests and record baseline
npm test 2>&1 | Tee-Object -Variable baseline
echo $baseline | Select-Object -Last 5
# If coverage is low, write characterization tests first
npm test -- --coverage --collectCoverageFrom="src/module-to-refactor.ts"
```
### 3. Plan the Refactoring
Before touching code, decide on the transformation:
- **Extract Function** — pull a block into a named function
- **Extract Module** — move related functions to a new file
- **Rename** — improve names for clarity
- **Inline** — remove unnecessary indirection
- **Replace Conditional with Polymorphism** — use strategy pattern
- **Introduce Parameter Object** — group related parameters
### 4. Make Small, Incremental Changes
Each change should be:
1. A single refactoring operation
2. Followed by running tests
3. Committed if tests pass
```powershell
# After each refactoring step
npm test 2>&1 | Select-Object -Last 10
# If tests break, revert and try a smaller step
git checkout -- src/module-to-refactor.ts
```
### 5. Verify Behavior is Preserved
```powershell
# Full test suite must still pass
npm test
# Compare coverage — it should not decrease
npm test -- --coverage
```
## Examples
### Extract Repeated Logic
```typescript
// BEFORE: duplicated validation in multiple handlers
function createUser(data) {
if (!data.email || !data.email.includes('@')) throw new Error('Invalid email');
// ... create logic
}
function updateUser(data) {
if (!data.email || !data.email.includes('@')) throw new Error('Invalid email');
// ... update logic
}
// AFTER: extracted to a shared validator
function validateEmail(email: string): void {
if (!email || !email.includes('@')) throw new Error('Invalid email');
}
function createUser(data) { validateEmail(data.email); /* ... */ }
function updateUser(data) { validateEmail(data.email); /* ... */ }
```
### Flatten Deep Nesting with Early Returns
```typescript
// BEFORE
function process(input) {
if (input) {
if (input.isValid) {
if (input.data.length > 0) {
return transform(input.data);
}
}
}
return null;
}
// AFTER
function process(input) {
if (!input || !input.isValid || input.data.length === 0) return null;
return transform(input.data);
}
```
## Common Rationalizations
| Rationalization | Reality |
|----------------|---------|
| "I'm not sure what this code does, but it looks unused" | If you're not sure, don't remove it. Use `git blame` to understand the context first. (Chesterton's Fence) |
| "I'll add a feature while refactoring" | Separate refactoring from feature work. Mixing the two makes debugging impossible. |
| "Tests still pass, so the refactor is correct" | Tests must exist before refactoring to have any meaning. If not, write them first. |
| "TypeScript isn't warning, so it's safe to delete" | Dynamic imports, reflection, and external references are invisible to the type system. |
## Red Flags
- Refactoring commit contains feature changes
- Dead code removed without any tests
- Type errors suppressed with `// @ts-ignore` or `any` types
- No verification that the same tests pass before and after refactoring
- Complex code left with "clean up later" TODO and no action
## Verification
- [ ] `npm test` passes identically before and after the refactor
- [ ] Removed code confirmed as unused (`grep -rn` or IDE reference search)
- [ ] Complexity metrics improved (reduced function length, nesting depth)
- [ ] Refactor commit contains no feature changes (commit message: `refactor:`)
- [ ] PR describes the motivation for the refactor (why this code was cleaned up)
## Tips
- **Never refactor and add features in the same commit** — keep them separate
- Use `explore` agent to understand call graphs before renaming or moving functions
- Use `grep` to find all callers before changing a function signature
- If tests are missing, write them first — refactoring without tests is gambling
- Commit after every successful small refactoring — you can always squash later
- The best refactoring is deleting code: look for dead code with `grep` and remove itRelated Skills
verification-before-completion
Use before claiming any task is done — run the exact command that proves the fix works, read the output, and only then report success.
using-git-worktrees
Use when you need multiple branches checked out at once — create isolated working directories for parallel development without cloning the repository repeatedly
triage
Use when a single issue needs structured triage — classify it, reproduce if needed, request missing information, and leave a durable brief or close-out note in the tracker.
to-issues
Use when a plan, spec, or PRD must become an actionable backlog — break it into thin dependency-aware issues that each deliver a verifiable vertical slice
sprint-workflow
Use when starting a new feature, refactor, or multi-step dev task — runs the full sprint cycle (Think → Plan → Build → Review → Test → Ship → Monitor) using Copilot CLI's plan/autopilot modes.
sprint-retro
Use at the end of a sprint to run a data-driven retrospective — analyzes session history and git metrics to surface what shipped, what slowed you down, and concrete improvements.
security-audit
Use when a codebase needs a formal security audit beyond a quick scan — applies OWASP Top 10 and STRIDE threat modeling from a CSO perspective to surface systemic vulnerabilities.
release
Use when a sprint or feature is complete and ready to ship — tags the version, generates GitHub Release notes, runs rollout or smoke verification, and publishes to npm/PyPI/Docker registries.
prompt-optimizer
Use when a rough prompt, vague idea, or task description needs to become a finished copy-pasteable prompt for a chat-based LLM - rewrite it into one ready-to-send prompt with no blanks, no placeholders, and a clear output shape.
outside-voice
Use when you need an independent second opinion before, during, or after implementation — run challenge, consult, or review mode in a direct builder-to-builder voice
llm-wiki
Use when research or domain knowledge keeps getting rediscovered across sessions — build a supplementary markdown wiki that compounds synthesized knowledge without replacing GitHub or committed project guidance
interview-me
Use when a request is underspecified and you need to discover what the user actually wants before writing a plan, spec, or code - ask one question at a time, attach your current hypothesis, and stop only after the intent is explicitly confirmed.