chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@w3nl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@w3nl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

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

chore(deps): update dependency jscpd to v5 - #123

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x
Open

chore(deps): update dependency jscpd to v5#123
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/jscpd-5.x

Conversation

@renovate

@renovaterenovateBot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
jscpd (source)^4.0.5^5.0.0ageconfidence

Release Notes

kucherenko/jscpd (jscpd)

v5.1.2

Compare Source

v5.1.1

Compare Source

Bug Fixes
  • jscpd on npm installed the 5.0.16 engine instead of 5.1.0 — the jscpd wrapper package published its optionalDependencies pinned to the 5.0.16 platform binaries, so npm i jscpd@5.1.0 resolved a native binary one release behind and jscpd --version reported cpd 5.0.16. Everything 5.1.0 fixed was therefore absent for jscpd users, including the Windows --baseline-from-ref fix. The cpd package was pinned correctly and is unaffected, as are the platform packages themselves — only the wrapper's pins were stale.

    The cause was in scripts/sync-version.mjs: the wrapper's version and its platform pins were updated together behind a single version !== npmVersion guard, so once anything set version before the script ran, the guard read "already up to date" and left the pins untouched. The two are now updated independently, and the script ends by verifying that every npm version and platform pin matches the release version, exiting non-zero if any disagree — the release workflow runs this script, so a repeat of this mismatch now fails the release instead of publishing. This is the same defect that produced the 5.0.13 republish; the earlier fix covered the cpd package but not the jscpd wrapper.

Other
  • Declared MSRV corrected to 1.96 — the workspace advertised rust-version = "1.87" on crates.io, a floor the crate could not build on: the oxc parser crates require 1.96.0, and ignore, globset and askama require 1.88. The value had been set when the Rust workspace was created and never revisited, and no CI job built at the declared MSRV, so the drift went unnoticed. CI now derives the toolchain from rust-version and checks against exactly that version.

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.13 on crates.io
  • cpd-reporter@0.1.11 on crates.io
  • cpd-tokenizer@0.1.12 on crates.io
  • jscpd@5.1.1 on crates.io
  • cpd@5.1.1 on npm
  • jscpd@5.1.1 on npm
  • jscpd-darwin-arm64@5.1.1 on npm
  • jscpd-darwin-x64@5.1.1 on npm
  • jscpd-linux-x64-gnu@5.1.1 on npm
  • jscpd-linux-arm64-gnu@5.1.1 on npm
  • jscpd-linux-x64-musl@5.1.1 on npm
  • jscpd-windows-x64-msvc@5.1.1 on npm
  • jscpd-windows-arm64-msvc@5.1.1 on npm

v5.1.0

Compare Source

