Reduce code duplication
Finds duplicated logic, separates true duplication from code that only looks alike, and merges only true duplicates behind one well-named function. Use when one fix keeps landing in many places.
Duplication hurts when the copies must change together and someone forgets one of them. Code that only looks alike but changes for different reasons is not duplication. Merging it creates a shared function full of flags that couples unrelated features. The wrong abstraction costs more than the copies did.
Reduce duplication in .
- Find candidate duplicates: repeated blocks, near-identical functions, parallel switch statements, the same validation or formatting written several times.
- For each group, decide whether it is:
- true duplication: the copies represent the same rule and must change together. Look for evidence: commits that changed several copies at once, or a bug fixed in one copy and not the others;
- coincidental: the copies look alike today but belong to different concepts that will change independently.
- Merge only true duplication with at least three copies, or two copies that have already drifted and caused a bug. Give the shared code a name that states the rule it represents, and keep its parameters few. If it needs a boolean flag to serve its callers, it is the wrong abstraction.
- Where copies have already drifted, decide which behaviour is correct. If you cannot tell, do not merge; report the difference as a question.
- Run the tests after each merge.
- Leave coincidental duplication alone and say why.
- No behaviour changes. If merging would change one copy's behaviour, stop and report it.
- Prefer a plain function over a class hierarchy, generic or framework hook.
- Do only what was asked. If you notice something else worth changing, mention it in one line at the end instead of changing it.
- Keep the change as small as it can be while still being correct.
- Before saying the work is done, run the check that proves it (tests, build, type check or the command the user gave) and report the real result.
- If you could not run a check, say so plainly and say which one.
Duplicates
A table: # | Where (path:line for each copy) | True or coincidental | Evidence | Action.
Changes
The diff for the merges you made.
Verification
Test commands and results. List any drifted copies you left for a decision.
1 required value still a placeholder; the assistant will ask for it.
details
- kind
- Prompt: a task you run by name to get one finished thing back
- domain
- Software engineering
- category
- Refactoring
- level
- Intermediate
- made for
- Software engineer, Tech lead / staff engineer
- needs
- repo-read, file-write, shell
- risk
- runs-commands
- version
- v1.0.1 · incubating
- reviewed
- 2026-10-02
- aliases
- refactor-dedup
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md
use in
npx @hermes-hq/hodios install reduce-duplication --target claude-codenpx skills add hermes-hq/hodios-dist --skill reduce-duplication -a claude-codeclaude plugin marketplace add hermes-hq/hodios-distclaude plugin install hodios-software-engineering@hodiosThe plugin brings every entry in this domain at once.
more in refactoring
All of RefactoringApply a design pattern where it removes complexity
Finds the complexity a design pattern would actually remove, such as a growing switch or tangled construction, applies it with identical behaviour, or says no pattern fits.
apply-design-patternConvert callbacks to async/await
Converts callback-style and promise-chain code to async/await across a module or repo without changing behaviour, keeping error handling, ordering and concurrency, with tests run before and after.
convert-callbacks-to-async-awaitDecouple code for testability
Breaks hard-wired dependencies such as clocks, network calls, globals and singletons behind seams so a class or module can be unit tested, keeping behaviour and public callers unchanged.
decouple-for-testabilityExtract configuration from code
Finds hard-coded URLs, limits, credentials and feature switches, moves them into typed configuration with defaults and validation, and updates usages and docs without committing secrets.
extract-configuration-from-codeExtract a module
Moves one responsibility out of a large file or class into its own module in small, test-verified steps, without changing behaviour or the public API. Use when a file does too many things.
extract-moduleEnable a lint rule and fix every violation
Enables a new lint or formatter rule and fixes its violations across a repository in small commits, keeping mechanical fixes apart from risky ones. Use when adopting a rule on an existing codebase.
fix-lint-violations-repo-wide