Finding Duplicate-Intent Functions Overview LLM-generated codebases accumulate semantic duplicates: functions that serve the same purpose but were implemented independently. Classical copy-paste detectors (jscpd) find syntactic duplicates but miss "same intent, different implementation." This skill uses a two-phase approach: classical extraction followed by LLM-powered intent clustering. When to Use - Codebase has grown organically with multiple contributors (human or LLM) - You suspect utility functions have been reimplemented multiple times - Before major refactoring to identify consolidati…

\\t' read -r category count; do\n if [[ \"$count\" -ge 3 ]]; then\n outfile=\"$OUTPUT_DIR/${category}.json\"\n jq --arg cat \"$category\" '[.[] | select(.category == $cat)]' \"$CATEGORIZED\" > \"$outfile\"\n echo \" $category: $count functions -> $outfile\" >&2\n else\n echo \" $category: $count functions (skipped, \u003c 3)\" >&2\n fi\ndone\n\necho \"\" >&2\necho \"Category files created in $OUTPUT_DIR\" >&2\necho \"Run Opus duplicate detection on each file with 3+ functions\" >&2\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":1965,"content_sha256":"3452d4a370fe2fdebc1f0fa6de93ac7ee8a6c382bbfe77907871c663b8d6ebad"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Finding Duplicate-Intent Functions","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"LLM-generated codebases accumulate semantic duplicates: functions that serve the same purpose but were implemented independently. Classical copy-paste detectors (jscpd) find syntactic duplicates but miss \"same intent, different implementation.\"","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill uses a two-phase approach: classical extraction followed by LLM-powered intent clustering.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"When to Use","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Codebase has grown organically with multiple contributors (human or LLM)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"You suspect utility functions have been reimplemented multiple times","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Before major refactoring to identify consolidation opportunities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"After jscpd has been run and syntactic duplicates are already handled","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Reference","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Phase","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Model","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Output","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1. Extract","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/extract-functions.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"catalog.json","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2. Categorize","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/categorize-prompt.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"haiku","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"categorized.json","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3. Split","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/prepare-category-analysis.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"categories/*.json","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4. Detect","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/find-duplicates-prompt.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"opus","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"duplicates/*.json","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5. Report","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"scripts/generate-report.sh","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"-","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"report.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Process","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"dot"},"content":[{"text":"digraph duplicate_detection {\n rankdir=TB;\n node [shape=box];\n\n extract [label=\"1. Extract function catalog\\n./scripts/extract-functions.sh\"];\n categorize [label=\"2. Categorize by domain\\n(haiku subagent)\"];\n split [label=\"3. Split into categories\\n./scripts/prepare-category-analysis.sh\"];\n detect [label=\"4. Find duplicates per category\\n(opus subagent per category)\"];\n report [label=\"5. Generate report\\n./scripts/generate-report.sh\"];\n review [label=\"6. Human review & consolidate\"];\n\n extract -> categorize -> split -> detect -> report -> review;\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 1: Extract Function Catalog","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"./scripts/extract-functions.sh src/ -o catalog.json","type":"text"}]},{"type":"paragraph","content":[{"text":"Options:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"-o FILE","type":"text","marks":[{"type":"code_inline"}]},{"text":": Output file (default: stdout)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"-c N","type":"text","marks":[{"type":"code_inline"}]},{"text":": Lines of context to capture (default: 15)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"-t GLOB","type":"text","marks":[{"type":"code_inline"}]},{"text":": File types (default: ","type":"text"},{"text":"*.ts,*.tsx,*.js,*.jsx","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--include-tests","type":"text","marks":[{"type":"code_inline"}]},{"text":": Include test files (excluded by default)","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Test files (","type":"text"},{"text":"*.test.*","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"*.spec.*","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"__tests__/**","type":"text","marks":[{"type":"code_inline"}]},{"text":") are excluded by default since test utilities are less likely to be consolidation candidates.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 2: Categorize by Domain","type":"text"}]},{"type":"paragraph","content":[{"text":"Dispatch a ","type":"text"},{"text":"haiku","type":"text","marks":[{"type":"strong"}]},{"text":" subagent using the prompt in ","type":"text"},{"text":"scripts/categorize-prompt.md","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Insert the contents of ","type":"text"},{"text":"catalog.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" where indicated in the prompt template. Save output as ","type":"text"},{"text":"categorized.json","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 3: Split into Categories","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"./scripts/prepare-category-analysis.sh categorized.json ./categories","type":"text"}]},{"type":"paragraph","content":[{"text":"Creates one JSON file per category. Only categories with 3+ functions are worth analyzing.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 4: Find Duplicates (Per Category)","type":"text"}]},{"type":"paragraph","content":[{"text":"For each category file in ","type":"text"},{"text":"./categories/","type":"text","marks":[{"type":"code_inline"}]},{"text":", dispatch an ","type":"text"},{"text":"opus","type":"text","marks":[{"type":"strong"}]},{"text":" subagent using the prompt in ","type":"text"},{"text":"scripts/find-duplicates-prompt.md","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Save each output as ","type":"text"},{"text":"./duplicates/{category}.json","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 5: Generate Report","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"./scripts/generate-report.sh ./duplicates ./duplicates-report.md","type":"text"}]},{"type":"paragraph","content":[{"text":"Produces a prioritized markdown report grouped by confidence level.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 6: Human Review","type":"text"}]},{"type":"paragraph","content":[{"text":"Review the report. For HIGH confidence duplicates:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify the recommended survivor has tests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Update callers to use the survivor","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Delete the duplicates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run tests","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"High-Risk Duplicate Zones","type":"text"}]},{"type":"paragraph","content":[{"text":"Focus extraction on these areas first - they accumulate duplicates fastest:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Zone","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Common Duplicates","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"utils/","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"helpers/","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"lib/","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"General utilities reimplemented","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Validation code","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Same checks written multiple ways","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error formatting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error-to-string conversions","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Path manipulation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Joining, resolving, normalizing paths","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"String formatting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Case conversion, truncation, escaping","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Date formatting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Same formats implemented repeatedly","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"API response shaping","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Similar transformations for different endpoints","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Common Mistakes","type":"text"}]},{"type":"paragraph","content":[{"text":"Extracting too much","type":"text","marks":[{"type":"strong"}]},{"text":": Focus on exported functions and public methods. Internal helpers are less likely to be duplicated across files.","type":"text"}]},{"type":"paragraph","content":[{"text":"Skipping the categorization step","type":"text","marks":[{"type":"strong"}]},{"text":": Going straight to duplicate detection on the full catalog produces noise. Categories focus the comparison.","type":"text"}]},{"type":"paragraph","content":[{"text":"Using haiku for duplicate detection","type":"text","marks":[{"type":"strong"}]},{"text":": Haiku is cost-effective for categorization but misses subtle semantic duplicates. Use Opus for the actual duplicate analysis.","type":"text"}]},{"type":"paragraph","content":[{"text":"Consolidating without tests","type":"text","marks":[{"type":"strong"}]},{"text":": Before deleting duplicates, ensure the survivor has tests covering all use cases of the deleted functions.","type":"text"}]}]},"metadata":{"date":"2026-11-02","name":"finding-duplicate-functions","author":"@skillopedia","source":{"stars":435,"repo_name":"superpowers-lab","origin_url":"https://github.com/obra/superpowers-lab/blob/HEAD/skills/finding-duplicate-functions/SKILL.md","repo_owner":"obra","body_sha256":"fa3782c9d7e583665cd18ff39981d7dc8a7dededb60942b97995653101eb66b3","cluster_key":"6611861dd3406338a4893afd2cb29dae4ec383f9a9c09fbc19aa6eec3aaab5d9","clean_bundle":{"format":"clean-skill-bundle-v1","source":"obra/superpowers-lab/skills/finding-duplicate-functions/SKILL.md","text_bytes":20532,"source_commit":"51111f74f24058117752d9aa917cb19859f8ec86","skills_sh_rank":17015,"attachment_count":5,"text_attachments":5,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/finding-duplicate-functions/SKILL.md","import_metadata":{"date":"2026-11-02","author":"@skillopedia","version":"v1","category":"software-engineering","category_label":"Engineering"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"software-engineering","import_tag":"skills-sh-top20k-2026-11","description":"Use when auditing a codebase for semantic duplication - functions that do the same thing but have different names or implementations. Especially useful for LLM-generated codebases where new functions are often created rather than reusing existing ones."}},"renderedAt":1793676294634}

Finding Duplicate-Intent Functions Overview LLM-generated codebases accumulate semantic duplicates: functions that serve the same purpose but were implemented independently. Classical copy-paste detectors (jscpd) find syntactic duplicates but miss "same intent, different implementation." This skill uses a two-phase approach: classical extraction followed by LLM-powered intent clustering. When to Use - Codebase has grown organically with multiple contributors (human or LLM) - You suspect utility functions have been reimplemented multiple times - Before major refactoring to identify consolidati…