agentleFS
Bruno-Cunha-SouzaBruno-Cunha-Souza/ValarMindSkills/skills/clean-code/SKILL.md

clean-code

Skill5 starsChanged 6 months agoMITView on GitHub

Clean code lifecycle for Go/Rust/TypeScript/Bun/Python — writing, reviewing, refactoring. Naming, functions, DRY, code smells, duplication (literal/logical/structural), dead-code removal with false-positive guardrails, safe refactoring. Triggers: 'clean code', 'código limpo', 'refactor', 'refatorar', 'remove duplication', 'remover duplicação', 'dead code', 'código morto', 'code smells', '/clean-code'.

  • Installs packages

108 other projects use a version of this, 12 of them edited.

Adopted by

Most recently taken up by

Used with

Projects with it also use intelligent-routing, nextjs-react-expert and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • SKB3002Skill

    intelligent-routing

    Automatic agent selection and intelligent task routing. Analyzes user requests and automatically selects the best specialist agent(s) without requiring explicit user mentions.

    Also in 5 projects that use this

  • SKB3002Skill

    nextjs-react-expert

    React and Next.js performance optimization from Vercel Engineering. Use when building React components, optimizing performance, eliminating waterfalls, reducing bundle size, reviewing code for performance issues, or implementing server/client-side optimizations.

    Also in 3 projects that use this

  • xfstudioSkill

    bash-pro

    Master of defensive Bash scripting for production automation, CI/CD

    Also in 4 projects that use this

  • xfstudioSkill

    code-refactoring-tech-debt

    You are a technical debt expert specializing in identifying, quantifying, and prioritizing technical debt in software projects. Analyze the codebase to uncover debt, assess its impact, and create acti

    Also in 4 projects that use this

  • flying-diceSkill

    clean-code-review

    Multi-agent clean code audit — each principle gets its own agent

    Also in 3 projects that use this

  • goca-seSkill

    batch-operations

    Apply a change safely across many files — refactors touching more than 5 files, library or API migrations, project-wide renames of symbols/imports/paths, or adding boilerplate to many files. Use when "do it all at once" risks context overflow or silent failures.

    Also in 3 projects that use this

  • +4 more from xfstudio

The file

We split this skill into the rules it gives an agent

2 rules. 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 101 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before applying any clean code principle, understand the project you're working in.

    line 36
  2. Distinctive:

    Refactoring without tests: If the code has no tests, write characterization tests first — tests that capture current behavior, even if that …

    line 261

“Common” is measured: kept by at least 6 in 10 of the 101 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Clean Code Lifecycle

"Code is clean if it can be read, and enhanced by a developer other than its original author." — Grady Booch

When to Use

  • Writing new code: To ensure high quality from the start.
  • Reviewing Pull Requests: To provide constructive, principle-based feedback.
  • Refactoring legacy code: To identify and remove code smells.
  • Improving team standards: To align on industry-standard best practices.

Prerequisites

ToolPurposeInstall
jscpdMulti-language clone detectionnpm install -g jscpd
pmdJava/multi-language CPDpmd.github.io
fdFast file finderbrew install fd / apt install fd-find
rgFast content searchbrew install ripgrep / apt install ripgrep
golangci-lintGo meta-linter (50+ linters)go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
clippyRust idiomatic linter (500+ lints)rustup component add clippy
biomeFast TS/JS linter + formatterbun install -D @biomejs/biome / npm install -D @biomejs/biome
knipFind unused TS exports/deps/filesbunx knip / npx knip
ruffPython linter — unused imports/vars, dedup hintspipx install ruff
vulturePython dead-code detection with confidence tierspipx install vulture
Project linterLanguage-specific checksCheck project config (.eslintrc, .golangci.yml, biome.json, pyproject.toml)

Phase 0 — Project Context Discovery

Before applying any clean code principle, understand the project you're working in. Refactoring or deduplicating without context leads to wrong abstractions, broken conventions, and wasted effort.

Discovery Commands

# 1. Find project documentation — README, ADRs, contributing guides
fd -t f -i '(README|CONTRIBUTING|ADR|ARCHITECTURE|CONVENTIONS|STYLE_GUIDE)' .