New Features
  • Windows on ARM support — npm installs now select a native aarch64-pc-windows-msvc binary from the jscpd-windows-arm64-msvc platform package on Windows ARM64.

  • Clone baseline (--baseline, --update-baseline, --fail-on-new-clones) — gate CI on new duplication only. A committed baseline file (e.g. .jscpd-baseline.json) records content-hash fingerprints of accepted clones (the same hash the SARIF reporter emits as partialFingerprints["jscpdCloneHash/v1"], with a multiplicity count per fingerprint); clones absent from it are reported as new, and --fail-on-new-clones[=N] exits 1 when more than N (default 0) new clones are found — independently of --threshold, so legacy duplication is tolerated while regressions fail the build. --update-baseline rewrites the file from the current run (creating it if missing) and prints added/removed fingerprint counts so baseline growth stays visible in CI logs and PR review. The baseline file is versioned, sorted one fingerprint per line for reviewable diffs and trivial merges, and configurable via the baseline / failOnNewClones config keys. New-clone info flows through the reporters: [NEW] markers and a "(N new)" found-count in console/console-full, per-clone isNew plus the newClones / newDuplicatedLines statistics in json, level error in sarif, and jscpd_new_clones / jscpd_new_duplicated_lines gauges in openmetrics. (#​944)

  • Ephemeral baseline from a git ref (--baseline-from-ref) — stateless variant of the clone baseline for PR gates without a committed file: cpd --baseline-from-ref origin/main --fail-on-new-clones . checks the base ref's tree out into a temporary detached git worktree (removed afterwards; shells out to git like blame does), scans it with the same detection configuration, and compares the current run against that in-memory fingerprint set — clones absent from the base ref are new. Costs a second scan of the corpus, where the committed --baseline file needs only one. When the ref is missing (shallow CI checkout) it fails with a clear hint to git fetch origin main or use fetch-depth: 0. Config key baselineFromRef; conflicts with --baseline / --update-baseline. (#​944)

  • OpenMetrics reporter (--reporters openmetrics) — writes jscpd-metrics.txt in the OpenMetrics text exposition format, ready to be declared as a GitLab CI artifacts:reports:metrics artifact so merge requests show duplication metric changes against the target branch. Exposes gauges for files/lines/tokens analyzed, clones found, duplicated lines/tokens with percentages (project total plus a format-labeled sample per format), and detection duration in seconds. (#​422)

  • CodeClimate / GitLab Code Quality reporter (--reporters codeclimate, alias gitlab) — writes gl-code-quality-report.json (the filename GitLab's docs use) in the CodeClimate issue format, restricted to the subset GitLab defines as its Code Quality report format, ready to be declared as an artifacts:reports:codequality artifact so duplicates appear as code quality issues in merge requests — unlike the SARIF reporter, which GitLab ingests as security vulnerability findings. Each clone yields an issue per fragment (each describing the other location, plus the CodeClimate other_locations field), with a deterministic fingerprint derived from the clone's content hash so GitLab can tell new issues from pre-existing ones across pipeline runs. Severity is minor, escalating to major for clones absent from a configured baseline or when the run exceeds --threshold. (#​958)

  • Config discovery in .config/ (dot-config convention) — auto-discovery now also checks .config/jscpd.json (and .config/.jscpd.json) per the dot-config convention, between the root .jscpd.json and the package.jsonjscpd key. A root .jscpd.json still wins, so existing setups are unaffected; paths inside the config resolve against the working directory, as with other auto-discovered sources. (#​979)

Bug Fixes
  • Unknown --format values warn instead of silently matching nothing — a typo like --format cs (instead of csharp) used to scan 0 files and exit 0, indistinguishable from a clean codebase in CI. The CLI now prints a stderr warning naming the unsupported value and pointing to --list; custom formats declared via --formats-exts stay accepted. (#​964)
  • Nix flake builds again — the flake pinned the hash of the mutable channel-rust-1.97.toml manifest, which broke with a fixed-output hash mismatch when Rust 1.97.1 was published. The toolchain is now pinned to the exact patch version (immutable manifest), so the hash can no longer drift. (#​976)
  • Windows: --baseline-from-ref no longer reports every clone as new — the format-suffix stripper treated the drive colon in Windows verbatim paths (\\?\C:\..., the form canonicalize returns) as a :format suffix and truncated the base scan's source ids to \\?\C, so every snippet read behind the fingerprint computation failed silently and the ephemeral baseline never matched. A colon followed by a path separator is now recognized as structural. Clone fingerprints are also line-ending agnostic now (CR stripped before hashing), so committed baselines survive CRLF/LF differences between platforms.
Other
  • Glama MCP listing — the repository now ships a glama.json maintainer manifest and a Dockerfile that runs the stdio MCP server (jscpd --mcp), used by Glama to build and score the server listing
  • Signed releases — release artifacts are signed with SLSA provenance, and piped downloads in workflows are pinned (OpenSSF Scorecard)
Dependencies
  • Bump Rust toolchain to 1.97.1 and oxc crates to 0.147 in /rust
  • Bump thiserror to 2.0.20, globset to 0.4.20, ignore to 0.4.33, log to 0.4.34 in /rust
Thank You ❤️

Published Packages

  • cpd-core@0.1.10 on crates.io
  • cpd-finder@0.1.12 on crates.io
  • cpd-reporter@0.1.10 on crates.io
  • cpd-tokenizer@0.1.11 on crates.io
  • jscpd@5.1.0 on crates.io
  • cpd@5.1.0 on npm
  • jscpd@5.1.0 on npm
  • jscpd-darwin-arm64@5.1.0 on npm
  • jscpd-darwin-x64@5.1.0 on npm
  • jscpd-linux-x64-gnu@5.1.0 on npm
  • jscpd-linux-arm64-gnu@5.1.0 on npm
  • jscpd-linux-x64-musl@5.1.0 on npm
  • jscpd-windows-x64-msvc@5.1.0 on npm
  • jscpd-windows-arm64-msvc@5.1.0 on npm

v5.0.16

Compare Source

New Features
  • MCP server over stdio (--mcp)cpd --mcp /path/to/project serves the Model Context Protocol on stdin/stdout; the project is scanned once at startup and kept in memory, so check_duplication snippet checks answer in milliseconds. Tools: check_duplication, get_file_clones, get_statistics, check_current_directory. (#​891)
  • Codebase summary (--summary) — opt-in refactoring-hotspot overview: top files and folders ranked by tokens, lines, size, or complexity, with each file's duplication share; --summary-top and --summary-by tune it. (#​934)
  • Isolated folder groups (--skip-isolated) — skip duplication between monorepo folders owned by different teams (--skip-isolated "packages/a|packages/b"); clones inside one folder or against shared code are still reported. Config file: "skipIsolated": [["packages/a", "packages/b"]]. (#​628, #​942)
Security
  • Supply-chain hardening (OpenSSF Scorecard) — GitHub Actions pinned to commit SHAs, least-privilege workflow tokens, SECURITY.md with private vulnerability reporting, protected master branch
Bug Fixes
  • GitHub "Latest" release badge stays on v5 — legacy v4 releases can no longer take the Latest badge from the v5 line
Thank You ❤️
  • @​hanzhangyu for proposing isolated folder groups for monorepos and contributing the original skipIsolated implementation (#​628), which this release ports to the Rust engine

v5.0.15

Compare Source

New Features
  • SARIF: size-based severity — new --sarif-error-tokens <N> flag (also sarifErrorTokens in .jscpd.json): clones with at least N tokens are reported at level error while smaller ones stay warning. When overall duplication exceeds --threshold, all SARIF results are emitted as error. (#​908)
  • SARIF: clone fingerprints — each result carries token_count, a clone_hash, and a partialFingerprints entry (jscpdCloneHash/v1) for cross-run result identity in consumers like GitHub code scanning. (#​909)
  • SARIF: related-location messages — the duplicate's counterpart location now has a message linked from the primary message, so GitHub code scanning displays it. (#​911)
  • SARIF: richer rule metadata — display name, full description, default configuration, and quality tags on the jscpd/duplicate-code rule. (#​914)
Bug Fixes
  • Scan-root-relative report paths — report paths are relative to the scanned directory again (as in 4.x) while reporters can still resolve source files; fixes empty snippets and unresolvable paths when scanning from outside the target directory, including multi-root scans. (#​872, #​892)
  • Report version stamping — SARIF tool.driver.version and the HTML report version now match --version. (#​915)
  • Multi-root blame attribution — git blame data is keyed by resolved path, so a second scan root no longer inherits the first root's authors
  • Git root discovery — walking up from a relative scan path no longer terminates before reaching the repository root
Thank You ❤️

v5.0.14

Compare Source

New Features
  • --cross-formats — detect clones across related formats via format equivalence groups sharing one comparison pool, e.g. --cross-formats "javascript,typescript" or the js-ts preset. When a group mixes TypeScript with JavaScript, TS files are compared with erasable type syntax stripped. Also configurable as crossFormats in .jscpd.json / package.json. (#​810)
Bug Fixes
  • Prose-only Markdown files are now analyzed.md files without code fences previously produced zero tokens and were silently skipped; prose is now tokenized, while embedded code fences keep their own sub-format pools. (#​883)

v5.0.12

Compare Source

Dependencies
  • Rust dependency updates (askama 0.16.0, log 0.4.33, env_logger 0.11.11, rustc-hash 2.1.3)

v5.0.11

Compare Source

New Features
Dependencies
  • cpd-core bumped to 0.1.6, cpd-tokenizer bumped to 0.1.7

v5.0.10

Compare Source

Bug Fixes
  • Emit scan-root-relative paths in all reporters when absolute: false. Fixes #​827
  • Fix --skip-local to match jscpd v4 TypeScript semantics
Refactoring
  • DRY duplication in reporters: extract shared helpers into cpd-reporter/src/shared.rs
  • Move blame enrichment from gitoxide to git blame --porcelain

v5.0.9

Compare Source

New Features
  • GitHub Action for jscpd (Rust v5) — jscpd-copy-paste-detector action for GitHub Actions Marketplace. Scan your repo for copy/paste in CI with uses: kucherenko/jscpd/.github/workflows/action.yml@v5
Bug Fixes
  • Resolve platform binary resolution when cpd is installed as a nested dependency (e.g. in a project's node_modules via a parent package). The runner now correctly locates the platform-specific binary relative to the installed package rather than assuming a top-level install. Fixes #​816

v5.0.8

Compare Source

Bug Fixes
  • Prevent mmap exhaustion crashes when scanning repositories with more files than vm.max_map_count (default 131 072 on Linux). The walker previously held a live Mmap per discovered file; each rayon worker now opens and drops its mapping within the processing closure, capping concurrent mappings to the thread-pool size (typically 8–32). Fixes #​813
  • Fix --pattern not matching relative paths when the scan root is absolute (e.g. CWD). Patterns like src/**/*.ts now match correctly by comparing against both the relative path and the full absolute path, and bare patterns like *.ts gain a **/ prefix to match at any depth. Fixes #​811
  • Fix trailing-newline off-by-one in line-count filter: files not ending with \n now count the final line correctly

v5.0.7

Compare Source

Bug Fixes
  • Prevent stack overflow when scanning directories containing deeply-nested JS/TS files (e.g. Bun's test/bundler with 320K+ nested for-loops). OXC's recursive-descent parser allocates one stack frame per AST nesting level; pathological inputs now exceed the default 8 MiB thread stack. Fixed by building a local rayon ThreadPool with 64 MiB stacks instead of using the global pool (which silently fails on re-init)
  • Default --max-size to 1mb — files exceeding the limit are skipped at walk time, consistent with jscpd v4's maxSize behavior. This prevents OXC from ever seeing megabyte-scale generated files that would overflow the stack
  • --workers N now correctly takes effect on every run() call (previously build_global() silently no-op'd after the first invocation)

v5.0.6

Compare Source

New Features
  • v4 config backward compatibility — .jscpd.json fields path, pattern, ignore, and ignorePattern are now read and applied, matching jscpd v4 behavior
  • ignore and ignorePattern are now distinct: ignore matches file-level globs, ignorePattern matches code-level regex patterns (previously conflated)
  • .jscpd.json path config support — reads scan directories from the path field, resolving relative paths against the config file's directory
  • jscpd npm wrapper package — publishes the same Rust binary under the jscpd name on npm with v5.x versioning
  • --exit-code now matches v4 behavior: accepts optional integer value (--exit-code exits 1, --exit-code 2 exits 2); --threshold and --exit-code are now independent
  • Performance improvements: memory-mapped file I/O (via memmap2) eliminates heap copies of file contents; SIMD-accelerated line counting (via memchr); parallel detection pipeline uses flat_map to avoid intermediate allocations; JS tokenizer no longer clones source strings before parsing (thanks to @​auterium, #​808)
Bug Fixes
  • Fixed --exit-code to match jscpd v4's --exitCode behavior (was boolean, now optional integer)
  • Fixed unique temp dir generation in reporter tests (added PID to prevent race conditions under parallel test runners)

v5.0.5

Compare Source

v5.0.4

Compare Source

New Features
  • CLI alignment with jscpd v4: new --absolute, --ignore-case, --formats-exts, --formats-names flags; fixed --threshold, improved --max-size
  • Detection and statistics aligned with jscpd for consistent output across Rust and TypeScript versions
  • Side-by-side blame comparison in console-full reporter
  • Clone list display in console reporter
Bug Fixes
  • HTML reporter now outputs jscpd-report.html at the output_dir root
  • Resolved all clippy warnings across workspace
  • Fixed unique temp dir generation in tests (use as_nanos() instead of subsec_nanos())


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@w3nl

w3nl commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

StatusScan Engine Critical High Medium LowTotal (0)
Open Source Security0000 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 2 times, most recently from c65cf38 to c73a4c6CompareJuly 19, 2026 18:28
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 0c222b8 to 5cdfadcCompareAugust 2, 2026 20:37
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 5 times, most recently from 84823dd to b131b2dCompareAugust 18, 2026 16:49
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch 3 times, most recently from 7dd1cbe to 4b52cbbCompareSeptember 1, 2026 15:52
@renovate
renovateBotforce-pushed the renovate/jscpd-5.x branch from 4b52cbb to 54b48e3CompareSeptember 3, 2026 12:01
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@w3nl