/dedupe-fix [path]
Find duplicated code patterns and consolidate them into shared utilities.
First: Activate Workflow
mkdir -p .claude && echo '{"skill":"dedupe-fix","started":"'$(date -Iseconds)'"}' > .claude/active-workflow.json
Craft Standards (MANDATORY)
Consolidate toward code a master craftsperson would be proud of.
Duplication is a form of technical debt. The consolidated code must look like it was written by a skilled human engineer.
AI Antipatterns When Consolidating
- •Don't create over-abstracted "utility frameworks"
- •Don't add unnecessary configuration to consolidated functions
- •Don't create deep inheritance hierarchies to share code
- •Don't wrap simple functions in classes for no reason
Human Craft When Consolidating
- •Create focused, single-purpose utility functions
- •Use clear names that describe what the function does
- •Keep the consolidated code SIMPLER than the duplicates
- •If consolidation makes code harder to understand, reconsider
Test: Is the consolidated version clearer than having the code inline? If not, maybe duplication was acceptable.
Process
Step 0: Load Expert Guidance
Before starting, read these canon skills and apply their principles throughout:
Always load:
- •
.claude/skills/composition/SKILL.md - •
.claude/skills/clarity/SKILL.md - •
.claude/skills/simplicity/SKILL.md
If a skill file doesn't exist (not installed in this project), skip it and continue. Reference loaded experts in your APPLIED output.
Step 0b: Learn From Past Mistakes
Read both lessons files if they exist:
- •
workflow-skills/phase-loop-lessons.md— universal patterns (ships with skills, applies to all projects) - •
.claude/phase-loop-lessons.md— project-specific patterns (accumulated from this project's runs)
Use relevant lessons to guide your deduplication:
- •DUPLICATION entries → actively search for these specific duplicate patterns (e.g., same-name constants in different files)
- •LOGIC entries → when consolidating, ensure the shared version avoids known bug patterns (e.g., TOCTOU)
- •AI_SMELL entries → when consolidating, don't over-abstract: only extract if 2+ callers exist; don't create single-use wrappers
If a file doesn't exist, skip it and continue.
Step 1: Find Duplicates
Search for duplicated patterns:
# Function definitions appearing in multiple files grep -rn "function copy\|function hash\|execSync.*git" --include="*.ts" | grep -v test | grep -v node_modules # Repeated utility patterns grep -rn "createHash\|getGitCommit\|getGitRemote" --include="*.ts" | grep -v test | grep -v node_modules
Step 2: Analyze Each Duplicate
For each pattern found in 2+ files:
- •Read all instances
- •Compare logic - are they truly identical?
- •If identical or nearly identical → consolidate
- •If intentionally different → document why and skip
Step 3: Consolidate (MANDATORY)
For each TRUE duplicate:
- •
Create shared utility in appropriate location:
- •
src/utils/for general utilities - •
src/shared/for cross-module code - •Module's own
helpers.tsfor module-specific
- •
- •
Extract the function to shared location:
typescript// src/utils/fs.ts export function copyDirectoryRecursive(src: string, dest: string): void { // consolidated implementation } - •
Update all usages to import from shared:
typescriptimport { copyDirectoryRecursive } from '../utils/fs.js'; - •
Delete duplicate code from original locations
- •
Verify - run build/tests:
bashnpm run build npm test
Step 4: Report
Document what was consolidated.
Output Format
## Deduplication Fix: [path] ### Summary | Metric | Value | |--------|-------| | Duplicates found | N | | Consolidated | N | | Kept separate | N | ### Consolidated 1. **copyDirectoryRecursive** - Extracted to: `src/utils/fs.ts` - Removed from: `src/canon/helpers.ts`, `src/workflow/index.ts` - Usages updated: 5 files 2. **getGitCommit** - Extracted to: `src/utils/git.ts` - Removed from: `src/canon/index.ts`, `src/profiles/apply.ts` - Usages updated: 3 files ### Kept Separate (with reason) 1. **hashDirectory** - Different algorithms for different manifest formats ### Verification - Build: ✅ Pass - Tests: ✅ Pass --- DUPLICATES_FOUND: N CONSOLIDATED: N KEPT_SEPARATE: N DEDUPE_COMPLETE: yes
Rules
- •MUST CONSOLIDATE - If it's truly duplicated, extract it
- •VERIFY - Build and test after each consolidation
- •DOCUMENT - If keeping separate, explain why
- •SINGLE SOURCE - Each piece of logic should exist once
Kept Separate Criteria
Only keep duplicates separate if:
- •Intentionally different algorithms
- •Different dependencies that can't be unified
- •Performance-critical paths needing specialization
"Might diverge in the future" is NOT a valid reason.
Comparison
| Skill | Finds | Fixes |
|---|---|---|
/dedupe-scan | ✓ | ✗ (read-only) |
/dedupe-fix | ✓ | ✓ (consolidates) |