# 2. Find configuration files that reveal conventions and tooling
fd -t f '(\.eslintrc|\.prettierrc|\.editorconfig|\.golangci|pyproject\.toml|biome\.json)' .

# 3. Check for a CLAUDE.md or similar AI-agent instructions
fd -t f 'CLAUDE.md' .

# 4. Read the project's commit style to match refactoring commits
git log --oneline -20

# 5. Check for existing shared utilities — avoid creating duplicates
fd -t f -i '(utils|helpers|shared|common|lib)' src/

Key Questions

QuestionWhy it mattersWhere to find it
Does the project have a style guide or coding conventions?Your refactoring must follow existing patterns, not introduce new onesCONTRIBUTING.md, linter configs, ADRs
Are there existing shared utility modules?Before extracting a helper, check if one already existsutils/, shared/, lib/, common/ dirs
What's the test strategy (unit, integration, e2e)?Determines how you verify refactoring safetyREADME.md, CI config, test directory structure
Are there architectural boundaries (modules, packages, bounded contexts)?Deduplicating across boundaries may violate the architecture intentionallyARCHITECTURE.md, ADRs, module/package structure
Is there a dependency injection or service pattern in use?Extracting code the wrong way can break DI wiringEntry points, main files, DI containers

Decision Rules

  • If a style guide exists → follow it, even if it contradicts Clean Code principles. Project consistency wins over theoretical purity.
  • If shared utils already exist → add to them instead of creating parallel helpers.
  • If ADRs document a decision to keep duplication → respect it. Not all duplication is accidental.
  • If no tests exist → write characterization tests before any refactoring (see Phase 3).
  • If no documentation exists → read code structure, git history, and CI config to infer conventions.

Rule: context before cleanup. A "clean" refactoring that ignores project conventions creates more mess than the duplication it removed.

Phase 1 — Code Quality Audit

Scan the codebase for code smells. Each smell includes a description and detection method.

#SmellDescriptionDetection
1RigidityOne change forces a cascade of dependent changesCount how many files a single-line change touches
2FragilityBreaks in many places when you make a changeLook for high coupling with no clear interface boundary
3ImmobilityUseful parts are entangled with unneeded detailsFunctions that import half the project to do a simple task
4ViscosityEasier to hack than to follow the designDevs keep bypassing an abstraction — it's too cumbersome
5Needless ComplexityPremature abstraction or speculative generalityUnused interfaces, empty abstract methods, config nobody changes
6Needless RepetitionSame logic in multiple placesnpx jscpd ./src or review similar function bodies
7Feature EnvyA method accesses another object's data more than its ownChains: order.getCustomer().getAddress().getCity()
8Shotgun SurgeryA single change requires edits across many filesgit log --name-only — same files always change together
9Divergent ChangeOne class changed for many different reasonsFile with commits from unrelated features

Principle Checks

For each file under review, verify against the core principles. See references/PRINCIPLES.md for full details.

  • Names: Intention-revealing, searchable, pronounceable?
  • Functions: Small (<30 lines), do one thing, ≤2 arguments?
  • Comments: Can any comment be eliminated by making the code clearer?
  • Formatting: Newspaper metaphor — high-level at top, details at bottom?
  • Objects: Law of Demeter respected? No a.getB().getC().doSomething()?
  • Error Handling: Exceptions over return codes? No null returns/passes?
  • Tests: F.I.R.S.T. principles followed?
  • Classes: Single Responsibility Principle?

Language-Specific Checks

For language-specific smells, idioms, and detection commands:

  • Go: See references/GOLANG.md — stuttering names, empty interface abuse, init() side effects, naked returns, oversized interfaces, functional options
  • Rust: See references/RUST.md — unwrap() abuse, unnecessary clone(), stringly typed APIs, Arc<Mutex<>> overuse, monolithic error enums, boolean parameters
  • TypeScript: See references/TYPESCRIPT.md — any abuse, excessive type assertions, enum vs union, barrel file bloat, god interfaces, class overuse
  • Bun: See references/BUN.md — Node.js APIs vs Bun natives, unnecessary polyfills, dotenv/jest/express replacements, Bun.file/Bun.serve/Bun.password
  • Python: See references/PYTHON.md — dict-as-object, if/elif dispatch chains, **kwargs soup, boolean flag params, stateless classes, import-time side effects, sync/async twins

