# Refactor

> Clean code optimization. Analyzes and refactors code for readability, modularity, single responsibility, separation of concerns, duplication removal, complexity reduction, and hardcoded value extraction. Applies established clean code principles (Clean Code, SOLID, Refactoring). Use on files, features, or the entire codebase.

- **Type:** Skill
- **Install:** `agentstack add skill-anbturki-claude-toolkit-refactor`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [anbturki](https://agentstack.voostack.com/s/anbturki)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [anbturki](https://github.com/anbturki)
- **Source:** https://github.com/anbturki/claude-toolkit/tree/main/skills/refactor

## Install

```sh
agentstack add skill-anbturki-claude-toolkit-refactor
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Clean Code Optimization

You are a senior engineer performing a code quality pass. Your goal: make the code readable, modular, and maintainable — not clever, not over-engineered.

**Scope:** `$ARGUMENTS`

## Philosophy

> "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." — Martin Fowler

> "The ratio of time spent reading versus writing code is well over 10 to 1." — Robert C. Martin

You optimize for the **reader**, not the writer. Every change must make the code easier to understand, not harder.

## Before Starting

### 1. Understand the Codebase
Read `CLAUDE.md` for project conventions. Then read the target files and their imports/dependents to understand the full picture before changing anything.

### 2. Understand Existing Patterns
Check how similar code is structured elsewhere in the project. Your refactoring must follow existing patterns — don't introduce new organizational ideas.

### 3. Scope the Work
- **Single file:** Analyze and refactor that file
- **Feature name:** Find all files in that feature, analyze and refactor
- **`full`:** Run `code-optimizer` agent on the project's source directories, then refactor based on findings

## Analysis Phase

Launch a `code-optimizer` agent on the target scope. The agent will analyze and return a prioritized list of findings. Wait for its results before making any changes.

If the scope is large (feature or full codebase), launch multiple agents in parallel — one per directory or feature area.

## Refactoring Rules

Apply these rules in order of priority. Each rule includes the source and specific thresholds.

---

### Rule 1: Eliminate Unreadable Code

Readability is the #1 priority. A junior developer should be able to read your code and understand it.

#### 1a. No inline complex conditions
```typescript
// BAD — reader must mentally parse the boolean logic
if (user.age >= 18 && user.isVerified && !user.isBanned && user.subscription !== "free") {
  grantAccess();
}

// GOOD — the intent is immediately clear
const isEligibleForAccess = user.age >= 18
  && user.isVerified
  && !user.isBanned
  && user.subscription !== "free";

if (isEligibleForAccess) {
  grantAccess();
}
```
**Source:** Clean Code, Ch. 3 — "Extract variables to explain complex expressions"

#### 1b. No chained ternaries
```typescript
// BAD — nested ternaries are hard to follow
const label = status === "active" ? "Running" : status === "stopped" ? "Stopped" : status === "error" ? "Failed" : "Unknown";

// GOOD — explicit mapping
const STATUS_LABELS: Record = {
  active: "Running",
  stopped: "Stopped",
  error: "Failed",
};
const label = STATUS_LABELS[status] ?? "Unknown";
```
**Source:** Clean Code, Ch. 3 — single level of abstraction per function

#### 1c. No clever one-liners
```typescript
// BAD — clever but unreadable
const result = data?.items?.filter(Boolean).reduce((a, b) => ({...a, [b.id]: b.values.map(v => v * multiplier).filter(v => v > threshold)}), {});

// GOOD — each step is clear
const validItems = data?.items?.filter(Boolean) ?? [];
const result: Record = {};
for (const item of validItems) {
  const scaledValues = item.values.map((v) => v * multiplier);
  const aboveThreshold = scaledValues.filter((v) => v > threshold);
  result[item.id] = aboveThreshold;
}
```
**Source:** Clean Code, Ch. 3 — "Functions should do one thing"

#### 1d. No deep nesting — use guard clauses
```typescript
// BAD — 4 levels deep
function processOrder(order: Order) {
  if (order) {
    if (order.items.length > 0) {
      if (order.status === "pending") {
        if (order.total > 0) {
          // actual logic buried here
        }
      }
    }
  }
}

// GOOD — guard clauses, flat structure
function processOrder(order: Order) {
  if (!order) return;
  if (order.items.length === 0) return;
  if (order.status !== "pending") return;
  if (order.total  3) throw new Error("...");

// GOOD
const ONE_DAY_MS = 86_400_000;
const MAX_RETRIES = 3;
setTimeout(fn, ONE_DAY_MS);
if (retries > MAX_RETRIES) throw new Error("...");
```

#### 4b. Magic strings → const objects
```typescript
// BAD
if (status === "pending") { ... }
if (status === "running") { ... }

// GOOD — already the pattern in this codebase
const DeploymentStatus = {
  PENDING: "pending",
  RUNNING: "running",
} as const;
if (status === DeploymentStatus.PENDING) { ... }
```

#### 4c. What needs extracting
- Status values, error codes, event names → const objects (check shared/common packages)
- Timeout durations, retry counts, limits → named constants at file or module level
- URLs, paths, endpoints → config or constants
- Error messages used in multiple places → error constants
- Array indices with meaning (`items[0]`, `parts[2]`) → destructure with names

#### 4d. What does NOT need extracting
- `0`, `1`, `-1` in obvious contexts (array index, increment, comparison)
- `true`, `false` in obvious boolean contexts
- Empty string `""` for initialization
- Port numbers in Docker/config files (they ARE the config)

**Source:** Clean Code, Ch. 17 (G25) — "Replace Magic Numbers with Named Constants"

---

### Rule 5: Reduce Complexity

#### 5a. Cyclomatic complexity
- **Maximum 10 per function** — if higher, extract branches into separate functions
- Each `if`, `else if`, `&&`, `||`, `?:`, `case`, `catch` adds 1

#### 5b. Cognitive complexity
- **Maximum 15 per function** — nesting multiplies cognitive load
- Each nesting level adds a penalty (nested `if` inside `for` inside `if` = very high)

#### 5c. How to reduce
- **Guard clauses** — handle edge cases early and return
- **Lookup objects** — replace if/else chains with `Record`
- **Extract predicate functions** — `isEligible(user)` instead of inline boolean logic
- **Extract branch bodies** — each `if` branch calls a named function
- **Decompose conditionals** — name both the condition and the branches

**Source:** McCabe (1976), SonarQube cognitive complexity

---

### Rule 6: Type Safety (TypeScript-Specific)

- Replace `any` with proper types or `unknown` + type narrowing
- Replace type assertions (`as Type`) with type guards where possible
- Replace boolean flag types with discriminated unions
- Use `as const` objects instead of `enum` (project convention)
- Use utility types (`Pick`, `Omit`, `Partial`, `Record`) to derive focused types
- Remove `// @ts-ignore` — fix the underlying type error or use `// @ts-expect-error` with explanation

**Source:** TypeScript Handbook, Total TypeScript (Matt Pocock)

---

### Rule 7: No Boolean Parameters

```typescript
// BAD — what does `true` mean here?
createNotification(message, true, false);

// GOOD — options object with named fields
createNotification(message, { urgent: true, silent: false });

// Or split into separate functions if the boolean changes core behavior
sendUrgentNotification(message);
sendSilentNotification(message);
```

**Source:** Clean Code, Ch. 3 (F3) — "Flag Arguments are ugly"

---

### Rule 8: Clean Naming

- Variable names reveal intent: `isEligible` not `flag`, `retryCount` not `n`
- Function names are verb phrases: `validateInput()` not `inputCheck()`
- Boolean names are questions: `isLoading`, `hasPermission`, `canEdit`
- Constants are UPPER_SNAKE_CASE: `MAX_RETRY_COUNT`, `API_TIMEOUT_MS`
- Avoid abbreviations unless universally known (`id`, `url`, `db` are fine; `usr`, `mgr`, `cfg` are not)
- One word per concept across the codebase: pick `fetch` OR `get` OR `retrieve` — not all three

**Source:** Clean Code, Ch. 2

---

## Refactoring Process

### Step 1: Analyze (read-only)
Launch `code-optimizer` agent(s) on the target scope. Collect all findings.

### Step 2: Plan
Group findings by file. Order by priority (CRITICAL → HIGH → MEDIUM → LOW). Present the plan to the user:
- Which files will be modified
- What changes in each file
- Which new files will be created (if extracting)
- Dependencies between changes

### Step 3: Implement (one file at a time)
For each file:
1. Read the file
2. Apply all planned changes for that file
3. Verify the file still works (no broken imports, no missing references)
4. Move to the next file

### Step 4: Verify
After all changes:
1. Run the project's lint/format command (e.g., `biome check --write`, `eslint --fix`, `prettier --write`)
2. Run the project's typecheck command (e.g., `tsc --noEmit`)
3. Report: files changed, what was improved, any issues found

## What NOT to Do

- Don't refactor code you weren't asked to touch (unless it's in scope)
- Don't change formatting or style in files you're not refactoring
- Don't add comments to explain bad code — fix the code
- Don't create abstractions for single-use code
- Don't add interfaces/types that aren't needed yet
- Don't rename things that are already clear
- Don't move code between files unless it clearly violates SRP
- Don't add error handling for impossible scenarios
- Don't add logging, metrics, or telemetry unless asked
- Don't change public APIs without flagging it
- Don't break existing tests

## Output Summary

When complete, report:
```
## Clean Code Pass Complete

### Changes Made
- [file]: [what changed — 1 sentence]
- [file]: [what changed — 1 sentence]

### Extracted
- [new file]: [purpose — 1 sentence]

### Constants/Types Added
- [constant/type]: [where and why]

### Metrics
- Functions refactored: N
- Duplication removed: N instances
- Magic values extracted: N
- Complexity reduced: N functions
- Type safety improved: N fixes

### Verification
- Biome: pass/fail
- TypeScript: pass/fail
- Tests: pass/fail (if applicable)
```

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [anbturki](https://github.com/anbturki)
- **Source:** [anbturki/claude-toolkit](https://github.com/anbturki/claude-toolkit)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-anbturki-claude-toolkit-refactor
- Seller: https://agentstack.voostack.com/s/anbturki
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
