DRY Refactoring With jscpd
kucherenko/jscpd
Removes copy-paste duplication found by jscpd, starting with exact clones and hotspots, then renamed and near-miss copies, using proven refactoring strategies.
Finds unused files, exports and class members with Knip, then verifies each candidate through reference tracing before removing anything, never using knip --fix.
$ npx skills add shift-editor/shift --skill dead-code -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install shift-editor/shift dead-code --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/dead-code .claude/skills/dead-code && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "dead-code" agent skill from https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-code into .claude/skills/dead-code/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dead-code", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-codeType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add shift-editor/shift --skill dead-code -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install shift-editor/shift dead-code --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/dead-code .agents/skills/dead-code && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "dead-code" agent skill from https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-code into .agents/skills/dead-code/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dead-code", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add shift-editor/shift --skill dead-code -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install shift-editor/shift dead-code --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/dead-code .cursor/skills/dead-code && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "dead-code" agent skill from https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-code into .cursor/skills/dead-code/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dead-code", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/shift-editor/shift.git --path .claude/skills/dead-code--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add shift-editor/shift --skill dead-code -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install shift-editor/shift dead-code --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/dead-code .gemini/skills/dead-code && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "dead-code" agent skill from https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-code into .gemini/skills/dead-code/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dead-code", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install shift-editor/shift dead-codeInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add shift-editor/shift --skill dead-code -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/dead-code .github/skills/dead-code && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "dead-code" agent skill from https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-code into .github/skills/dead-code/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dead-code", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add shift-editor/shift --skill dead-code -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install shift-editor/shift dead-code --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/dead-code .opencode/skills/dead-code && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "dead-code" agent skill from https://github.com/shift-editor/shift/tree/main/.claude/skills/dead-code into .opencode/skills/dead-code/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "dead-code", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
dead-codeFinds unused files, exports and class members with Knip, then verifies each candidate through reference tracing before removing anything, never using knip --fix.
Knip is used only to generate candidates, through the project's deadcode and class-member scripts, and the output is sorted into unused files, unused exports and unused class members. The skill warns never to run knip --fix because it once deleted code that was in use, breaking the editor and its tests.
Each candidate is then checked by hand. Files are searched by name and checked against config files, test helpers, package scripts and CI. Exports are checked for barrel re-exports, extends and implements clauses and test-only use, with a find-refs.ts script giving a compiler-level reference count. Class members, where most false positives occur, are traced through interface contracts, composite types, dependency-injection interfaces, base classes and abstract methods.
3 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit e7dacfa. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pnpmnpxFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use pnpm and npx, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Dead Code Removal with Knip loads about 1.8k tokens when it runs. Until then it costs about 75 tokens; SKILL.md has 646 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from shift-editor/shift at commit e7dacfa, republished under its Apache-2.0 licence (© shift-editor). 646 words, ~1,807 tokens.
.claude/skills/dead-code/SKILL.md (or your agent's skills folder).Use this skill to find unused files, exports, and class members in the codebase. It uses Knip as a candidate generator, then verifies each candidate through AST-level analysis and interface tracing before removing anything.
NEVER use knip --fix — it has previously deleted code that was actually in use, breaking the editor and tests.
Run Knip to generate candidates:
pnpm deadcode 2>&1 # unused files + exports
pnpm deadcode:class 2>&1 # unused class membersParse the output into three categories:
For each candidate, apply the appropriate checks below. Use scripts/find-refs.ts when reading code alone is insufficient.
tsconfig.json, vite.*.config.ts, forge.config.tspackage.json scripts or CI workflowsindex.ts) consumed by another packageextends/implements clausesnpx tsx scripts/find-refs.ts <file> <symbol> for compiler-level reference countThis is where most false positives occur. Knip cannot trace usage through interfaces, composite types, or dep interfaces.
Check these patterns in order:
ShiftEditor = EditorAPI & CanvasCoordinatorContext means all EditorAPI members on Editor are used.BaseCommand, BaseTool) and used by subclasses?npx tsx scripts/find-refs.ts <file> <memberName> for compiler confirmation.Members that satisfy any of these interfaces are NOT dead code, even if Knip reports them:
EditorAPI sub-interfaces (apps/desktop/src/renderer/src/lib/tools/core/EditorAPI.ts):
Viewport: zoomLevel, panX, panY, screenToUpm, upmToScreen, screenToUpmDistance, viewportBoundsSelection: selectedPointIds, selectedSegmentIds, selectPoints, selectSegments, clearSelection, marqueePreviewPointIds, setMarqueePreviewHitTesting: hitTestPoint, hitTestSegment, hitTestContour, hitTestBoundingBox, hitTestContourEndpoint, hitTestHandleSnapping: createDragSnapSession, createRotateSnapSession, setSnapIndicatorEditing: startEdit, commitEdit, cancelEdit, isEditingCommands: executeToolLifecycle: activeTool, setActiveTool, activeToolSettingsVisualState: hoveredPoint, setHoveredPoint, hoveredSegment, setHoveredSegment, cursor, setCursorFont interface (apps/desktop/src/renderer/src/lib/editor/Font.ts):
getMetrics, getMetadata, getSvgPath, getAdvance, getBboxCommand interface (apps/desktop/src/renderer/src/lib/commands/core/):
execute, undo, redo, nameBehavior interface (apps/desktop/src/renderer/src/lib/tools/core/):
canHandle, transition, onTransitionBaseTool abstract members:
behaviors, render, executeAction, onStateChange, preTransitionDep interfaces (consumed by managers, implemented by FontEngine or Editor):
EditingEngineDeps — apps/desktop/src/renderer/src/engine/editing.tsSessionEngineDeps — apps/desktop/src/renderer/src/engine/session.tsInfoEngineDeps — apps/desktop/src/renderer/src/engine/info.tsIOEngineDeps — apps/desktop/src/renderer/src/engine/io.tsSnap — apps/desktop/src/renderer/src/managers/SnapManager.tsClipboard — apps/desktop/src/renderer/src/managers/ClipboardManager.tsCanvasCoordinatorContext — apps/desktop/src/renderer/src/lib/editor/rendering/CanvasCoordinator.ts# Check if a symbol has any non-definition references
npx tsx scripts/find-refs.ts apps/desktop/src/renderer/src/lib/editor/Editor.ts undo
# Output shows: file, line, kind (definition vs reference)
# Zero non-definition references = confirmed dead
# >0 references = inspect them to confirm usagePresent a categorized report:
| Category | Meaning | Action |
|---|---|---|
| Confirmed dead | No references, not on any interface | Remove with confirmation |
| Likely dead | Ambiguous — few references, possibly test-only | Flag for human review |
| False positive | Interface-mediated, dep interface, or base class | Tag with @knipclassignore |
knip --fix)pnpm typecheck && pnpm test && pnpm lint:checkFor confirmed false positive class members, add the @knipclassignore JSDoc tag:
/** @knipclassignore */
undo(): void {
// ...
}After tagging, decrease the --max-issues threshold in package.json's deadcode:class script:
# Current threshold
pnpm deadcode:class # check current --max-issues value
# After tagging N false positives, reduce by N
# Edit package.json: --max-issues (current - N)
# Verify the new threshold holds
pnpm deadcode:classThe goal is to drive --max-issues toward 0, at which point CI catches any new dead code with zero tolerance.
knip --fix or deadcode:fixpnpm typecheck && pnpm test && pnpm lint:check after removals© shift-editor, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/dead-code of shift-editor/shift.
Open the folder on GitHubat commit e7dacfa
Dead Code Removal with Knip next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Dead Code Removal with Knip this skillshift-editor/shift | 343 | — | ~1.8k | Automated safety check: Pass | Apache-2.0 | |
| DRY Refactoring With jscpdkucherenko/jscpd | 6.3k | — | ~2.1k | Automated safety check: Pass | MIT | |
| Code RefinerMathews-Tom/armory | 327 | — | ~3.1k | Automated safety check: Pass | MIT | |
| Code Simplification for ego-litecitrolabs/ego-lite | 17k | — | ~1.2k | Automated safety check: Pass | MIT | |
| Dep Refszai-org/ZCode | 7.5k | — | ~552 | Automated safety check: Pass | Apache-2.0 | |
| Codebase Health Refactoringkucherenko/jscpd | 6.3k | — | ~2.5k | Automated safety check: Pass | MIT |
kucherenko/jscpd
Removes copy-paste duplication found by jscpd, starting with exact clones and hotspots, then renamed and near-miss copies, using proven refactoring strategies.
Mathews-Tom/armory
Deep code simplification and refactoring preserving behavior across Python, Go, TypeScript, Rust.
citrolabs/ego-lite
Finds and implements evidence-backed simplifications in the ego-lite repository, such as dead code, duplicated state and speculative abstractions, without hiding behavior changes.
zai-org/ZCode
A skill your agent uses when needs to inspect TypeScript export references in the z-code workspace, list exports from a file, verify whether an export is unused before deletion, investigate who…
kucherenko/jscpd
A three-part cleanup guided by jscpd: measure health, then fix duplicated code, remove dead code and simplify the most complex files, finishing by re-measuring the score.
kucherenko/jscpd
Finds duplicated code in 220+ languages with jscpd, reports exact, renamed and near-miss clones in a compact agent-friendly format and measures duplication.
shift-editor/shift
Rules for writing git commits in the Shift font editor repo: Conventional Commits subjects, user-facing changelog wording, concise subjects and logical commit boundaries.
shift-editor/shift
Updates or creates DOCS.md files for Shift subsystems, recording the architecture invariants and constraints that cannot be learned from reading the source.
shift-editor/shift
Fact-checks DOCS.md files against the source code, testing each concrete claim and sorting it as true, false, stale or unverifiable.
shift-editor/shift
Sets the rules for finding, writing and updating Shift GitHub issues: search for duplicates first, use outcome-focused titles and testable acceptance criteria.
shift-editor/shift
Guides writing JSDoc for Shift exported APIs as a stable caller contract, covering ownership, lifetime, side effects and nullability that TypeScript types cannot express.
shift-editor/shift
Rules for preparing, opening and updating pull requests in the Shift repository: Conventional Commit titles, Release Please effects, evidence-based bodies and UI screenshots.
Works with
Categories
Finds unused files, exports and class members with Knip, then verifies each candidate through reference tracing before removing anything, never using knip --fix. Knip is used only to generate candidates, through the project's deadcode and class-member scripts, and the output is sorted into unused files, unused exports and unused class members. The skill warns never to run knip --fix because it once deleted code that was in use, breaking the editor and its tests.
Dead Code Removal with Knip fits situations like: cleaning up unused files and exports in a TypeScript codebase; deciding whether a class member that Knip flags is really unused; reducing codebase size without breaking code Knip cannot trace.
Run `npx skills add shift-editor/shift --skill dead-code -a claude-code`. Or copy the skill folder (.claude/skills/dead-code in shift-editor/shift) into .claude/skills/dead-code in your project. Claude Code loads it when a task matches its description.
Run `npx skills add shift-editor/shift --skill dead-code -a codex`. Or copy the skill folder (.claude/skills/dead-code in shift-editor/shift) into .agents/skills/dead-code in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add shift-editor/shift --skill dead-code -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/dead-code, .gemini/skills/dead-code, .github/skills/dead-code and .opencode/skills/dead-code in your project.
Going by SKILL.md and its folder, Dead Code Removal with Knip needs the command-line tools its instructions call (pnpm and npx). Our summary lists: Knip with the project's deadcode scripts configured; pnpm.
SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Dead Code Removal with Knip is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 1.8k tokens (SKILL.md is roughly 7.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Dead Code Removal with Knip: DRY Refactoring With jscpd (kucherenko/jscpd, 6.3k stars), Code Refiner (Mathews-Tom/armory, 327 stars), Code Simplification for ego-lite (citrolabs/ego-lite, 17k stars) and Dep Refs (zai-org/ZCode, 7.5k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
shift-editor (a GitHub organization) maintains it in shift-editor/shift, which has 343 GitHub stars. The repository holds 14 skills in this directory. The repository was last updated on October 6, 2026.
Source: shift-editor/shift on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.