Phase 2 — Duplication & Dead Code Detection

Duplication is the same knowledge, logic, or intent expressed in more than one place. Dead code is a symbol nothing reaches. Both inflate the change surface — find them before Phase 3 touches anything.

2.1 Duplication

ClassSignatureCost of leaving it
LiteralIdentical blocks copied verbatimCopies drift; the next fix lands in one of them, not all
LogicalSame outcome, different names or control flowInvisible to clone tools — only reading similar signatures finds it
StructuralRepeated if/else or switch chains spelling out the same decisionAdding one case means editing N sites; one gets forgotten
DataConstants, URLs, configs, error envelopes repeated across filesValues drift silently; the copies disagree

Detection commands per class, how to read the Structural signal from commit history, and the when NOT to deduplicate rules: references/DUPLICATION.md.

Rule of Three. Tolerate two copies. Extract on the third. A premature abstraction — the shared function that needs 4 parameters and 2 boolean flags to serve every caller — is worse than the duplication it removed.

2.2 Dead Code

TypeExample
Unreferenced function / typeNo call site in source, tests, templates, config, or CI
Unused importFlagged by the linter, with no side-effect or re-export role
Assigned-never-read variable / unused parameterFlagged by the linter, not fixed by an interface signature
Unreachable branchDead feature flag, code after return, provably constant guard
Unused dependency / orphan fileManifest or module graph shows zero importers

Command matrix per language, plus the twelve false-positive guardrails that must clear before any deletion: references/DEAD_CODE.md.

Rule: two independent signals before deleting. A tool finding plus a manual sweep of non-source assets. Reflection, DI registries, framework decorators, serialization, and string-based routing are invisible to every dead-code tool — deleting a live symbol passes the test suite and breaks production.

Phase 3 — Safe Refactoring

Apply refactoring patterns to resolve the issues found in Phases 1 and 2. For concrete before/after diffs, see references/PATTERNS.md.

Available Patterns

PatternUse WhenResult
Extract FunctionIdentical blocks across multiple call sitesAuth check in every handler → middleware
Extract Constant/ConfigMagic values repeated across files30 * time.Second in 3 files → config.DefaultTimeout
Generic/Parameterized FunctionNear-identical functions differing by one callGetUser, GetOrder → getByID[T]
Template Method / StrategySimilar flows with one varying stepPDF/CSV generators → GenerateReport(data, renderer)
Substitute AlgorithmTwo functions reach the same result by different meansTwo CSV parsers → keep the streaming one, delete the other
Replace Conditional with PolymorphismThe same switch/if-elif chain repeated across filesChannel switch in 3 handlers → dispatch table, then interface

Step 1 — Secure the starting point

# Ensure all tests pass BEFORE you start
go test ./...          # Go
cargo test             # Rust
bun test               # Bun
npm test               # Node/TS
pytest                 # Python

# Ensure a clean git state
git status             # should be clean, or stash first
git stash              # if needed

# Create a dedicated branch
git checkout -b refactor/describe-the-change

Rule: never refactor on a dirty working tree. Mixing feature changes with refactoring makes rollback impossible.

Step 2 — One transformation at a time

Each refactoring step must be atomic — a single, small, independently verifiable change.

StepActionVerify
1Extract function / constant / typeRun tests
2Replace first call site with the new abstractionRun tests
3Replace next call siteRun tests
4Remove old dead code — follow the DEAD_CODE.md protocol: two signals, guardrails cleared, own commitRun tests
5Commitgit commit -m "refactor: extract getByID generic handler"

Never batch multiple extractions into a single step.

# After EACH small change:
go test ./...  # or your project's test command
git add -p     # stage only the relevant change
git commit -m "refactor: step N — description"

Step 3 — Verify behavior preservation

