Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - nikhaldi/drywall: A Claude Code plugin for detecting and eliminating code duplication using jscpd · GitHub
Skip to content

Repository files navigation

DRYwall

A Claude Code plugin for detecting and eliminating code duplication using jscpd.

DRY = Don't Repeat Yourself

This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.

Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication. This blog post provides some background.

Installation & Quickstart

Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).

Open Claude Code and add the marketplace, then install the plugin:

/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall

To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:

/drywall:scan

If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):

Deduplicate code in this codebase

Configuration

Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below. Example config:

{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "5.0.12"
}

The configuration options specific to DRYwall are:

  • respectGitignoretrue by default. Files excluded by .gitignore are automatically skipped. Set to false to disable.
  • jscpdVersion — Pin the jscpd version used via npx. Defaults to 5.0.12 if not set. The older 4.x Node-core line is also supported by pinning e.g. "4.2.5"; note that some jscpd CLI options changed between 4.x and 5.x, so options in your config must match the pinned major version.
  • maxDuplicates — Maximum number of duplicate pairs to return, ranked by impact. Defaults to 20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)
  • maxFragmentLength — Maximum character length of each code fragment before truncation. Defaults to 500.

Ignored code blocks

If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-endmarkers in the code. JavaScript example:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */

Components

Skill: /drywall:scan

Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.

Invoke within a Claude Code session with:

/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10

Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).

Agent: dedup-refactor

An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.

MCP Tool: detect_code_duplication

Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.

Parameters:

  • path — directory to scan (default: .)
  • options — object of jscpd options passed as CLI flags. Keys are camelCase and converted to --kebab-case flags (e.g., {"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})
  • maxDuplicates — maximum number of duplicate pairs to return, ranked by impact (default: 20)
  • maxFragmentLength — maximum character length of each code fragment before truncation (default: 500)

Development

npm install
npm test
npm run build

To test the plugin locally in Claude Code:

claude --plugin-dir /path/to/drywall

License

This project is licensed under the MIT License.

About

A Claude Code plugin for detecting and eliminating code duplication using jscpd

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages