unstale

npm / jscpd

jscpd

What changed in jscpd 4 to 5, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.

14 breaking6 security1 deprecations120 new APIs and options4 performance15 behavior and defaults8 tooling70 fixes and other

See which of these apply to your code, ranked, in your agent:

npx @unstale/cli init

@unstale/cli on npm

jscpd 5211 changes

Breaking changes 11

  • The minimum Rust version is now 1.97.

    5.4.1release notes

  • Compares function structure across 15 languages and supported code blocks using Jaccard similarity. It finds every pair meeting the ratio; scores differ from 5.4.0, and a ratio of 1 now reports identical structures.

    5.4.1release notes

  • Similarity pairs now use their own SARIF rule instead of jscpd/similar-code, changing alert identity for GitHub code scanning and Code Climate check names.

    5.4.0release notes

  • Ignore-pattern matching in files with CRLF endings now removes the intended tokens, which can change clone token counts.

    5.3.3release notes

  • Dead-code configuration precedence is flag over the deadCode section over older top-level keys; misspelled keys in the section are reported by name.

    5.3.1release notes

  • Unknown formats, nonexistent scan paths, and reporter file-write failures now print an error and exit 1 instead of passing with an empty report.

    5.2.1release notes

  • The declared minimum Rust version is corrected to 1.96, the floor required to build the crate.

    5.1.1release notes

  • The CLI binary and platform npm packages are now named jscpd / jscpd-* instead of cpd / cpd-* to avoid antivirus false positives.

    5.0.12release notes

  • When absolute is false or unset, all reporters now emit paths relative to the canonicalized scan root and strip leading ./ or .\ components.

    5.0.10release notes

  • Now filters clones whose fragments are under the same scan root, matching jscpd v4 TypeScript semantics rather than limiting the filter to the same parent directory.

    5.0.10release notes

  • File-level globs and code-level regex patterns are no longer conflated.

    5.0.6release notes

Security 4

  • An API key echoed by an embeddings API in an error is now redacted.

    5.4.1release notes

  • Dashboard and health reports, including markdown and HTML output, escape untrusted file paths, custom format names and external metric IDs before rendering.

    5.3.0release notes

  • Each release archive and checksums.txt now has a Sigstore keyless signature that can be verified with this command.

    5.1.2release notes

  • The SARIF schema URI now uses HTTPS, avoiding "untrusted URI" errors in SARIF-consuming tools.

    5.0.12release notes

Deprecations 1

  • The ineffective flag is hidden from help and warns when passed, but remains accepted; use --threshold, --min-lines, or --min-tokens for the stated purposes.

    5.3.3release notes

