feat: migrate commands to skills

This commit is contained in:
duthaho
2026-04-19 10:55:51 +07:00
parent 09538078e7
commit 70e258e1dc
62 changed files with 1880 additions and 4492 deletions
+113
View File
@@ -0,0 +1,113 @@
---
name: refactoring
argument-hint: "[file or function]"
description: >
Use when improving code structure, readability, or maintainability without changing behavior. Trigger for keywords like "refactor", "clean up", "extract", "simplify", "rename", "restructure", "code smell", "technical debt", "DRY", or any request to improve code quality without adding features. Also activate when code reviews identify structural issues, when functions are too long, or when duplication needs elimination.
---
# Refactoring
## When to Use
- Improving code structure without changing behavior
- Extracting reusable functions or components
- Eliminating code duplication
- Reducing complexity (long functions, deep nesting)
- Renaming for clarity
- Addressing code review feedback about structure
## When NOT to Use
- Adding new features — use `feature-workflow`
- Fixing bugs — use `systematic-debugging` (behavior change, not refactoring)
- Performance optimization — use `performance-optimization`
---
## Quick Reference
| Topic | Reference | Key content |
|-------|-----------|-------------|
| Refactoring patterns | `references/patterns.md` | Extract, inline, rename, move, decompose, introduce parameter object |
| Code smells | `references/code-smells.md` | Detection signals and recommended refactorings |
---
## Safe Refactoring Workflow
1. **Ensure tests pass** before any change
2. **Make one small, behavior-preserving change** at a time
3. **Run tests after each change**
4. **Commit each successful step** independently
5. **Use type checkers** (mypy/tsc) as a secondary safety net
6. **Never mix refactoring with feature/bug changes** in the same commit
---
## Core Patterns
| Pattern | When | Example |
|---------|------|---------|
| Extract function | Long function, repeated logic | Pull 10-line block into named function |
| Inline function | Trivial wrapper adding no clarity | Remove `getAge()` that just returns `this.age` |
| Rename symbol | Name doesn't reveal intent | `x``userCount` |
| Introduce parameter object | 4+ related parameters | `(name, email, age)``UserInput` |
| Replace conditional with polymorphism | Long if/else or switch chains | Strategy pattern or subclass dispatch |
| Decompose conditional | Complex boolean expression | `isEligible()` instead of `age > 18 && !banned && verified` |
| Extract variable | Complex expression | `const isOverBudget = total > limit * 1.1` |
---
## Code Smell Signals
- **Long function** (>20-30 lines)
- **Long parameter list** (>3-4 params)
- **Duplicated logic** across multiple locations
- **Deep nesting** (>3 levels)
- **Feature envy** — function uses another class's data more than its own
- **Shotgun surgery** — one change requires edits in many files
- **Primitive obsession** — raw strings/dicts instead of typed objects
- **Dead code** — unreachable or unused functions/imports
---
## Python-Specific
- Convert `dict` bags to **dataclasses** or **TypedDict**
- Add **type hints** progressively
- Replace loops with **comprehensions** where clearer
- Use **`@property`** instead of get/set methods
- Use **`Enum`** instead of string constants
## TypeScript-Specific
- Use **discriminated unions** instead of class hierarchies
- Replace `any` with **generics** or **`unknown`** + narrowing
- Replace enums with **`as const`** objects for tree-shaking
- Extract **utility types** (`Pick`, `Omit`, `Partial`)
---
## Best Practices
1. **Rule of three** — extract on the third duplication, not the first.
2. **Tests are the safety net** — never refactor without them.
3. **Small steps** — one rename is better than a big-bang rewrite.
4. **Preserve interfaces** — change internals, not public APIs (unless that's the goal).
5. **Use IDE tooling** — automated rename/move updates all references.
## Common Pitfalls
1. **Refactoring without tests** — no safety net to catch regressions.
2. **Mixing refactoring with features** — makes it impossible to identify behavior changes.
3. **Premature abstraction** — extracting patterns before duplication exists.
4. **Too-large refactors** — big-bang rewrites instead of incremental steps.
5. **Breaking public interfaces** — changing signatures without updating callers.
---
## Related Skills
- `testing` — Ensure test coverage before refactoring
- `languages` — Language-specific idioms and patterns
- `writing-concisely` — Refactoring responses can be terse (show before/after)
@@ -0,0 +1,32 @@
# Code Smells Detection Guide
## Smell → Refactoring Map
| Smell | Signal | Refactoring |
|-------|--------|-------------|
| Long function | >20-30 lines | Extract function |
| Long parameter list | >3-4 params | Introduce parameter object |
| Duplicated logic | Same code in 3+ places | Extract function, DRY |
| Deep nesting | >3 levels of indentation | Early return, extract function |
| Feature envy | Uses another class's data more than its own | Move method to the class with the data |
| Shotgun surgery | One change → edits in many files | Move related code together |
| Primitive obsession | Raw strings/dicts instead of types | Introduce dataclass/interface |
| Dead code | Unreachable or unused | Delete it (git has history) |
| God class | Class does too many things | Extract class by responsibility |
| Comments as deodorant | Comments explaining messy code | Refactor the code to be clear |
## Python-Specific Smells
- `dict` used as a struct → use `@dataclass` or `TypedDict`
- Missing type hints on public functions
- Manual `__init__` boilerplate → `@dataclass`
- String constants → `Enum`
- Getter/setter methods → `@property`
## TypeScript-Specific Smells
- `any` type → `unknown` + narrowing or generics
- Enum → `as const` object (better tree-shaking)
- Class hierarchy for variants → discriminated union
- Interface duplication → utility types (`Pick`, `Omit`, `Partial`)
- Index as key in lists → stable unique ID
@@ -0,0 +1,93 @@
# Refactoring Patterns
## Extract Function
Pull cohesive logic into a named function.
```python
# Before
def process_order(order):
# validate
if not order.items:
raise ValueError("Empty order")
if order.total < 0:
raise ValueError("Negative total")
# ... 50 more lines
# After
def validate_order(order):
if not order.items:
raise ValueError("Empty order")
if order.total < 0:
raise ValueError("Negative total")
def process_order(order):
validate_order(order)
# ... rest of processing
```
## Introduce Parameter Object
Group 4+ related parameters into a single object.
```typescript
// Before
function createUser(name: string, email: string, age: number, role: string) { ... }
// After
interface CreateUserInput {
name: string;
email: string;
age: number;
role: string;
}
function createUser(input: CreateUserInput) { ... }
```
## Replace Conditional with Polymorphism
```typescript
// Before
function getPrice(type: string, base: number): number {
if (type === 'premium') return base * 0.8;
if (type === 'bulk') return base * 0.7;
return base;
}
// After
const pricingStrategies: Record<string, (base: number) => number> = {
premium: (base) => base * 0.8,
bulk: (base) => base * 0.7,
standard: (base) => base,
};
function getPrice(type: string, base: number): number {
return (pricingStrategies[type] ?? pricingStrategies.standard)(base);
}
```
## Decompose Conditional
```python
# Before
if age > 18 and not banned and verified and subscription_active:
grant_access()
# After
def is_eligible(user):
return user.age > 18 and not user.banned and user.verified and user.subscription_active
if is_eligible(user):
grant_access()
```
## Extract Variable
```typescript
// Before
if (order.total > 100 && order.items.length > 5 && !order.hasDiscount) { ... }
// After
const isLargeOrder = order.total > 100 && order.items.length > 5;
const qualifiesForDiscount = isLargeOrder && !order.hasDiscount;
if (qualifiesForDiscount) { ... }
```