# Go: check exported symbols haven't changed
go doc ./pkg/handlers
go vet ./...
golangci-lint run ./...

# Rust: clippy + format + test
cargo clippy -- -W clippy::pedantic
cargo fmt -- --check
cargo test

# TypeScript / Bun: type check + lint
bunx tsc --noEmit          # or: npx tsc --noEmit
bunx biome check .         # or: npx eslint .
bun test                   # or: npx vitest run

# Python: type check + lint + test
ruff check .
ruff format --check .
mypy --strict .
pytest -q

# Find unused exports and dependencies (TypeScript / Bun)
bunx knip

# Run integration/e2e tests if available
npm run test:e2e

# Check for unused imports/variables introduced by refactoring
go vet ./...                                            # Go
cargo machete                                           # Rust
bunx knip                                               # TypeScript / Bun
npx eslint --rule '{"no-unused-vars": "error"}' src/    # TypeScript (eslint)
ruff check --select=F401,F841,ARG .                     # Python — unused imports/vars/params
vulture src/ tests/ --min-confidence 90                 # Python — dead symbols

Step 4 — Rollback strategy

# Undo current uncommitted change (keep committed steps)
git checkout -- .

# Revert just one committed step
git revert <commit-hash>

# Abandon the entire refactoring branch
git checkout main
git branch -D refactor/describe-the-change

The branch-per-refactoring approach means you never risk main.

Common Pitfalls

  • Changing behavior during refactoring: Resist the urge to "fix that bug while I'm here." Refactoring and behavior changes are separate commits — always.
  • Refactoring without tests: If the code has no tests, write characterization tests first — tests that capture current behavior, even if that behavior has bugs.
  • Big-bang refactoring: Rewriting an entire module at once. Prefer the Strangler Fig pattern — replace piece by piece.
  • Skipping the test run: "It's just a rename." Type aliases, reflection, serialization, string-based routing — all break on renames.

Plan-only mode

Composing /clean-code /only-plan suppresses every write in Phase 3 — no branch, no commits, no edits. Phases 0–2 run normally, and each planned transformation becomes a numbered step in the single IMPLEMENTATION_PLAN.md at the project root, following @only-plan's section contract. This skill writes no file of its own in either mode.

Related Skills

  • @only-plan — compose as /clean-code /only-plan for a refactor plan at the project root instead of applied edits.
  • @code-optimization — when duplication or a smell has a measurable performance cost; it grades Impact and writes OPTIMIZATION_REPORT.md.
  • @code-review — broad severity-ranked review; its Rule-of-Three findings hand off here for the refactor mechanics.
  • @code-debugger — a smell that is actually a live defect belongs there first. Refactor after the fix is green.

References

  • PRINCIPLES — the eight Clean Code principle families
  • PATTERNS — six refactoring patterns with before/after diffs
  • DUPLICATION — taxonomy, detection probes, when NOT to deduplicate
  • DEAD_CODE — per-language detection, false-positive guardrails, removal protocol
  • GOLANG · RUST · TYPESCRIPT · BUN · PYTHON — language-specific smells and idioms

Implementation Checklist

  • Is this function smaller than 30 lines?
  • Does this function do exactly one thing?
  • Are all names searchable and intention-revealing?
  • Have I avoided comments by making the code clearer?
  • Am I passing too many arguments?
  • Is there a failing test for this change?
  • Is there duplicated logic that could be extracted into a shared function?
  • Are magic strings/numbers extracted into named constants?
  • Did I check for existing utilities before writing a new helper?
  • If I extracted a shared abstraction, is it used in 3+ places (Rule of Three)?
  • Did two independent signals confirm each dead symbol before deleting it (tool finding + non-source sweep)?
  • Did I clear the false-positive guardrails (reflection, DI, framework decorators, serialization, entry points, published API)?
  • Is each deletion in its own commit, separate from any refactor?
  • Did I run all tests before AND after refactoring?
  • Is each refactoring step in its own commit (one transformation per commit)?
  • Did I avoid mixing behavior changes with structural refactoring?
  • If the code had no tests, did I write characterization tests before refactoring?

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.