Agent Skills
Overview
jscpd ships five agent skills for skills.sh. A skill is a folder with a SKILL.md that an assistant (Claude Code, Copilot, Gemini, Cursor and others) reads when a task matches its description, so the agent runs jscpd with the right options and follows a tested workflow instead of improvising one.
| Skill | What it does | When the agent needs it |
|---|---|---|
jscpd | The tool reference: the flags, the ai reporter, the config file. | Any run of jscpd. |
dry-refactoring | Removes the clones jscpd found: reads each pair, picks an extraction, applies it, checks the clone is gone. | "Find and fix code duplication." |
codebase-refactoring | A pass over the three biggest maintenance costs, measured with --health: duplicated code, dead code, then the most complex files. | "Clean up this codebase", "pay down tech debt." |
compare-codebases | Compares two folders function by function with --compare, in one language or across two, and explains the result. | "How far is the port?", "What does the Android app have that iOS lacks?" |
code-migration | Ports a codebase to another language or framework: tests first, then the code, one function at a time, with --compare as the progress measure. | "Port this Python library to TypeScript." |
Installation
# All five skills
npx skills add kucherenko/jscpd
# One at a time
npx skills add kucherenko/jscpd --skill jscpd
npx skills add kucherenko/jscpd --skill dry-refactoring
npx skills add kucherenko/jscpd --skill codebase-refactoring
npx skills add kucherenko/jscpd --skill compare-codebases
npx skills add kucherenko/jscpd --skill code-migration
The skills run jscpd through npx jscpd, so the agent needs no global install. Once a skill is installed, a request in its words is enough: "find and fix code duplication" runs the first two, "clean up this codebase" the third, "port this library to Rust" the last two.
jscpd
The reference the other skills build on. It tells the agent to run jscpd with the ai reporter, which lists each clone on one line and uses about 79% fewer tokens than the console output, to read the pairs (file paths and line ranges) and to report what it found.
npx jscpd --reporters ai ./src
Clones:
src/utils/ auth.ts:10-25 ~ helpers.ts:40-55
src/utils/auth.ts 30-45 ~ 80-95
---
2 clones · 3.1% duplication
It also covers the options that decide what counts as a clone, --min-tokens, --min-lines, --ignore, --format and --mode, and the keys of .jscpd.json. Configuration lists them all, and AI Token Efficiency measures the reporter.
dry-refactoring
A workflow for removing the clones jscpd reports:
- Run jscpd with
--reporters aion the target path. - Parse each clone line to find the two duplicated locations (file and line range).
- Read both fragments from the source files.
- Understand what the duplicated code does.
- Design a refactoring: extract a shared function, class, module or constant.
- Apply it, updating both locations and every other usage.
- Re-run jscpd to confirm the clone is gone.
- Repeat for the remaining clones, highest impact first.
| Strategy | When to use it |
|---|---|
| Extract function | The duplicate is a block of logic. |
| Extract module or utility | The duplicate spans files in different domains. |
| Extract constant or config | The duplicate is repeated data or configuration. |
| Template or base class | The duplicate is a repeated class shape. |
Start with the clones that have the most lines. A clone between test files often means a missing test helper, and a clone across unrelated modules a missing shared utility. --min-lines 10 filters the noise when the list is long.
codebase-refactoring
Starts from one number and works where it is lowest:
npx jscpd --health --reporters ai ./src
health 74 B (duplication 75, dead-code 72, complexity 76; 93 code lines)
The health score is a weighted mix of three sub-scores, each a share of the code lines, and the lowest one names where the codebase hurts most. The skill then makes three passes: dry-refactoring for the clones, --dead-code for unused files, exports and imports (removed, or kept with a reason), and --complexity for the largest and most complex files, which get split or simplified. After each pass the agent runs --health again and reports the change, so the result is a number and not a feeling.
compare-codebases
jscpd --compare A B pairs every function of folder A with the function of folder B that does the same job, in one language or across two, and lists the functions that have no counterpart (5.4.0+, experimental). The skill explains how the pairing works: a code embedding model that runs inside jscpd after a one-time jscpd --semantic-download (548 MB), pairs by code and then by name, three similarity levels, and tests measured apart from code. It also says how to run a comparison well: point at the code, not at the repository roots, keep vendored dependencies and build output out of both paths with .gitignore or --ignore, and read the report's counterpart column before trusting its percentage.
npx jscpd --compare python/ typescript/ # a port: the source first, the target second
npx jscpd --compare ios/ android/ # two implementations of one app
See Comparing Two Codebases for the reports and how to read them.
code-migration
The port workflow. It uses --compare as the progress measure and the source's tests as the definition of done:
- Run
--compareon the source and the empty target to list every function to port. - Collect test coverage of the source and map each test to the functions it runs, so a function is ported together with the tests that check it. A function no test covers gets a test on the source side first.
- Port the tests before the code, keeping inputs and expected values as they are. No stubs to make them compile: a stub under the source's name can pair by name and count as ported.
- Port the code one function at a time, starting with the functions whose callees are already ported (the report's
readyToPortlist), and run--compareafter each step to see the function leave the unmatched list and pair with the right counterpart. - Report progress as two numbers, tests ported and passing, and functions ported, with the functions left out on purpose and why.
The skill was tested by porting fs-extra 11.4.1 to a Rust addon. The port is on npm as @jscpd/fs-extra, with the code at kucherenko/fs-extra-rs; a run of the same task without the skill is kept at kucherenko/fs-extra-rs-plain for comparison.
More information
- Skills on skills.sh: skills.sh/kucherenko/jscpd
- The skills' sources: skills/ in the jscpd repository
- Reporters, Configuration, MCP Server