Repository navigation
Dry
The dry slice helps find duplicate code.
It uses jscpd, a tool that spots copied blocks, and it helps Claude decide which copies to merge.
Less duplicate code means less to read and less to fix.
The slice adds one command and one skill.
It has no hook, no userConfig key, and no setting, so there is nothing to turn off.
The command jscpd-config writes the config of jscpd.
The skill dry tells Claude when to run jscpd and how to read a clone.
| Item | Kind | What it does |
|---|---|---|
jscpd-config |
Command in bin/
|
Merges jscpd.local.json and its extends chain into .jscpd.json. |
dry |
Skill | Finds clones, reads each clone, and decides if a merge is good. |
The slice runs no jscpd itself.
Claude runs bunx jscpd after the command wrote the config.
Run jscpd-config from the root of the project to write the config:
jscpd-config [--local FILE] [--out FILE]
| Option | Default | Meaning |
|---|---|---|
--local FILE |
jscpd.local.json |
The file with the rules of the project. |
--out FILE |
.jscpd.json |
The file that the command writes. |
When the local file does not exist, the command writes the shipped base.
The command writes the output file in one step, so a failed run leaves no half file.
--help and -h print the usage and exit with 0.
The base is assets/jscpd.base.json in the slice.
It sets these keys:
| Key | Value |
|---|---|
minTokens |
50 |
minLines |
5 |
mode |
mild |
similarity |
0.8 |
semantic |
{ "scope": "all" } |
baseline |
.jscpd-baseline.json |
failOnNewClones |
0 |
gitignore |
true |
reporters |
["console"] |
The base ignores .git, node_modules, dist, build, target, vendor, minified files, and lock files.
With the baseline file and failOnNewClones at 0, only a new clone fails a run.
The base lists no format, so a project adds each format in formatsExts.
semantic needs a large model download, so a project sets "semantic": null when it does not want it.
jscpd.local.json can name a parent in extends.
The value is a path from the folder of the file, or claudetto:base for the shipped base.
The command merges the chain from the first file to the local file:
- A key of the child replaces the key of the parent.
- An object merges deep.
- A list under a key that starts with
ignoreappends the child items to the parent items, with no repeat. - The key
<key>Removetakes items out of the list of the parent. - A value
nulldeletes the key.
A chain that returns to a file is an extends cycle, and the command stops with an error.
| Code | Meaning |
|---|---|
| 0 | The command wrote the file, or printed the usage. |
| 2 | A file does not parse, an extends chain has a cycle, or the write failed. |
Claude runs the skill when a change copies a block, before it finishes a change that adds many lines, and when the user asks about duplication.
The skill tells Claude to merge two clones only when one change of a rule must change both, and the behavior and the effects stay the same.
It tells Claude not to merge blocks that only look alike, or a merge that needs a flag for each difference.
A clone that Claude keeps on purpose goes in the baseline with bunx jscpd --update-baseline, and Claude says why.
claudetto
- Start
- Slices
- Add-Ons
- Reference
- Rationale
- Evidence
- Development
Claude Code