New APIs and options 113

  • Selects the file used to save or read the baseline for --changed.

    5.4.1release notes

  • Reports clones involving files listed by git status, including staged, unstaged and untracked files, while still scanning every file. A baseline marks clones absent from HEAD as [NEW].

    5.4.1release notes

  • Scans only changed files and matches them only against one another.

    5.4.1release notes

  • The MCP server adds compare_folders(left, right), which returns the JSON report of --compare for two folders.

    5.4.1release notes

  • The -r edn reporter writes jscpd-report.edn, including similarity candidates with scores, languages, locations and node counts, plus clones found by other passes.

    5.4.1release notes

  • MCP tools accept clone kinds to report, including exact, renamed, similar, semantic, or type1 through type4.

    5.4.1release notes

  • Sets the smallest normalized function tree considered by similarity matching; defaults to 20.

    5.4.1release notes

  • The JSON report now gives the node count of both functions in a similarity result.

    5.4.1release notes

  • Sets the base name for JSON, XML, CSV, HTML, Markdown, SARIF and EDN report files to avoid collisions in a shared reports folder.

    5.4.1release notes

  • An installable agent skill guides test-first codebase ports, binding tests to code by coverage and selecting functions to port from --compare.

    5.4.0release notes

  • An installable agent skill explains how --compare pairs functions and how to check a comparison.

    5.4.0release notes

  • Compares two codebases by pairing functions with the semantic model, reporting counterparts, unmatched functions, similarity levels, and functions ready to port.

    5.4.0release notes

  • Starts a language server that reports diagnostics for edited buffers, supports configurable analyses, and provides clone actions and project-wide custom requests.

    5.4.0release notes

  • Selects which language-server analyses to enable; clones are enabled by default, and editor settings can override this option.

    5.4.0release notes

  • Lowers smaller clone diagnostics from warnings to information in the language server.

    5.4.0release notes

  • Provides the API key for semantic embeddings requests; jscpd reads it only from this environment variable.

    5.3.3release notes

  • The semantic value filters results to semantic clones.

    5.3.3release notes

  • Replaces the instruction prefix jscpd adds before functions for models that expect one.

    5.3.3release notes

  • Downloads a semantic embedding model before scanning; the default model runs locally on the CPU.

    5.3.3release notes

  • Selects a semantic embedding model by its listed name, Hugging Face id, or Ollama name.

    5.3.3release notes

  • Lists the calibrated semantic models, including their thresholds, licenses, and execution locations.

    5.3.3release notes

  • Re-embeds all functions and replaces the semantic vector cache file at once.

    5.3.3release notes

  • Sets the minimum cosine similarity for a semantic clone pair within one language; thresholds vary by model.

    5.3.3release notes

  • Restricts semantic clone pairs to the same language or to different languages.

    5.3.3release notes

  • Sets the minimum cosine similarity for a semantic clone pair across languages; thresholds vary by model.

    5.3.3release notes

  • Sends functions to an OpenAI-compatible embeddings API; the API key is read only from JSCPD_SEMANTIC_API_KEY.

    5.3.3release notes

  • Experimental semantic clone detection embeds supported functions and reports sufficiently similar pairs as semantic clones.

    5.3.3release notes

  • The semantic config key enables experimental semantic clone detection.

    5.3.3release notes

  • The dead-code config section accepts a Rust diagnostics file, allowing Rust compiler diagnostics to be used for dead-code reporting.

    5.3.2release notes

  • jscpd accepts compiler JSON diagnostics via a file or pipe for dead-code, dashboard, and health runs, enabling Rust dead-code reporting without running cargo.

    5.3.2release notes

  • basta discovers framework definitions from basta.frameworks.yaml, basta.frameworks.yml or basta.frameworks.json in the working directory.

    5.3.1release notes

  • The standalone basta binary accepts -c, --config <file> to select its configuration file.

    5.3.1release notes

  • The .jscpd.json deadCode setting can be an object with enabled, categories, confidence and line thresholds, entry and ignore settings, reporting controls, and framework settings. The object enables the mode only when enabled is true; the existing boolean switch still works.

    5.3.1release notes

  • Treats a named framework as present, useful when a scan starts below its package.json.

    5.3.1release notes

  • Loads custom framework definitions from a YAML or JSON file; definitions can add frameworks or replace built-ins with the same name.

    5.3.1release notes

  • Framework definitions can declare names looked up in code; declarations with those names are treated as used, and the names-and-files form scopes them to selected files.

    5.3.1release notes

  • Prints the list of framework definitions.

    5.3.1release notes

  • Turns framework detection off.

    5.3.1release notes

  • The dashboard JSON adds project.largestFiles, containing the ranked list of largest code files.

    5.3.1release notes

  • Dead-code threshold can be set inside deadCode; if omitted there, a dead-code run still falls back to the top-level threshold.

    5.3.1release notes

  • The dead-code analysis engine is also available as a standalone command.

    5.3.0release notes

  • Reports complexity without running a clone scan, providing the complexity portion of --summary.

    5.3.0release notes

  • Adds a one-run report combining health information, project size, duplication by format, complex files and dead-code findings by category.

    5.3.0release notes

  • Finds unused files, exports and imports across JavaScript, TypeScript, Vue, Svelte, Astro and Python using the project's import graph and real entry points; findings include confidence scores.

    5.3.0release notes

  • Adds a 0–100 health score with an A–E grade based on duplication, dead code and complexity, adjusted for project size and excluding unmeasurable dimensions.

    5.3.0release notes

  • Lets you plug custom metrics, such as coverage or security scan results, into the health score.

    5.3.0release notes

  • Adds HTML output for both dashboard and health reports.

    5.3.0release notes

  • Filters clones by whether they were found as exact, renamed or similar matches; similar matches distinguish gap merges from structural matches, and typos are caught.

    5.3.0release notes

  • Adds markdown output for both dashboard and health reports.

    5.3.0release notes

  • Makes a run fail when no files were analyzed, so a mistyped path or over-broad ignore cannot look like a clean run.

    5.2.1release notes

  • Adds a GitHub Action input that makes a run fail when no files were analyzed.

    5.2.1release notes

  • Makes a run fail when no files were analyzed, so a mistyped path or over-broad ignore cannot look like a clean run.

    5.2.1release notes

  • Scans every commit in a Git range and prints duplication trends, per-commit changes, and how far --threshold could be tightened without failing the build.

    5.2.1release notes

  • Adds a flag to narrow the commit range scanned by --history.

    5.2.1release notes

  • Adds a flag to narrow the commit range scanned by --history.

    5.2.1release notes

  • Adds a flag to narrow the commit range scanned by --history.

    5.2.1release notes

  • The JSON reporter includes history points under a new history key.

    5.2.1release notes

  • The GitHub Action accepts a history input for duplication trend scans.

    5.2.1release notes

  • The MCP check_duplication tool accepts the similarity argument for function-level similarity detection.

    5.2.0release notes

  • Reporters distinguish renamed and similar clones; JSON and XML include clone metadata, statistics expose renamedClones and similarClones, and SARIF and Code Climate use dedicated rules.

    5.2.0release notes

  • Drops supported annotation runs before hashing so code blocks that differ only in annotations can be detected as renamed clones.

    5.2.0release notes

  • Normalizes identifiers before hashing so code blocks that differ only in names can be detected as renamed clones.

    5.2.0release notes

  • Normalizes literal values before hashing so code blocks that differ only in literals can be detected as renamed clones.

    5.2.0release notes

  • Drops supported annotation runs before hashing so code blocks that differ only in annotations can be detected as renamed clones.

    5.2.0release notes

  • Normalizes identifiers before hashing so code blocks that differ only in names can be detected as renamed clones.

    5.2.0release notes

  • Normalizes literal values before hashing so code blocks that differ only in literals can be detected as renamed clones.

    5.2.0release notes

  • Every clone carries a kind of exact or renamed; runs without the new normalization flags remain unchanged apart from the additive exact JSON field.

    5.2.0release notes

  • Merges nearby clone fragments from one file pair into a similar clone when at most N unmatched lines separate them in both files; defaults to off.

    5.2.0release notes

  • Merges nearby clone fragments from one file pair into a similar clone when at most N unmatched lines separate them in both files; defaults to off.

    5.2.0release notes

  • Compares JavaScript and TypeScript functions, methods, and arrow functions by syntax-tree 4-grams and reports pairs meeting the ratio as similar clones.

    5.2.0release notes

  • Compares JavaScript and TypeScript functions, methods, and arrow functions by syntax-tree 4-grams and reports pairs meeting the ratio as similar clones.

    5.2.0release notes

  • npm installs on musl-based ARM64 Linux systems now select a native prebuilt binary from this platform package.

    5.1.2release notes

  • Compare current clones with fingerprints scanned from a base Git ref using a temporary detached worktree, without a committed baseline file.

    5.1.0release notes

  • Use a committed baseline of accepted clone fingerprints so CI can distinguish new duplication from legacy duplication.

    5.1.0release notes

  • Configure the committed clone baseline file with the baseline config key.

    5.1.0release notes

  • Configure the Git ref used as an ephemeral clone baseline.

    5.1.0release notes

  • Add .config/.jscpd.json to automatic config discovery.

    5.1.0release notes

  • Add .config/jscpd.json to automatic config discovery, after the root .jscpd.json and before the package.json jscpd key.

    5.1.0release notes

  • Exit 1 when new clones exceed the specified count, defaulting to zero, independently of --threshold.

    5.1.0release notes

  • Configure the maximum number of new clones allowed before the run fails.

    5.1.0release notes

  • npm installs on Windows ARM64 now select a native binary from this platform package.

    5.1.0release notes

  • Report new clones through console markers and counts, JSON fields and statistics, SARIF errors, and OpenMetrics gauges.

    5.1.0release notes

  • Select a CodeClimate/GitLab Code Quality reporter that writes gl-code-quality-report.json with clone issues and deterministic fingerprints.

    5.1.0release notes

  • Add gitlab as an alias for the CodeClimate/GitLab Code Quality reporter.

    5.1.0release notes

  • Select a reporter that writes OpenMetrics text exposition to jscpd-metrics.txt, including duplication and detection-duration gauges.

    5.1.0release notes

  • Rewrite the baseline from the current run, creating it if missing, and print added and removed fingerprint counts.

    5.1.0release notes

  • The MCP server provides a tool that returns the clone list.

    5.0.16release notes

  • The MCP server provides snippet checks that accept format names or file extensions.

    5.0.16release notes

  • The MCP server provides clone lookup for one file, a capability described as new over the HTTP server.

    5.0.16release notes

  • The MCP server provides a statistics tool.

    5.0.16release notes

  • Starts an MCP server over stdio, scanning the project once and keeping detection-ready token hashes in memory for snippet checks. Standard detection options apply to the scan and snippet checks.

    5.0.16release notes

  • Accepts comma-separated isolation groups of pipe-separated folders and drops clones whose fragments fall under different folders of the same group. It also applies to MCP project scans.

    5.0.16release notes

  • Accepts a nested-array shape to declare isolated folder groups in the config file.

    5.0.16release notes

  • Opts into a refactoring-hotspot overview appended to run output, ranking top files and folders by a selected metric and showing each file's duplication share.

    5.0.16release notes

  • Selects whether the codebase summary ranks by tokens, lines, size, or a token-based cyclomatic-complexity estimate.

    5.0.16release notes

  • Sets the list length for the codebase summary.

    5.0.16release notes

  • The config-file setting enables the refactoring-hotspot summary.

    5.0.16release notes

  • When the summary flag is enabled, the JSON report adds a summary key; it is absent when the flag is off, preserving the schema for existing consumers.

    5.0.16release notes

  • Selects the codebase summary ranking metric in the config file.

    5.0.16release notes

  • Sets the codebase summary list length in the config file.

    5.0.16release notes

  • SARIF results include an order-insensitive clone hash for cross-run identity, alongside token_count and clone_hash in the properties bag.

    5.0.15release notes

  • Reports clones with at least N tokens as SARIF errors and smaller clones as warnings; when overall duplication exceeds --threshold, all SARIF results are errors.

    5.0.15release notes

  • Sets the token count at which clones are reported as SARIF errors; when overall duplication exceeds --threshold, all SARIF results are errors.

    5.0.15release notes

  • Detect clones across related formats using comparison groups, including the js-ts preset; TypeScript is compared with erasable type syntax stripped when grouped with JavaScript.

    5.0.14release notes

  • Configure cross-format clone detection in .jscpd.json or package.json with a string, array of strings, or array of arrays.

    5.0.14release notes

  • Adds a tokenizer for Razor files that parses HTML content and Razor keyword blocks.

    5.0.11release notes

  • The path config field reads scan directories and resolves relative paths against the config file's directory.

    5.0.6release notes

  • Adds the --absolute CLI flag as part of alignment with jscpd v4.

    5.0.4release notes

  • The console reporter displays a clone list.

    5.0.4release notes

  • The console-full reporter adds side-by-side blame comparison.

    5.0.4release notes

  • Adds the --formats-exts CLI flag as part of alignment with jscpd v4.

    5.0.4release notes

  • Adds the --formats-names CLI flag as part of alignment with jscpd v4.

    5.0.4release notes

  • Adds the --ignore-case CLI flag as part of alignment with jscpd v4.

    5.0.4release notes

