Skip to content

chore(deps): update npm dependencies updates - #96

Open
renovate[bot] wants to merge 1 commit into
developfrom
renovate/npm-dependencies-updates
Open

renovate[bot] wants to merge 1 commit into
developfrom
renovate/npm-dependencies-updates

Conversation

@renovate

@renovate renovate Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
dotenv 18.0.1 → 18.0.4 age confidence
jscpd (source) 5.3.0 → 5.3.3 age confidence

Release Notes

motdotla/dotenv (dotenv)

v18.0.4

Compare Source

Changed
  • import dotenv/config should default quiet: true (#​1063)

v18.0.3

Compare Source

Changed
  • Patch DOTENV_QUIET setting when inside .env file (#​1059)

v18.0.2

Compare Source

  • Patch additional edge cases for the fast parser (#​1056)
kucherenko/jscpd (jscpd)

v5.3.3

Compare Source

New Features
  • Semantic clones, experimental: --semantic. The token passes match runs of tokens, so they miss two functions that do the same job with different code. Such a function may be renamed and restructured, or written in another language, like a validation rule that a Rust backend enforces and a Svelte frontend repeats (Type-4 clones). --semantic (config key semantic) embeds every function with a code embedding model and reports the pairs whose vectors point the same way as clones of kind semantic.
    • jscpd embeds the functions of JavaScript, TypeScript, JSX, TSX, Vue, Svelte, Astro, Python, Rust, Go, Java, Kotlin, C#, C, C++, PHP, Ruby, Scala and Swift files that clear --min-tokens and --min-lines. It embeds each function's code without comments, starting at the name the function is declared under.
    • Two functions pair only if they are in different files, neither calls the other, and the clones already found do not cover both. Each must be the other's closest match among the functions of its language; a function that is only close to the best match needs a higher similarity. The cosine must reach --semantic-threshold for a pair across languages, or --semantic-same-threshold for a pair within one language (0.4125 and 0.6375 with the default model), and it must stand at least 3 standard deviations above each function's background. --semantic-scope same keeps the pairs within one language, and --semantic-scope cross keeps the pairs across languages.
    • The default model, CodeRankEmbed (MIT), runs inside jscpd on the CPU once jscpd --semantic-download has fetched it (548 MB, pinned by revision and SHA-256), and a scan makes no network call. In a comparison of nine open models, it found more known clones than jina-embeddings-v2-base-code at the same precision, and reviewers judged more of its pairs to be duplicates. jscpd also runs jina-embeddings-v2-base-code, which is faster: jscpd --semantic-download jina-embeddings-v2-base-code fetches it (324 MB), and --semantic-model jina-embeddings-v2-base-code scans with it.
    • --semantic-url sends the functions to an OpenAI-compatible embeddings API instead, such as Ollama, llama.cpp, text-embeddings-inference or a hosted API. jscpd reads the API key only from JSCPD_SEMANTIC_API_KEY, and sends it only to a URL given on the command line or to a server on this machine. A config file can neither hold a key nor send code to another host on its own.
    • jscpd caches the vectors, so a repeat run embeds only the functions whose code changed. Each set of scanned paths has its own cache file. Once the vectors of changed and deleted functions make up more than a quarter of that file, the next run that embeds something rewrites it without them. --semantic-rebuild-cache embeds everything again and replaces the file at once.
    • Each model scores similarity on its own scale, so each model gets its own thresholds. jscpd --semantic-models lists the nine models jscpd has calibrated, with their thresholds, licenses and where they run. --semantic-model takes any of them by the name in that list (CodeRankEmbed), by Hugging Face id or by Ollama name, and the thresholds follow the model. The rule for groups of copies has two more settings, tuned with jina-embeddings-v2-base-code: a near-best margin of 0.05 and a floor of 0.8. jscpd scales both for every other model by the model's gap between its two thresholds, which gives 0.075 and 0.7125 for CodeRankEmbed. Qwen3-Embedding-0.6B and jina-code-embeddings-0.5b expect an instruction before the text, and jscpd puts the one they were calibrated with before every function; the config key prefix replaces it. A model that jscpd has not calibrated gets 0.6 and 0.75, and the run warns about it.
    • The console prints Clone found (rust, semantic ~0.78), -r ai prints [~0.78 semantic], JSON carries "kind": "semantic" and similarity, and SARIF uses the rule jscpd/semantic-code. --kind semantic keeps only these clones. The code lives in a new crate, cpd-semantic, and a run without --semantic works as before.
    • fixtures/semantic-demo is a runnable example: a Rust API and a SvelteKit frontend with 8 rules written on both sides and 2 features written twice in one language. (#​1101, #​1103, #​1105, #​1108, #​1110)
Bug Fixes
  • A scan path inside another scanned its files twice. With jscpd . src, or a config file that lists src next to src/generated, jscpd walked every file under the inner path once for each path and reported each of those files as a clone of itself. --semantic embedded their functions twice and paired each one with itself. Version 4 read those files once, and so does jscpd now, as it already did with --follow-symlinks. See fixtures/nested-paths-demo. (#​1106)

  • Svelte components lost two kinds of use to --dead-code. Svelte reads a store as $name, in the script and in the markup, and that is often the only use that import { page } from '$app/stores' gets, so --dead-code reported the import as unused with 100% confidence. It also reported a name as an unused symbol when the markup read it only inside the ${…} of a template literal, as in href={(p) => `/?${base}&page=${p}`}, because the markup scan skipped template literals the way it skips plain strings. $name now counts as a read of name (runes such as $state and $props, and $$props, do not), and jscpd reads the placeholders of a template literal as code in every component format. On two SvelteKit apps, sshx and the RealWorld example, the six and three findings of basta 0.3.0 were all of these two kinds, and neither app has a finding now. See fixtures/dead-code-demo. (#​1102)

  • Positions in files with Windows line endings drifted. The generic tokenizer, which reads Python, Go, Java, C# and most other formats, moved one byte forward per line where a CRLF line ends in two bytes, so every position was short by the number of lines above it. The position values in the JSON report were off, and an --ignore-pattern match removed tokens a byte behind per line, which changed the token counts of the clones around it. Files with CRLF endings now report true byte offsets, and where a pattern applies, their clones can count different tokens than before. Files with LF endings are unaffected. See fixtures/crlf-demo. (#​1101)

Dependencies
  • paste is gone from the build. The crate is unmaintained (RUSTSEC-2024-0436), and candle's matrix kernels, pulp and tokenizers still depend on it. The workspace now patches it with a small local crate that hands its one macro to pastey, its maintained successor, so cargo audit and cargo deny pass without an ignore for the advisory. The patch goes away once those crates release their switch to pastey. sha2 moved to 0.11, and every other dependency to its latest compatible release. (#​1107, #​1109)
  • oxc moved to 0.151 and ruff to 0.0.15, each as one family of crates (#​1098), and clap to 4.6.7 (#​1097).
Deprecations
  • --min-duplicated-lines never did anything, and now says so. Since the first 5.x release, the docs described it as a minimum percentage of duplication to report, but no code ever read it: a scan with --min-duplicated-lines 100 found the same clones as one without it. jscpd now hides the flag from --help and prints a warning when it is passed, and a later release will remove it. The flag is still accepted, so a script that passes it keeps working. To fail a run on too much duplication, use --threshold; to set the smallest clone worth reporting, use --min-lines or --min-tokens. (#​1100)

Published Packages

  • basta@0.3.0 on crates.io
  • cpd-core@0.1.19 on crates.io
  • cpd-finder@0.1.19 on crates.io
  • cpd-reporter@0.1.20 on crates.io
  • cpd-tokenizer@0.1.18 on crates.io
  • cpd@5.3.3 on npm
  • jscpd@5.3.3 on npm
  • jscpd-darwin-arm64@5.3.3 on npm
  • jscpd-darwin-x64@5.3.3 on npm
  • jscpd-linux-x64-gnu@5.3.3 on npm
  • jscpd-linux-arm64-gnu@5.3.3 on npm
  • jscpd-linux-x64-musl@5.3.3 on npm
  • jscpd-linux-arm64-musl@5.3.3 on npm
  • jscpd-windows-x64-msvc@5.3.3 on npm
  • jscpd-windows-arm64-msvc@5.3.3 on npm
  • jscpd==5.3.3 on PyPI

Not Yet Published

  • cpd-semantic@0.1.0 (published: none)
  • jscpd@5.3.3 (published: 5.3.2)

Verify

Archives are signed with Sigstore (keyless, <asset>.sigstore.json)
and carry SLSA build provenance. Replace jscpd-linux-x64-gnu.tar.gz with your asset:

cosign verify-blob \
  --bundle jscpd-linux-x64-gnu.tar.gz.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/kucherenko/jscpd/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  jscpd-linux-x64-gnu.tar.gz
gh attestation verify jscpd-linux-x64-gnu.tar.gz --repo kucherenko/jscpd
sha256sum --check --ignore-missing checksums.txt

v5.3.2

Compare Source

New Features
  • Rust dead code, read from the compiler. jscpd does not parse Rust, and does not need to. Every cargo build already prints lines like function reprint is never used, with real name resolution, trait dispatch and macro expansion behind them. The dead-code run now reads that output, from the JSON of cargo check (or build, clippy, test --no-run), and reports it next to everything else, through the same categories, reporters and --min-confidence, at 100% confidence.
    • basta takes --rust-diagnostics <file>, or - for a pipe: cargo check --all-targets --message-format=json | basta . --rust-diagnostics -.
    • jscpd takes the same flag for --dead-code, --dashboard and --health, so a Rust project gets its health badge from the check it already runs: cargo check --all-targets --message-format=json | jscpd . --health --rust-diagnostics - --reporters badge. The dead-code section of the config file takes the file as rustDiagnostics.
    • Neither tool runs cargo itself, because that would execute the project's build scripts and procedural macros.
    • The compiler's span covers only the name, so the item's real size is read from the source. An item that --all-targets reports twice is counted once. A diagnostic inside a macro expansion, or for a crate outside the scanned paths, is left out.
    • A finding from a test target is handled like a test file in any other language: reported only with --include-tests, at 85%.
    • In a workspace, cargo writes paths relative to the workspace root, and they are resolved as such. A relative manifest_path in a hand-edited or copied file is resolved from where the file lives.
    • The compiler never reports a pub item of a library, and it has no notion of an unused file, so jscpd reports neither for Rust.
    • The dashboard's dead-code heading no longer names three languages, and a project with no language the run could read says so in its health score.
    • See fixtures/dead-code-demo. (#​1089)
Bug Fixes
  • Text around an embedded code block was counted as code. A ts block in a markdown file, a <script> in a single-file component: jscpd scans these under the embedded language's own format, and the block keeps the line numbers of the file it lives in. The statistics read those numbers as if the block ran the whole way, which put the markdown prose and the component templates into the embedded language's line counts — both the total and the duplicated lines. On a repository with about 3600 markdown files the typescript row said 51.30% of lines were duplicated where the same code, scanned with -f typescript, said 3.37%. Neither number was a typo and both came from the same run.

    An embedded source now counts the lines its blocks occupy, and a clone counts the block lines it covers rather than everything its fragment reaches across. The two percentage columns agree again, which is the quickest way to check a run: they measure the same duplication, so when the line column sits far below the token column it is counting text that holds no code. Ordinary files are counted exactly as before. See fixtures/embedded-stats-demo. (#​1091, closes #​1090)

  • Every clone was one line short. Duplicated lines came from end - start, so a clone covering lines 10 through 19 counted nine — while the console printed 10 lines for it, from its own arithmetic. Line counts are inclusive now, and the header and the table come from one place. Expect duplicated-line totals to rise by about one line per clone, and percentages with them. (#​1091)

Other

Published Packages

  • basta@0.3.0 on crates.io
  • cpd-core@0.1.18 on crates.io
  • cpd-finder@0.1.18 on crates.io
  • cpd-reporter@0.1.19 on crates.io
  • cpd-tokenizer@0.1.17 on crates.io
  • jscpd@5.3.2 on crates.io
  • cpd@5.3.2 on npm
  • jscpd@5.3.2 on npm
  • jscpd-darwin-arm64@5.3.2 on npm
  • jscpd-darwin-x64@5.3.2 on npm
  • jscpd-linux-x64-gnu@5.3.2 on npm
  • jscpd-linux-arm64-gnu@5.3.2 on npm
  • jscpd-linux-x64-musl@5.3.2 on npm
  • jscpd-linux-arm64-musl@5.3.2 on npm
  • jscpd-windows-x64-msvc@5.3.2 on npm
  • jscpd-windows-arm64-msvc@5.3.2 on npm
  • jscpd==5.3.2 on PyPI

Verify

Archives are signed with Sigstore (keyless, <asset>.sigstore.json)
and carry SLSA build provenance. Replace jscpd-linux-x64-gnu.tar.gz with your asset:

cosign verify-blob \
  --bundle jscpd-linux-x64-gnu.tar.gz.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/kucherenko/jscpd/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  jscpd-linux-x64-gnu.tar.gz
gh attestation verify jscpd-linux-x64-gnu.tar.gz --repo kucherenko/jscpd
sha256sum --check --ignore-missing checksums.txt

v5.3.1

Compare Source

New Features
  • --dashboard lists the largest code files. The Project section now ranks files by lines, with their tokens and size, next to the largest formats — the files worth splitting, beside the most complex ones further down. Only code is ranked: a lockfile, a changelog or a long HTML page is often the longest file in a repository and nothing anyone would refactor, so prose, data and markup files are left out, as they are from the complexity list. --summary-top sets the rows, and the json, markdown and html reporters carry the same list (project.largestFiles in jscpd-dashboard.json, an added key). See fixtures/dashboard-demo. (#​1086)

  • basta now detects which frameworks a project uses. A framework runs files that nothing imports: a router's pages, a runtime's plugin directories, handlers it finds by convention. basta used to know three such cases, hard-coded: Nuxt, Nitro and WXT. It now reads them from a list of about fifty definitions built into the binary, frameworks.yaml. The list covers Next.js, Nuxt, Nitro, WXT, Plasmo, Remix, React Router, SvelteKit, Astro, SolidStart, TanStack Start, Qwik City, Gatsby, RedwoodJS, Angular, NestJS, AdonisJS, Sails, @fastify/autoload, Strapi, Medusa, Ember, Quasar, React Native, Expo, Cloudflare Workers, Vercel, Netlify, Serverless, Trigger.dev, Docusaurus, VitePress, Eleventy, Storybook, Histoire, Jest, Vitest, Mocha, AVA, Playwright, Cypress, Cucumber, Prisma, Knex, Sequelize, TypeORM, Hardhat and Create React App.

    • A framework counts as present when basta finds any one of three things: its config file, its package among the package.json dependencies, or its section in package.json. basta checks every directory that holds scanned files, so each package of a monorepo is treated as its own project.
    • Several frameworks can apply at once, and each one keeps its own files alive. A Next.js application with Storybook, Vitest and Prisma counts as four.
    • The files and directories a framework loads are matched relative to the directory where the framework was found. basta also reads the framework's config for the settings that move directories: srcDir, entrypointsDir, appDirectory, sourceRoot in nest-cli.json, and imports: false.
    • The console report lists what was detected, for example Frameworks: next (apps/web), vitest. Both basta and jscpd --dead-code print it.
    • New basta flags: --list-frameworks prints the list. --framework <name> treats a framework as present, which helps when the scan starts below its package.json. --no-frameworks turns detection off. --frameworks-config <file> loads your own definitions, in YAML or JSON, in the same shape as the built-in list. basta also picks up basta.frameworks.{yaml,yml,json} from the working directory. Your definitions can add a framework basta does not know, or replace a built-in one that has the same name. If the file fails to load, basta stops with an error, because running without it would report as dead the very files the definitions protect.
    • A definition can also list the names its framework looks up in your code, under globals. The built-in list has getServerSideProps, generateMetadata and the route segment config for Next; loader, action and meta for Remix and React Router; load, actions, prerender and the hooks for SvelteKit; getStaticPaths for Astro; the Gatsby Node, browser and SSR APIs; the lifecycle methods of Angular and Nest; onRequest* for Cloudflare Pages Functions; handler for Netlify and Serverless functions; and more. basta treats a declaration with such a name as used. It never reports it, including under --include-entry-exports and as an unused member, and everything the declaration calls stays reachable.
    • A plain name in globals applies to every file of the project. The { names, files } form limits names to the files the framework reads them from, so loader counts for Remix under the app directory and is an ordinary name everywhere else. This also fixes a React Router route named from routes.ts. basta reaches that file through a string, so it is not an entry point, and its loader used to be reported as an unused export.
    • Nitro now follows srcDir and treats tasks/ as loaded by the framework.
    • See fixtures/dead-code-demo. (#​1087)
  • .jscpd.json can hold dead-code settings in a section of their own. The deadCode key (also spelled dead-code or basta) used to be a boolean that turned the mode on. It can now also be an object with these keys: enabled, categories, minConfidence, minLines, entry, ignore, includeTests, includeEntryExports, threshold, and the framework settings frameworks (definitions written inline, in the shape of frameworks.yaml), frameworksConfig, framework and noFrameworks.

    • The object only supplies settings. It turns the mode on only when it says "enabled": true, so you can keep clone settings and dead-code settings in one file and choose the run on the command line. "deadCode": true still works as the switch.
    • A flag wins over the section. The section wins over the older top-level keys (minConfidence, entry, deadCodeCategories, …), which still work.
    • minLines and threshold exist only inside the section, because the top-level keys with those names are about clones. The top-level minLines is the smallest clone to report and is never applied to a dead-code run. The top-level threshold is a limit for duplicated lines. A dead-code run still falls back to it when the section sets no threshold, as before.
    • A misspelled key inside the section is reported by name.
    • jscpd --dead-code and --dashboard now also pick up basta.frameworks.{yaml,yml,json} from the working directory.
    • The standalone basta binary reads the same section from the same file. It has a new -c, --config <file> flag. Without it, basta looks in the working directory for .jscpd.json, .config/jscpd.json or package.json. Both tools give the same result when you start them in the same directory.
    • See fixtures/dead-code-demo. (#​1087)
Fixes

We ran basta next to knip and fallow on 55 repositories: the GitHub trending lists for JavaScript, TypeScript, Vue, Svelte and Astro, plus the source code of Nuxt, Next.js, Svelte, Gatsby and Astro. The run found these problems in basta, all fixed in [#​1087](#​1087:

  • --dead-code was very slow on projects with many path aliases. basta tested every import against every alias in the project, and it did the slow check first: comparing the importer's path with the directory of the config that declared the alias, one path segment at a time. A monorepo with 150 packages, each listing a few hundred paths, took 198 s (ever-gauzy). Next.js took 83 s. basta now checks first whether the alias pattern matches the import at all, which fails on the first character for almost every alias. The same two projects now take 3.3 s and 4.4 s, and the findings are byte for byte the same.
  • A catch-all alias made every package import slow. With "*": ["./*", "../../node_modules/*"], an import of react went through the resolver from every file, and each miss built and hashed about twenty candidate paths. The module index can now tell in two lookups whether a path could name any module, under any extension or as a directory index, and the answer is exact. LibreChat went from 4.0 s to 0.86 s with identical findings.
  • Vite's '@': '/src' alias was read as the root of the file system. In a Vite alias target a leading / means the project root, as it does in a URL, and many projects write the alias that way. basta lost every @/ import in such a project and reported its components as unused files at 95% confidence. MoeKoeMusic went from 55 unused files to 0.
  • require(`./x`) with backticks was ignored. A template literal with nothing interpolated is as static as a quoted string, and Gatsby writes every string that way. Gatsby went from 584 unused files to 352.
  • An arrow function in a Svelte or Astro attribute broke parsing. In <script on:load={() => { … }} src=…>, basta took the > of => for the end of the tag and passed the rest of the attribute to the JavaScript parser as the component's script. The file failed to parse, and everything it imports was reported as unused. cobalt went from 37 unused files to 8.
  • Django migrations and management commands were reported as unused files. So were admin.py, apps.py, template tags, and the modules that settings name by dotted path. Django, Alembic and Scrapy are now in the framework list, detected by manage.py, alembic.ini and scrapy.cfg. AdventureLog went from 144 unused Python files to 6.
  • A file named only by a path string without an extension is no longer reported at full confidence. resolve(distDir, 'runtime/handlers/island') is how a framework registers a file it loads itself. It is not an import, and basta does not treat it as one. But a file whose own path ends the same way now gets a new reason, path-appears-in-string ("its path appears in a string literal"), which costs 40 points. That puts the file under the default threshold of 60, and it still shows up with --min-confidence 0. Nuxt went from 83 unused files to 46. The reason is a new possible value of reasons in the JSON report.
  • --dead-code read a WXT browser extension as almost entirely dead (#​1082): the framework's entrypoints/ directory — background, content scripts, popup pages — was not recognized as entry points, and its @/~ → srcDir, @@/~~ → root aliases live only in the generated .wxt/tsconfig.json, which no repository commits, so the whole tree dangled and cascaded (Tencent/BrowserSkill: 27.9% "unused", 115 unused files — now 0.4% and 5). A wxt.config.* now marks the entrypoints and auto-import directories as entries, honoring srcDir, entrypointsDir and imports: false, and declares the conventional aliases, the same way nuxt.config.* roots Nuxt's directories and svelte.config.* supplies $lib. (#​1083)
  • Markup, stylesheet and template files (HTML, XML, SVG, CSS, Handlebars, …) were assigned a complexity, counting words like if, for or a media query's and as branches — an HTML page could top the "Most complex files" list. These formats now have complexity 0, like prose and data files already did, and are therefore no longer counted as code by the health score: an all-markup project reports "no code files" instead of being scored on its markup. Component formats (Vue, Svelte, Astro) still count in full through their script blocks. The markup block of a component file (tokenized as html) is now also excluded from the duplication share, matching the css/scss blocks that already were. (#​1081) (#​1084)
Other

Published Packages

  • basta@0.2.0 on crates.io
  • cpd-core@0.1.16 on crates.io
  • cpd-finder@0.1.17 on crates.io
  • cpd-reporter@0.1.17 on crates.io
  • cpd-tokenizer@0.1.17 on crates.io
  • jscpd@5.3.1 on crates.io
  • cpd@5.3.1 on npm
  • jscpd@5.3.1 on npm
  • jscpd-darwin-arm64@5.3.1 on npm
  • jscpd-darwin-x64@5.3.1 on npm
  • jscpd-linux-x64-gnu@5.3.1 on npm
  • jscpd-linux-arm64-gnu@5.3.1 on npm
  • jscpd-linux-x64-musl@5.3.1 on npm
  • jscpd-linux-arm64-musl@5.3.1 on npm
  • jscpd-windows-x64-msvc@5.3.1 on npm
  • jscpd-windows-arm64-msvc@5.3.1 on npm
  • jscpd==5.3.1 on PyPI

Verify

Archives are signed with Sigstore (keyless, <asset>.sigstore.json)
and carry SLSA build provenance. Replace jscpd-linux-x64-gnu.tar.gz with your asset:

cosign verify-blob \
  --bundle jscpd-linux-x64-gnu.tar.gz.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/kucherenko/jscpd/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  jscpd-linux-x64-gnu.tar.gz
gh attestation verify jscpd-linux-x64-gnu.tar.gz --repo kucherenko/jscpd
sha256sum --check --ignore-missing checksums.txt

Configuration

📅 Schedule: (in timezone Europe/Paris)

  • Branch creation
    • "before 8am on monday"
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

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

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


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

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

@renovate
renovate Bot force-pushed the renovate/npm-dependencies-updates branch from 7503058 to 51dd94a Compare September 28, 2026 20:16
Sign up for free to 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.

0 participants