Install
$ agentstack add skill-anbturki-claude-toolkit-refactor ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →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: Runcode-optimizeragent 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
// 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
// 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
// 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
// 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
// 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,-1in obvious contexts (array index, increment, comparison)true,falsein 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,catchadds 1
5b. Cognitive complexity
- Maximum 15 per function — nesting multiplies cognitive load
- Each nesting level adds a penalty (nested
ifinsideforinsideif= 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
ifbranch 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
anywith proper types orunknown+ type narrowing - Replace type assertions (
as Type) with type guards where possible - Replace boolean flag types with discriminated unions
- Use
as constobjects instead ofenum(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-errorwith explanation
Source: TypeScript Handbook, Total TypeScript (Matt Pocock)
Rule 7: No Boolean Parameters
// 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:
isEligiblenotflag,retryCountnotn - Function names are verb phrases:
validateInput()notinputCheck() - Boolean names are questions:
isLoading,hasPermission,canEdit - Constants are UPPERSNAKECASE:
MAX_RETRY_COUNT,API_TIMEOUT_MS - Avoid abbreviations unless universally known (
id,url,dbare fine;usr,mgr,cfgare not) - One word per concept across the codebase: pick
fetchORgetORretrieve— 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:
- Read the file
- Apply all planned changes for that file
- Verify the file still works (no broken imports, no missing references)
- Move to the next file
Step 4: Verify
After all changes:
- Run the project's lint/format command (e.g.,
biome check --write,eslint --fix,prettier --write) - Run the project's typecheck command (e.g.,
tsc --noEmit) - 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
- Source: anbturki/claude-toolkit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.