Performance 3

  • The module index can quickly determine whether a path could name a module under any extension or as a directory index, avoiding expensive resolver misses for catch-all aliases.

    5.3.1release notes

  • basta checks whether an alias pattern matches an import before comparing paths, substantially reducing dead-code scan time on projects with many aliases without changing findings.

    5.3.1release notes

  • Memory-mapped file I/O, SIMD line counting, a parallel detection pipeline, and avoiding tokenizer source-string clones improve performance and reduce allocations.

    5.0.6release notes

Behavior and default changes 12

  • The MCP tool now finds every copy of a snippet instead of matching one of two.

    5.4.1release notes

  • The Project section ranks the largest code files by lines, with tokens and size; json, markdown and html reporters include the same list.

    5.3.1release notes

  • basta detects frameworks from built-in definitions and keeps files they load alive, checking each scanned-file directory independently.

    5.3.1release notes

  • basta reads the deadCode section from the same configuration file as jscpd and searches .jscpd.json, .config/jscpd.json or package.json by default.

    5.3.1release notes

  • The top-level minLines remains a clone-reporting setting and is not applied to dead-code runs; dead-code minLines is configured inside deadCode.

    5.3.1release notes

  • Nitro framework detection follows srcDir and treats tasks/ as framework-loaded.

    5.3.1release notes

  • The --summary --summary-by complexity estimate more closely tracks cyclomatic complexity, accounting for short-circuit operators and language-specific branches and measuring complexity per function.

    5.3.0release notes

  • Tips and sponsor lines print only on an interactive terminal, preventing them from appearing in piped output, files, CI logs, or agent hooks.

    5.2.0release notes

  • The counterpart location gets a message and the primary message links to it, enabling GitHub code scanning to display the relationship.

    5.0.15release notes

  • A CLI option now accepts an optional integer value, with distinct exit codes; two options are now independent.

    5.0.6release notes

  • Several previously unsupported v4 configuration fields are now read and applied, matching jscpd v4 behavior.

    5.0.6release notes

  • Improves the --max-size CLI flag.

    5.0.4release notes

