fix-jscpd

star 347

Decision framework for fixing jscpd (copy-paste detector) errors. Use when asked to fix jscpd issues, copy-paste errors, clones or COPYPASTE lint failures.

hardisgroupcom By hardisgroupcom schedule Updated 5/19/2026

name: fix-jscpd description: Decision framework for fixing jscpd (copy-paste detector) errors. Use when asked to fix jscpd issues, copy-paste errors, clones or COPYPASTE lint failures. user-invocable: false

Fixing jscpd / Copy-Paste Issues

When jscpd reports a clone, decide between factorization and ignore comments based on these criteria.

Decision Criteria

Factorize when

  • The duplicate logic is semantically identical and would not diverge (same intent, same data shape).
  • Extracting it produces a clean, named helper with a clear single responsibility.
  • The helper is small (under ~15 lines) and self-contained.
  • The duplication is within the same file or a closely related module.

Examples in this project: buildPersonaCols(n) in profiles-extract.ts, formatLimitLine(limit) in limits.ts.

Ignore with /* jscpd:ignore-start */ / /* jscpd:ignore-end */ when

  • The clones are in separate, unrelated command files (each command is a standalone unit).
  • The structure is the same but the data shapes or intent diverge (e.g., different result fields in different audit commands).
  • The duplication is unavoidable boilerplate (standard flags: agent, debug, websocket, skipauth).
  • Extracting would add indirection with no real benefit (e.g., buildInitialMarkdownLines in different DocBuilder subclasses).

Ignore Comment Placement

Place /* jscpd:ignore-start */ on the line before the first duplicate line, and /* jscpd:ignore-end */ on the line after the last duplicate line. Keep the comments on their own lines, indented to match the surrounding code.

/* jscpd:ignore-start */
for (const catcher of catchers) {
  const results = await catchMatches(catcher, file, fileText, this);
  this.matchResults.push(...results);
}
/* jscpd:ignore-end */

Factorization Pattern

Add a private (or private static) helper method to the enclosing class, or a module-level function if the logic is pure and stateless.

private static formatLimitLine(limit: any): string {
  return `• ${limit.name}: *${limit.percentUsed}%* used (${limit.used}/${limit.max})`;
}

Then replace the duplicate .map(...) blocks with .map(MyClass.formatLimitLine).

Standard Flag Boilerplate

The agent, debug, websocket, and skipauth flags appear in every command. These are always intentional duplicates - wrap them with jscpd:ignore rather than abstracting.

Install via CLI
npx skills add https://github.com/hardisgroupcom/sfdx-hardis --skill fix-jscpd
Repository Details
star Stars 347
call_split Forks 96
navigation Branch main
article Path SKILL.md
More from Creator
hardisgroupcom
hardisgroupcom Explore all skills →