seb1n/refactoring
Improve code quality and maintainability through systematic identification of code smells and application of proven refactoring patterns.
npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill refactoring
This skill guides an AI agent through the disciplined process of restructuring existing code without changing its external behavior. Refactoring improves readability, reduces complexity, and makes the codebase easier to extend and maintain. The agent identifies code smells, proposes targeted refactoring patterns, applies transformations safely, and verifies correctness through tests.
Provide the code you want refactored along with an optional goal such as "reduce complexity," "improve naming," or "break this into smaller functions." The agent will analyze the code, present a refactoring plan, and apply the changes upon approval. You can also point the agent at an entire file or module and ask it to perform a general quality pass.
User Request: "This function is too long and the nested ifs are hard to follow. Refactor it."
Before:
def register_user(payload):
if payload.get("email"):
if "@" in payload["email"]:
if payload.get("password") and len(payload["password"]) >= 8:
user = {"email": payload["email"], "active": True}
db.save(user)
send_welcome_email(user["email"])
log.info(f"User {user['email']} registered")
return user
else:
raise ValueError("Password must be at least 8 characters")
else:
raise ValueError("Invalid email format")
else:
raise ValueError("Email is required")
After:
def register_user(payload):
_validate_payload(payload)
user = _create_user(payload["email"])
_notify_and_log(user)
return user
def _validate_payload(payload):
if not payload.get("email"):
raise ValueError("Email is required")
if "@" not in payload["email"]:
raise ValueError("Invalid email format")
if not payload.get("password") or len(payload["password"]) < 8:
raise ValueError("Password must be at least 8 characters")
def _create_user(email):
user = {"email": email, "active": True}
db.save(user)
return user
def _notify_and_log(user):
send_welcome_email(user["email"])
log.info(f"User {user['email']} registered")
Patterns applied: Extract Method, Flatten Nested Conditionals (guard clauses).
User Request: "Clean up this Express route handler. There's a lot of repetition."
Before:
app.post("/orders", async (req, res) => {
if (!req.body.items || req.body.items.length === 0) {
return res.status(400).json({ error: "Items are required" });
}
if (req.body.items.length > 50) {
return res.status(400).json({ error: "Too many items" });
}
let total = 0;
for (const item of req.body.items) {
total += item.price * item.quantity;
}
if (total > 10000) {
return res.status(400).json({ error: "Order exceeds maximum total" });
}
const order = { items: req.body.items, total: total, status: "pending" };
await db.orders.insert(order);
return res.status(201).json(order);
});
After:
const MAX_ITEMS = 50;
const MAX_ORDER_TOTAL = 10_000;
app.post("/orders", async (req, res) => {
const { items } = req.body;
const validationError = validateOrder(items);
if (validationError) {
return res.status(400).json({ error: validationError });
}
const total = calculateTotal(items);
if (total > MAX_ORDER_TOTAL) {
return res.status(400).json({ error: "Order exceeds maximum total" });
}
const order = await createOrder(items, total);
return res.status(201).json(order);
});
function validateOrder(items?: OrderItem[]): string | null {
if (!items || items.length === 0) return "Items are required";
if (items.length > MAX_ITEMS) return "Too many items";
return null;
}
function calculateTotal(items: OrderItem[]): number {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
async function createOrder(items: OrderItem[], total: number) {
const order = { items, total, status: "pending" as const };
await db.orders.insert(order);
return order;
}
Patterns applied: Extract Method, Replace Magic Number with Named Constant, Destructuring.
validate_email is better than check with a comment explaining what it checks.Take seb1n/refactoring from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.