Tooling 7

  • The release publishes platform wheels installable with pip or uvx, providing the Rust engine without Python code or a Node.js runtime.

    5.2.1release notes

  • The four MCP tools now include titles, read-only annotations, parameter descriptions with examples and defaults, and descriptions of use and return values; server instructions describe the workflow.

    5.2.0release notes

  • The crate now provides cargo-binstall metadata so this command downloads a prebuilt binary instead of compiling the oxc parser stack from source.

    5.1.2release notes

  • A multi-arch amd64/arm64 distroless Docker image built from release binaries is published with every release.

    5.1.2release notes

  • The SARIF rule now includes a display name, full description, default configuration, and quality tags for improved presentation in SARIF viewers and Azure DevOps.

    5.0.15release notes

  • A GitHub Action is available to scan repositories for copy/paste in CI.

    5.0.9release notes

  • An npm package publishes the same Rust binary with v5.x versioning.

    5.0.6release notes

Fixes and other changes 60

  • Comparison fixes include counting test helpers among call namesakes, recognizing .NET test projects wherever Tests appears in a dotted name, and aligning console and HTML percentages; declarations without bodies no longer count as functions.

    5.4.1release notes

  • Imports referenced in TSDoc links and JavaScript JSDoc types now count as used; documentation-only references do not make a function live.

    5.4.1release notes

  • Git subprocesses drop variables exported to hooks, refs or history ranges beginning with - are refused, and worktree cleanup preserves the user's other worktrees.

    5.4.1release notes

  • Ignored ranges now align with offsets in Markdown fences, component scripts and Razor blocks, so the intended tokens are excluded.

    5.4.1release notes

  • The MCP server no longer ignores --semantic.

    5.4.1release notes

  • C, C++ and C# scans no longer treat control-flow keywords around preprocessor directives as phantom functions or count every matching keyword call.

    5.4.1release notes

  • Svelte store reads using $name and template-literal placeholders in component markup now count as uses, avoiding false unused-symbol findings.

    5.3.3release notes

  • Files under a scanned path that is nested inside another scanned path are read once instead of twice, preventing self-clones and duplicate semantic embeddings.

    5.3.3release notes

  • JSON report positions for files with CRLF endings now use true byte offsets.

    5.3.3release notes

  • Embedded sources now count only the lines occupied by their code blocks, and clones count the block lines they cover, preventing surrounding prose or templates from inflating line totals.

    5.3.2release notes

  • Duplicated-line counts now include both the start and end lines of each clone, so totals rise by about one line per clone and percentages rise with them.

    5.3.2release notes

  • Alembic is detected as a framework, preventing its loaded files from being reported unused.

    5.3.1release notes

  • Django is detected as a framework, so migrations, management commands, admin.py, apps.py, template tags and modules named by dotted settings paths are not incorrectly reported unused.

    5.3.1release notes

  • The markup block of a component file tokenized as html is excluded from the duplication share, matching css and scss blocks.

    5.3.1release notes

  • Markup, stylesheet and template files now have complexity 0 and are excluded from the health score's code count; component script blocks still count.

    5.3.1release notes

  • The JSON report can include path-appears-in-string as a reason when a file's extensionless path appears in a string literal; this reduces its confidence by 40 points.

    5.3.1release notes

  • Static require calls using a template literal with no interpolation are recognized.

    5.3.1release notes

  • Scrapy is detected as a framework, preventing its loaded files from being reported unused.

    5.3.1release notes

  • Arrow functions in component attributes no longer cause the tag parser to mistake the arrow's > for the end of the tag and fail parsing the script.

    5.3.1release notes

  • A leading slash in a Vite alias target is resolved from the project root rather than the filesystem root, preventing imported components from being reported unused.

    5.3.1release notes

  • A wxt.config.* marks entrypoints and auto-import directories as entries, honors srcDir, entrypointsDir and imports: false, and declares conventional aliases.

    5.3.1release notes

  • Plain text, log and CSV files now handle comments differently; the notes do not specify further details.

    5.3.0release notes

  • With --fail-on-empty, complexity mode writes its reports before failing, matching other modes.

    5.3.0release notes

  • Dashboard and health reports omit the dead-code section rather than failing when --format excludes every analyzable language.

    5.3.0release notes

  • Excluding markup duplication from scoring now properly excludes it on both sides of the calculation.

    5.3.0release notes

  • A mistyped field no longer invalidates the whole configuration; only the bad field is dropped and the rest still applies.

    5.3.0release notes

  • Values above 100 are clamped with a warning everywhere the option is read, not only in standalone dead-code mode.

    5.3.0release notes

  • Windows report paths now use forward slashes consistently with other platforms.

    5.3.0release notes

  • Clone growth now checks whether the clone's own anchor continues and starts a new clone otherwise, preventing N-way copies from losing pairs or producing mismatched ends.

    5.2.1release notes

  • Prints the --history block, matching the console reporter.

    5.2.1release notes

  • Files retain the path they were found at, and each real file is scanned once, avoiding renamed paths, duplicate sources, and self-clones through symlinks.

    5.2.1release notes

  • Replaces XML 1.0-invalid characters with U+FFFD, splits ]]> across CDATA sections, and escapes paths once so generated reports can be parsed.

    5.2.1release notes

  • Config-file entries are now applied verbatim instead of being treated as relative paths, so patterns without * or ? work; invalid regexes produce a warning.

    5.2.0release notes

  • Files with recoverable parser diagnostics now use lexer tokens unless parsing fails outright, allowing them to match clean files.

    5.2.0release notes

  • Markdown no longer inherits C comment syntax, preventing prose containing /* or // from swallowing the rest of a file during clone detection.

    5.2.0release notes

  • Vue template tokens are kept in source order and wrapper tags are excluded, correcting template clone line ranges and preventing script and style bodies from counting as duplicated HTML.

    5.2.0release notes

  • The pre-commit hook now passes the v5 CLI flag --exit-code 1 instead of rejected v4-only flags, so repository hooks no longer fail on every run.

    5.1.2release notes

  • The version output and help usage line now use the invoked executable name, jscpd or cpd, instead of always saying cpd.

    5.1.2release notes

  • On Windows, drive-anchored pattern values such as C:\src\**\*.ts are now treated as absolute instead of also receiving a relative **/ variant.

    5.1.2release notes

  • When no prebuilt binary matches, npm launchers name the host, list supported platform keys, and point to cargo install jscpd.

    5.1.2release notes

  • The floating GitHub Action tag v5 follows the latest 5.x release and is moved on every stable release.

    5.1.2release notes

  • The npm wrapper now pins its platform binaries to the release version, so installing jscpd no longer resolves a native binary one release behind.

    5.1.1release notes

  • On Windows, ephemeral baselines now match clone fingerprints instead of reporting every clone as new.

    5.1.0release notes

  • Fingerprint hashing strips CR characters, so committed baselines survive CRLF/LF differences between platforms.

    5.1.0release notes

  • Unsupported format values now produce a stderr warning naming the value and pointing to --list instead of silently scanning zero files.

    5.1.0release notes

  • Pinning the Rust toolchain to an exact patch version fixes flake builds that failed when the mutable Rust manifest changed.

    5.1.0release notes

  • Walking up from a relative scan path no longer stops before reaching the repository root.

    5.0.15release notes

  • Git blame data is keyed by resolved path when multiple scan roots contain the same relative path, preventing the second root from inheriting the first root's authors.

    5.0.15release notes

  • The SARIF tool driver and HTML report versions now match cpd --version instead of using a hardcoded SARIF version.

    5.0.15release notes

  • Report paths are relative to the scanned directory while reporters can still resolve and read source files, fixing empty snippets and unresolvable paths, including in multi-root scans.

    5.0.15release notes

  • Markdown prose is now tokenized, so prose-only files are analyzed and duplicated prose can be detected as clones; embedded code fences remain detected under their own sub-format pools.

    5.0.14release notes

  • Lisp, Clojure, Scheme, and Racket semicolon comments are recognized as comments, allowing --mode weak and --skip-comments to drop them.

    5.0.12release notes

  • When installed as a nested dependency, the runner locates the platform-specific binary relative to the installed package instead of assuming a top-level install.

    5.0.9release notes

  • The walker opens and drops each file mapping within the processing closure, capping concurrent mappings to the thread-pool size and preventing mmap exhaustion crashes.

    5.0.8release notes

  • Patterns match against both the relative path and the full absolute path when the scan root is absolute; bare patterns gain a prefix to match at any depth.

    5.0.8release notes

  • Scanning directories with deeply nested JS/TS files no longer risks stack overflow; parsing uses a local rayon pool with 64 MiB stacks.

    5.0.7release notes

  • Files exceeding the size limit are skipped during directory walking, preventing OXC from processing megabyte-scale generated files.

    5.0.7release notes

  • Detection and statistics are aligned with jscpd for consistent output across Rust and TypeScript versions.

    5.0.4release notes

  • The HTML reporter now outputs jscpd-report.html at the output_dir root.

    5.0.4release notes

  • Fixes the --threshold CLI flag.

    5.0.4release notes

jscpd 427 changes

Breaking changes 3

  • The server now binds to 127.0.0.1 by default.

    4.3.0release notes

  • Custom mappings that assign .vue to markup no longer take effect because .vue is handled by the dedicated vue format processor.

    4.2.0release notes

  • Vue SFC blocks are tokenized and reported under their resolved sub-format names instead of markup; tooling relying on markup reports must be updated.

    4.2.0release notes

Security 2

  • Adds a Host allowlist option for DNS-rebinding protection on both /mcp and the REST API.

    4.3.0release notes

  • Adds an Origin allowlist option for DNS-rebinding protection on both /mcp and the REST API.

    4.3.0release notes

New APIs and options 7

  • Adds a config key to override automatic ANSI color detection; explicit flag or config settings take precedence over FORCE_COLOR, NO_COLOR, and TTY detection.

    4.3.0release notes

  • Adds a flag to override automatic ANSI color detection.

    4.3.0release notes

  • Adds a flag to disable ANSI colors, overriding automatic detection.

    4.3.0release notes

  • Maps specific filenames, such as Makefile and Dockerfile, to a detection format.

    4.2.0release notes

  • Extensionless executable scripts are detected from their #! shebang line and tokenized in the corresponding language.

    4.2.0release notes

  • Adds a shorthand flag for --mode weak, which strips comments before detection.

    4.2.0release notes

  • Configures a custom directory for the LevelDB cache, avoiding collisions when multiple jscpd processes run in parallel on the same machine.

    4.2.0release notes

Performance 1

  • The new self-contained reprism-based grammar engine replaces prismjs and improves tokenization speed by about 11.5% on real projects.

    4.2.0release notes

Behavior and default changes 3

  • ANSI colors are disabled automatically when stdout is not a TTY, including for the statistics table.

    4.3.0release notes

  • jscpd-server migrates to the official MCP SDK v2 and stateless 2026-07-28 revision, with a legacy fallback for 2025-era clients.

    4.3.0release notes

  • Vue, Svelte, Astro, and Markdown files are tokenized per block or section, allowing their code to match files in the corresponding language.

    4.2.0release notes

Tooling 1

  • Support increased from 152 to 223 formats, including Apex, CFML/ColdFusion, GDScript, Svelte, and Astro.

    4.2.0release notes

Fixes and other changes 10

  • Skips the progress announcer for ai and consoleFull reporters that print every clone themselves, preventing duplicate output.

    4.3.0release notes

  • Server output now respects NO_COLOR and FORCE_COLOR and detects TTY status like the CLI.

    4.3.0release notes

  • Fixes off-by-one source line counts in statistics and reports.

    4.3.0release notes

  • Ignore files in parent directories up to the repository root are combined with scan-directory ignore files; Git info and global excludes are also read.

    4.2.5release notes

  • Duplicate token counts in JSON output are now computed from token positions.

    4.2.5release notes

  • The Commander upgrade enables modern Node.js compatibility.

    4.2.5release notes

  • Complete copies of files are detected instead of being silently dropped when RabinKarp flushes a pending clone.

    4.2.0release notes

  • Replaces a catastrophically backtracking Lisp string regex with a linear pattern, preventing hangs on unterminated strings.

    4.2.0release notes

  • Invalid JSON now produces a warning and an empty config instead of an unhandled SyntaxError that crashes the process.

    4.2.0release notes

  • Tokens on the first line of a Vue SFC block now use file-absolute rather than block-relative column numbers.

    4.2.0release notes