depcurfew v1.4.1
On this page

Package manager knowledge base

The facts depcurfew relies on, each linked to the official documentation or changelog it was verified against.

Legend: ↗ source · ❓ uncertain (official sources are incomplete) · ⚠️ disputed (official sources disagree; every variant is shown) · 1.2.3+ means "from version 1.2.3".

13 tools · 811 facts · 112 uncertain · 14 disputed · verified 2026-10-28 to 2026-11-02.

Release-age cooldown

How each tool delays freshly published versions.

ToolSettingConfig filesCLI flagUnitSinceDefaultExclusionsExclusions sinceExclusion patternsSecurity updates
npmmin-release-age ↗.npmrc ↗--min-release-age=<days> ↗days ↗11.10.0 ↗11.10.0+: off ↗min-release-age-exclude ↗11.17.0 ↗Package names or minimatch globs matched against the name, e.g. @myorg/*; only the named package is exempt, not its dependencies; also exempts from before ↗applies ↗
pnpmminimumReleaseAge ↗pnpm-workspace.yaml ↗none ❓ ↗minutes ↗10.16.0 ↗10.16.0+: 0
11.0.0+: 1440 ↗
minimumReleaseAgeExclude ↗10.16.0 ↗Package names (all versions); globs such as @myorg/* since 10.17.0; exact versions name@1.2.3 or name@1.2.3 || 1.2.4 since 10.19.0; ranges are not documented ↗applies ↗
Yarn (Berry)npmMinimalAgeGate ↗.yarnrc.yml ↗none ❓ ↗minutes ↗4.10.2 ↗⚠️ 4.10.0+: 0
4.15.0+: 1d ↗ / 4.10.0+: 0
4.11.0+: 3d
4.15.0+: 1d ↗
npmPreapprovedPackages ↗4.10.0 ↗Package descriptors or name globs, optionally with a semver range: @scope/*, package, package*, package@^1.0.0; global only, not per npmScopes ↗applies ❓ ↗
Buninstall.minimumReleaseAge ↗bunfig.toml ↗--minimum-release-age ↗seconds ↗1.3.0 ↗⚠️ 1.3.0+: off ↗ / 1.3.0+: 259200 ↗install.minimumReleaseAgeExcludes ↗1.3.0 ↗Exact package names (all versions); since 1.4.4 also name@exactVersion. No wildcards; ranges and tags are ignored with a warning ↗applies ❓ ↗
DenominimumDependencyAge ↗deno.json, .npmrc ↗--minimum-dependency-age ↗minutes ↗⚠️ 2.5.5 ↗ / 2.6.0 ↗earlier: off
2.9.0+: 1440 ↗
minimumDependencyAge.exclude ↗2.5.5 ↗Specifiers prefixed npm: or jsr:; a trailing * matches by prefix (npm:@scope/*) since 2.9.2 ↗applies ❓ ↗
uvexclude-newer ↗uv.toml, pyproject.toml ↗--exclude-newer ↗duration-string ↗0.9.17 ↗0.9.17+: off ↗exclude-newer-package ↗0.9.25 ↗Exact package names as table keys; no wildcards ↗applies ❓ ↗
pipuploaded-prior-to ↗[] ↗--uploaded-prior-to ↗days ↗26.1.0 ↗26.1.0+: off ↗none ❓ ↗--applies ❓ ↗
Poetrysolver.min-release-age ↗poetry.toml ↗none ❓ ↗days ↗2.4.0 ↗2.4.0+: off ↗solver.min-release-age-exclude ↗2.4.0 ↗Exact package names; no wildcards ↗applies ❓ ↗
PDMexclude-newer ↗pyproject.toml ↗--exclude-newer ↗duration-string ↗2.26.9 ↗2.26.9+: off ↗exclude-newer-override ↗2.29.1 ↗Package names, normalized before matching; no wildcards ↗applies ❓ ↗
Pipenvcool-down-period ↗Pipfile ↗none ❓ ↗duration-string ↗2026.6.2 ↗2026.6.2+: off ↗none ❓ ↗--applies ❓ ↗
Composerconfig.policy.cooldown.period ↗composer.json ↗none ❓ ↗duration-string ↗2.11.0 ↗2.11.0+: off ↗config.policy.cooldown.ignore ↗2.11.0 ↗Package names with * wildcards, e.g. vendor/* ↗applies ❓ ↗
RenovateminimumReleaseAge ↗renovate.json, renovate.jsonc, renovate.json5, .github/renovate.json, .github/renovate.jsonc, .github/renovate.json5, .gitlab/renovate.json, .gitlab/renovate.jsonc, .gitlab/renovate.json5, .renovaterc, .renovaterc.json, .renovaterc.jsonc, .renovaterc.json5 ↗--minimum-release-age ↗duration-string ↗35.46.0 ↗all versions: off ↗packageRules: matchPackageNames + minimumReleaseAge: null ↗35.46.0 ❓ ↗matchPackageNames: exact names, globs such as @org/** (with ! negation) or /regex/; case-insensitive ↗bypass ↗
Dependabotcooldown ↗.github/dependabot.yml, .github/dependabot.yaml ↗none ❓ ↗days ↗2025-07-01 ↗2025-07-01+: off
2026-07-14+: 3 ↗
cooldown.exclude ↗2025-07-01 ❓ ↗Dependency names with * wildcards, up to 150 entries; exclude always wins over include ↗bypass ↗

Install scripts

Whether dependency lifecycle scripts run, and how to allow specific packages.

ToolDefault policyAllow-list settingAllow-list fileAllow-list sinceAllow-list formatDisable all
npmearlier: run
11.16.0+: run-with-warning
12.0.0+: deny-except-allowlist ↗
allowScripts ↗package.json ↗11.16.0 ↗Object keyed by name, name@version or name@v1 || v2 with true (allow) or false (deny); npm install-scripts approve writes pinned name@version entries ❓ ↗ignore-scripts ↗
pnpmearlier: run
10.0.0+: deny-except-allowlist ↗
allowBuilds ↗pnpm-workspace.yaml ↗10.26.0 ↗Map of package matcher to true (allow) or false (deny), e.g. esbuild: true or "nx@21.6.4 || 21.6.5": true; a bare name never approves git or tarball dependencies (pnpm 11+) ↗ignoreScripts ↗
Yarn (Berry)2.0.0+: run
4.14.0+: deny-except-allowlist ↗
dependenciesMeta.<package>.built ↗package.json ↗2.0.0 ❓ ↗Object keyed by package name or name@version: { built: true } allows a package when enableScripts is false; { built: false } denies it when enableScripts is true ↗enableScripts: false ↗
Bunall versions: deny-except-allowlist ↗trustedDependencies ↗package.json ↗1.0.5 ❓ ↗Array of package names, e.g. ["node-sass"] ↗install.ignoreScripts ↗
Denoall versions: deny-except-allowlist ↗allowScripts ↗deno.json ↗2.6.0 ↗true, an array of npm: constraints (semver ranges allowed, tags rejected) or { "allow": ..., "deny": [...] } ↗allowScripts: false ❓ ↗
uvall versions: run ↗no-binary-package ↗pyproject.toml ↗0.2.12 ↗A list of package names ↗no-build ↗
pipall versions: run ↗--no-binary ↗requirements.txt ↗7.0.0 ❓ ↗One option line per package or a comma-separated list, e.g. --no-binary=docopt ↗--only-binary=:all: ↗
Poetryall versions: run ↗installer.no-binary ↗poetry.toml ↗2.2.0 ↗A list of package names, or :all: or :none: ↗installer.only-binary ↗
PDMall versions: run ↗no-binary ↗pyproject.toml ↗2.15.0 ↗A comma-separated string or a list of package names, or :all: ↗only-binary ↗
Pipenvall versions: run ↗none ❓ ↗---none ❓ ↗
Composerearlier: run
2.2.0+: deny-except-allowlist ↗
config.allow-plugins ↗composer.json ↗2.2.0 ↗An object of package name patterns (vendor/*) to true (allow) or false (disallow without asking); true allows every plugin and false none ↗config.allow-plugins: false ↗
Renovateall versions: deny ↗none ❓ ↗---ignoreScripts: true ↗
Dependabotall versions: deny ❓ ↗none ↗---none ❓ ↗

Project files

How depcurfew recognizes each package manager in a repository.

ToolLockfilesManifestsWorkspacesObject form key
npmearlier: npm-shrinkwrap.json, package-lock.json
12.0.0+: package-lock.json ↗
package.json ↗{"files":["package.json"],"key":"workspaces"} ↗packages ❓ ↗
pnpmall versions: pnpm-lock.yaml ↗package.json, package.json5, package.yaml ↗{"files":["pnpm-workspace.yaml"],"key":"packages"} ↗none ❓ ↗
Yarn (Berry)all versions: yarn.lock ↗package.json ↗{"files":["package.json"],"key":"workspaces"} ↗packages ❓ ↗
Bunearlier: bun.lockb
1.2.0+: bun.lock, bun.lockb ❓ ↗
package.json ↗{"files":["package.json"],"key":"workspaces"} ↗packages ↗
Denoall versions: deno.lock ↗deno.json, deno.jsonc ↗{"files":["deno.json","deno.jsonc"],"key":"workspace"} ↗members ↗
uvall versions: uv.lock ↗pyproject.toml ↗{"files":["pyproject.toml"],"key":"tool.uv.workspace","excludeKey":"exclude"} ↗members ↗
pip25.1.0+: pylock.toml ↗requirements.txt ↗none ❓ ↗none ❓ ↗
Poetryall versions: poetry.lock ↗pyproject.toml ↗none ❓ ↗none ❓ ↗
PDMall versions: pdm.lock ↗pyproject.toml ↗none ❓ ↗none ❓ ↗
Pipenvall versions: Pipfile.lock ↗Pipfile ↗none ❓ ↗none ❓ ↗
Composerall versions: composer.lock ↗composer.json ↗none ❓ ↗none ❓ ↗

Dependency sources

Settings that allow or forbid dependencies from git, remote tarballs and local paths.

ToolSettingValuesSinceDefault
npm · gitallow-git ↗all, none, root ↗⚠️ 11.9.0 ↗ / 11.10.0 ↗11.9.0+: all
12.0.0+: none ↗
npm · remote tarballallow-remote ↗all, none, root ↗⚠️ 11.14.0 ↗ / 11.15.0 ↗11.14.0+: all
12.0.0+: none ↗
npm · local tarballallow-file ↗all, none, root ↗⚠️ 11.14.0 ↗ / 11.15.0 ↗11.14.0+: all ↗
npm · local directoryallow-directory ↗all, none, root ↗⚠️ 11.14.0 ↗ / 11.15.0 ↗11.14.0+: all ↗
pnpm · gitblockExoticSubdeps ↗true, false ↗10.26.0 ↗10.26.0+: false
11.0.0+: true ↗
pnpm · remote tarballblockExoticSubdeps ↗true, false ↗10.26.0 ↗10.26.0+: false
11.0.0+: true ↗
pnpm · local tarballnone ❓ ↗---
pnpm · local directorynone ❓ ↗---
Yarn (Berry) · gitapprovedGitRepositories ↗repository URL glob patterns, e.g. https://github.com/org/* ↗4.14.0 ↗4.14.0+: [] (every git dependency is blocked) ↗
Yarn (Berry) · remote tarballnone ❓ ↗---
Yarn (Berry) · local tarballnone ❓ ↗---
Yarn (Berry) · local directorynone ❓ ↗---
Bun · gitnone ❓ ↗---
Bun · remote tarballnone ❓ ↗---
Bun · local tarballnone ❓ ↗---
Bun · local directorynone ❓ ↗---
Deno · gitnone ↗---
Deno · remote tarballnone ↗---
Deno · local tarballnone ↗---
Deno · local directorynone ↗---
uv · gitnone ❓ ↗---
uv · remote tarballnone ❓ ↗---
uv · local tarballnone ❓ ↗---
uv · local directorynone ❓ ↗---
pip · gitnone ❓ ↗---
pip · remote tarballnone ❓ ↗---
pip · local tarballnone ❓ ↗---
pip · local directorynone ❓ ↗---
Poetry · gitnone ❓ ↗---
Poetry · remote tarballnone ❓ ↗---
Poetry · local tarballnone ❓ ↗---
Poetry · local directorynone ❓ ↗---
PDM · gitnone ❓ ↗---
PDM · remote tarballnone ❓ ↗---
PDM · local tarballnone ❓ ↗---
PDM · local directorynone ❓ ↗---
Pipenv · gitnone ❓ ↗---
Pipenv · remote tarballnone ❓ ↗---
Pipenv · local tarballnone ❓ ↗---
Pipenv · local directorynone ❓ ↗---
Composer · gitnone ❓ ↗---
Composer · remote tarballnone ❓ ↗---
Composer · local tarballnone ❓ ↗---
Composer · local directorynone ❓ ↗---

Additional facts

Further facts used by generators and doctor.

npm

  • environmentNames (✅ verified): {"prefix":"npm_config_","match":"any-case"} ↗
  • localPrefix (✅ verified): {"markers":{"file":"package.json","directory":"node_modules"},"workspaceRoot":true,"workspacesField":"workspaces","workspacesObjectKey":"packages","prefixOption":"--prefix","workspacesOption":"--workspaces","projectFile":".npmrc"} ↗
  • childEnvironment (✅ verified): {"marker":"npm_execpath","prefix":"npm_config_"} ↗
  • denyList (✅ verified): {"file":"package.json","setting":"allowScripts","value":false,"since":"11.16.0"} ↗
  • trustedPublishing (✅ verified): {"minimumNpm":"11.5.1","minimumNode":"22.14.0","githubPermission":"id-token: write","automaticProvenance":true,"firstPublishWithinDays":2} ↗
  • stagedPublishing (✅ verified): {"minimumNpm":"11.15.0","minimumNode":"22.14.0","stage":"npm stage publish","approve":"npm stage approve","reject":"npm stage reject","newPackagePlaceholder":"0.0.0-stage"} ↗
  • trustCommand (✅ verified): {"command":"npm trust github","minimumNpm":"11.15.0","packageMustExist":true,"permissions":["--allow-publish","--allow-stage-publish"]} ↗
  • tarballIdentity (✅ verified): {"separator":"/-/","extension":".tgz","scopeSeparator":"/|%2f","version":"semver"} ↗
  • lockfileFormat (✅ verified): {"installScripts":"hasInstallScript","gitPrefixes":["git+","git:"],"filePrefix":"file:","linkFlag":"link","registryTarball":"^https?://[^/]+/.+/-/[^/]+-\\d","specWithoutResolved":"version","dependencyFields":["dependencies","optionalDependencies","peerDependencies","devDependencies"]} ↗
  • overrides (✅ verified): {"field":"overrides","selfKey":"."} ↗
  • npmrcScope (✅ verified): {"read":"project root","workspacePackages":"ignored","globalMode":"ignored"} ↗
  • npmrcFormat (✅ verified): {"commentLines":["#",";"],"inlineComments":["#",";"],"escape":"\\","sectionHeader":"^\\[([^\\]]*)\\]\\s*$","keyWithoutValue":"true","settingsFrom":"top level"} ↗
  • npmrcListSyntax (✅ verified): [] ↗
  • allowAllScripts (✅ verified): {"setting":"dangerously-allow-all-scripts","since":"11.16.0","value":true} ↗
  • excludeWildcards (✅ verified): {"since":"11.17.0","trailingOnly":false} ↗
  • latestVersion (✅ verified): 12.2.1 ↗
  • beforeInteraction (✅ verified): {"setting":"before","exclusive":{"since":"11.10.0","until":"11.15.0"},"beforeWinsSince":"11.15.0"} ↗
  • strictAllowScripts (✅ verified): {"setting":"strict-allow-scripts","value":true,"since":"11.16.0"} ↗
  • strictAllowScriptsEffect (✅ verified): 11.16.0+: the install fails instead of running the script with a notice
    12.0.0+: the install fails instead of blocking the script with a warning ↗
  • unknownNpmrcKeys (✅ verified): unknown keys in .npmrc files only warn unless strict-npmrc is set; unknown command-line flags throw since npm 12 ↗
  • commandLine (✅ verified): {"add":[["npm","install"],["npm","add"],["npm","i"],["npm","in"],["npm","ins"],["npm","inst"],["npm","insta"],["npm","instal"],["npm","isnt"],["npm","isnta"],["npm","isntal"],["npm","isntall"],["npm","install-test"],["npm","it"]],"run":[{"command":["npx"],"packageOptions":["--package","-p"],"lineOptions":["--call","-c"]},{"command":["npm","exec"],"packageOptions":["--package"],"lineOptions":["--call","-c"]},{"command":["npm","x"],"packageOptions":["--package"],"lineOptions":["--call","-c"]}],"create":[{"command":["npm","init"],"packageOptions":[]},{"command":["npm","create"],"packageOptions":[]},{"command":["npm","innit"],"packageOptions":[]}],"createNames":"prefix","valueOptions":[]} ↗
  • valueOptions (✅ verified): --access, --allow-directory, --allow-file, --allow-git, --allow-remote, --allow-scripts, --also, --audit-level, --auth-type, --before, --ca, --cache, --cache-max, --cache-min, --cafile, --call, --cert, --cidr, --cpu, --depth, --diff, --diff-dst-prefix, --diff-src-prefix, --diff-unified, --edit-dir, --editor, --expect-result-count, --expires, --extension-file, --fetch-retries, --fetch-retry-factor, --fetch-retry-maxtimeout, --fetch-retry-mintimeout, --fetch-timeout, --git, --global-ignore-file, --globalconfig, --heading, --https-proxy, --include, --init-author-email, --init-author-name, --init-author-url, --init-license, --init-module, --init-type, --init-version, --install-strategy, --key, --libc, --local-address, --location, --lockfile-version, --loglevel, --logs-dir, --logs-max, --maxsockets, --message, --min-release-age, --min-release-age-exclude, --name, --node-gyp, --node-options, --noproxy, --omit, --only, --orgs, --orgs-permission, --os, --otp, --pack-destination, --package, --packages, --packages-and-scopes-permission, --password, --patches-dir, --prefix, --preid, --provenance-file, --proxy, --registry, --replace-registry-host, --save-prefix, --sbom-format, --sbom-type, --scope, --scopes, --script-shell, --searchexclude, --searchlimit, --searchopts, --searchstaleness, --shell, --tag, --tag-version-prefix, --to, --token-description, --umask, --user-agent, --userconfig, --viewer, --which, --workspace, -C, -L, -c, -m, -w ↗
  • flagOptions (✅ verified): --all, --allow-same-version, --allow-scripts-pending, --allow-scripts-pin, --allow-unused-patches, --audit, --bin-links, --browser, --bypass-2fa, --color, --commit-hooks, --dangerously-allow-all-scripts, --description, --dev, --diff-ignore-all-space, --diff-name-only, --diff-no-prefix, --diff-text, --dry-run, --engine-strict, --expect-results, --force, --foreground-scripts, --format-package-lock, --fund, --git-tag-version, --global, --global-style, --if-present, --ignore-existing, --ignore-extension, --ignore-patch-failures, --ignore-scripts, --include-attestations, --include-staged, --include-workspace-root, --init-private, --install-links, --json, --keep-edit-dir, --legacy-bundling, --legacy-peer-deps, --link, --long, --offline, --omit-lockfile-registry-resolved, --optional, --package-lock, --package-lock-only, --packages-all, --parseable, --prefer-dedupe, --prefer-offline, --prefer-online, --production, --progress, --provenance, --read-only, --rebuild-bundle, --save, --save-bundle, --save-dev, --save-exact, --save-optional, --save-peer, --save-prod, --shrinkwrap, --sign-git-commit, --sign-git-tag, --strict-allow-scripts, --strict-npmrc, --strict-peer-deps, --strict-ssl, --timing, --unicode, --update-notifier, --usage, --version, --versions, --workspaces, --workspaces-update, --yes ↗
  • parsing (✅ verified): {"abbreviations":true,"anyDashes":true,"negation":"--no-","shorthands":{"enjoy-by":["--before"],"d":["--loglevel","info"],"dd":["--loglevel","verbose"],"ddd":["--loglevel","silly"],"quiet":["--loglevel","warn"],"q":["--loglevel","warn"],"s":["--loglevel","silent"],"silent":["--loglevel","silent"],"verbose":["--loglevel","verbose"],"desc":["--description"],"help":["--usage"],"local":["--no-global"],"n":["--no-yes"],"no":["--no-yes"],"porcelain":["--parseable"],"readonly":["--read-only"],"reg":["--registry"],"iwr":["--include-workspace-root"],"ws":["--workspaces"],"a":["--all"],"c":["--call"],"f":["--force"],"g":["--global"],"L":["--location"],"l":["--long"],"m":["--message"],"p":["--parseable"],"C":["--prefix"],"S":["--save"],"B":["--save-bundle"],"D":["--save-dev"],"E":["--save-exact"],"O":["--save-optional"],"P":["--save-prod"],"?":["--usage"],"H":["--usage"],"h":["--usage"],"v":["--version"],"w":["--workspace"],"y":["--yes"]}} ↗
  • versionSelection (✅ verified): {"tagOption":"--tag","tagVariable":"npm_config_tag","tagKey":"tag","bareRange":"*"} ↗
  • packageSpecs (✅ verified): {"git":["git://","git+ssh://","git+http://","git+https://","git+file://","github:","gist:","bitbucket:","gitlab:"],"local":["file:"],"workspace":[],"alias":"npm:","remoteTarball":["http://","https://"],"tarballExtensions":[".tar",".tar.gz",".tgz"],"shorthand":"github:"} ↗
  • registryConfig (✅ verified): {"file":".npmrc","userFile":"~/.npmrc","key":"registry","scopeKeySuffix":":registry"} ↗
  • registryOverrides (✅ verified): {"registryOptions":["--registry","--@<scope>:registry"],"registryVariables":["npm_config_registry"],"configOptions":["--userconfig","--globalconfig"],"configVariables":["npm_config_userconfig","npm_config_globalconfig"]} ↗
  • configCommands (✅ verified): {"command":["npm","config"],"writes":["set","delete","rm","del","edit","fix"]}, {"command":["npm","set"],"operands":1}, {"command":["npm","pkg"],"writes":["set","delete","fix"],"manifest":true} ↗
  • commandNames (✅ verified): {"commands":["access","approve-scripts","audit","bugs","cache","ci","completion","config","dedupe","deny-scripts","deprecate","diff","dist-tag","docs","doctor","edit","exec","explain","explore","find-dupes","fund","get","help","help-search","init","install","install-ci-test","install-scripts","install-test","link","ll","login","logout","ls","org","outdated","owner","pack","patch","ping","pkg","prefix","profile","prune","publish","query","rebuild","repo","restart","root","run","sbom","search","set","stage","start","stop","team","test","token","trust","undeprecate","uninstall","unpublish","update","version","view","whoami"],"aliases":{"author":"owner","home":"docs","issues":"bugs","info":"view","show":"view","find":"search","add":"install","unlink":"uninstall","remove":"uninstall","rm":"uninstall","r":"uninstall","un":"uninstall","rb":"rebuild","list":"ls","ln":"link","create":"init","i":"install","it":"install-test","cit":"install-ci-test","u":"update","up":"update","c":"config","s":"search","se":"search","tst":"test","t":"test","ddp":"dedupe","v":"view","run-script":"run","clean-install":"ci","clean-install-test":"install-ci-test","x":"exec","why":"explain","la":"ll","verison":"version","ic":"ci","innit":"init","in":"install","ins":"install","inst":"install","insta":"install","instal":"install","isnt":"install","isnta":"install","isntal":"install","isntall":"install","install-clean":"ci","isntall-clean":"ci","hlep":"help","dist-tags":"dist-tag","upgrade":"update","udpate":"update","rum":"run","sit":"install-ci-test","urn":"run","ogr":"org"}} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--min-release-age","weakens":"delay","values":"delay"},{"name":"--before","weakens":"delay","values":"any"},{"name":"--min-release-age-exclude","weakens":"delay","values":"any"},{"name":"--ignore-scripts","weakens":"scripts","values":{"except":["true"]}},{"name":"--dangerously-allow-all-scripts","weakens":"scripts","values":{"except":["false","null","undefined"]}},{"name":"--allow-scripts","weakens":"scripts","values":"any"}],"variables":[{"name":"npm_config_min_release_age","weakens":"delay","values":"delay"},{"name":"npm_config_before","weakens":"delay","values":"any"},{"name":"npm_config_min_release_age_exclude","weakens":"delay","values":"any"},{"name":"npm_config_ignore_scripts","weakens":"scripts","values":{"except":["true",""]}},{"name":"npm_config_dangerously_allow_all_scripts","weakens":"scripts","values":{"except":["false","null","undefined"]}},{"name":"npm_config_allow_scripts","weakens":"scripts","values":"any"}]} ↗
  • directoryOptions (✅ verified): {"options":[{"name":"--prefix","moves":"directory","localPrefix":true}],"variables":[]} ↗
  • booleanWords (✅ verified): true ↗
  • installCommands (✅ verified): {"install":["install","add","i","in","ins","inst","insta","instal","isnt","isnta","isntal","isntall","install-test","it"],"clean":["ci","clean-install","ic","install-clean","isntall-clean","install-ci-test","cit","clean-install-test","sit"],"update":["update","up","upgrade","udpate"]} ↗
  • globalOption (✅ verified): --global, -g, --location=global ↗
  • unknownConfigKeys (✅ verified): earlier: ignored
    11.2.0+: warning ↗
  • lockfileInstalls (❓ uncertain): npm ci installs versions pinned in package-lock.json without applying min-release-age ❓ ↗
  • cleanInstall (✅ verified): {"commands":"clean","installsLockedVersions":true,"failsWhenOutOfSync":true,"writesLockfile":false} ↗
  • scriptsOff (✅ verified): {"option":"--ignore-scripts","variable":"npm_config_ignore_scripts","anyCase":true,"value":"true"} ↗
  • nodeEngines (✅ verified): {"since":"11.0.0","node":"^20.17.0 || >=22.9.0"}, {"since":"12.0.0","node":"^22.22.2 || ^24.15.0 || >=26.0.0"} ↗
  • rootLifecycleScripts (✅ verified): {"events":["preinstall","install","postinstall","prepublish","preprepare","prepare","postprepare"],"skippedBy":"ignore-scripts","allowListApplies":false} ↗
  • omitOptional (✅ verified): {"omit":{"setting":"omit","value":"optional"},"alias":{"setting":"optional","off":false},"include":{"setting":"include"},"variablePrefix":"npm_config_","listSeparator":"\n\n"} ↗

pnpm

  • environmentNames (✅ verified): {"prefix":"pnpm_config_","match":"lower-or-upper"}, {"prefix":"npm_config_","match":"any-case"} ↗
  • denyList (✅ verified): {"file":"pnpm-workspace.yaml","setting":"allowBuilds","value":false,"since":"10.26.0"} ↗
  • projectInstall (✅ verified): {"commands":["install","i"],"bare":false} ↗
  • commandLine (✅ verified): {"add":[["pnpm","add"]],"run":[{"command":["pnx"],"packageOptions":["--package"],"shellOptions":["--shell-mode","-c"]},{"command":["pnpx"],"packageOptions":["--package"],"shellOptions":["--shell-mode","-c"]},{"command":["pnpm","dlx"],"packageOptions":["--package"],"shellOptions":["--shell-mode","-c"]}],"create":[{"command":["pnpm","create"],"packageOptions":[]}],"createNames":"prefix-unless-prefixed","valueOptions":["--save-prefix","--save-catalog-name","--lockfile-dir","--filter","-F","--registry","--allow-build","--cpu","--os","--libc","-C","--dir","--workspace-packages","--env-file","--reporter","--loglevel"]} ↗
  • packageSpecs (✅ verified): {"git":["github:","bitbucket:","gitlab:","gist:","git+ssh://"],"local":["link:","file:"],"workspace":["workspace:"],"remoteTarball":["http://","https://"],"tarballExtensions":[".tar",".tar.gz",".tgz"],"shorthand":"github:"} ↗
  • registryOverrides (✅ verified): {"registryOptions":["--registry","--@<scope>:registry"],"registryVariables":["pnpm_config_registry"],"configOptions":["--userconfig","--npmrc-auth-file"],"configVariables":["pnpm_config_npmrc_auth_file","pnpm_config_userconfig"]} ↗
  • parsing (✅ verified): {"abbreviations":true,"anyDashes":true,"negation":"--no-","settingPrefix":"--config.","shorthands":{"s":["--reporter=silent"],"d":["--loglevel=info"],"dd":["--loglevel=verbose"],"ddd":["--loglevel=silly"],"L":["--latest"],"r":["--recursive"],"silent":["--reporter=silent"],"verbose":["--loglevel=verbose"],"quiet":["--loglevel=warn"],"q":["--loglevel=warn"],"h":["--help"],"H":["--help"],"?":["--help"],"usage":["--help"],"v":["--version"],"f":["--force"],"local":["--no-global"],"l":["--long"],"p":["--parseable"],"porcelain":["--parseable"],"prod":["--production"],"development":["--dev"],"g":["--global"],"S":["--save"],"D":["--save-dev"],"P":["--save-prod"],"E":["--save-exact"],"O":["--save-optional"],"C":["--dir"],"w":["--workspace-root"],"i":["--interactive"],"F":["--filter"],"y":["--yes"]}} ↗
  • booleanWords (✅ verified): true ↗
  • directoryOptions (✅ verified): {"options":[{"name":"--dir","moves":"directory"}],"variables":[]} ↗
  • configCommands (✅ verified): {"command":["pnpm","config"],"writes":["set","delete"]}, {"command":["pnpm","c"],"writes":["set","delete"]}, {"command":["pnpm","pkg"],"writes":["set","delete","fix"],"manifest":true} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--ignore-scripts","weakens":"scripts","values":{"except":["true"]}},{"name":"--ignoreScripts","weakens":"scripts","values":{"except":["true"]}},{"name":"--allow-build","weakens":"scripts","values":"any"},{"name":"--dangerouslyAllowAllBuilds","weakens":"scripts","values":{"except":["false"]}},{"name":"--dangerously-allow-all-builds","weakens":"scripts","values":{"except":["false"]}},{"name":"--minimumReleaseAge","weakens":"delay","values":"delay"},{"name":"--minimum-release-age","weakens":"delay","values":"delay"},{"name":"--minimumReleaseAgeExclude","weakens":"delay","values":"any"},{"name":"--minimum-release-age-exclude","weakens":"delay","values":"any"},{"name":"--minimumReleaseAgeStrict","weakens":"delay","values":{"except":["true"]}},{"name":"--minimum-release-age-strict","weakens":"delay","values":{"except":["true"]}}],"variables":[{"name":"pnpm_config_minimum_release_age","weakens":"delay","values":"delay"},{"name":"pnpm_config_minimum_release_age_exclude","weakens":"delay","values":"any"},{"name":"pnpm_config_minimum_release_age_strict","weakens":"delay","values":{"except":["true"]}},{"name":"pnpm_config_ignore_scripts","weakens":"scripts","values":{"except":["true"]}},{"name":"pnpm_config_dangerously_allow_all_builds","weakens":"scripts","values":["true"]},{"name":"npm_config_minimum_release_age","weakens":"delay","values":"delay"},{"name":"npm_config_dangerously_allow_all_builds","weakens":"scripts","values":{"except":["false","null","undefined"]}}]} ↗
  • minimumReleaseAgeStrict (✅ verified): {"setting":"minimumReleaseAgeStrict","value":true,"since":"11.0.0"} ↗
  • cooldownExactVersions (✅ verified): 10.17.0 ↗
  • lockfileDocuments (✅ verified): {"bootMarker":"---","graph":"last"} ↗
  • lockfileFormat (✅ verified): {"installScripts":null,"gitKeyPrefix":"git+","gitHostedFlag":"gitHosted","gitHostedTarballHosts":["codeload.github.com","bitbucket.org","gitlab.com"],"gitType":"git","directoryType":"directory"} ↗
  • npmrcPrecedence (✅ verified): {"winner":"pnpm-workspace.yaml","over":[".npmrc","npm_config_*"]} ↗
  • npmrcCooldownKey (✅ verified): {"key":"minimum-release-age","until":"11.0.0"} ↗
  • sharedWorkspaceLockfile (✅ verified): {"setting":"sharedWorkspaceLockfile","npmrcKey":"shared-workspace-lockfile","default":true} ↗
  • perProjectNpmrc (❓ uncertain): {"sharedWorkspaceLockfile":false,"until":"11.0.0"} ❓ ↗
  • ignoredSince (✅ verified): {"since":"11.0.0","npmrc":"auth and registry settings","packageJsonField":"pnpm"} ↗
  • lockfileRecheck (❓ uncertain): 10.16.0+: false
    11.1.3+: true ❓ ↗
  • allowAllBuilds (✅ verified): {"setting":"dangerouslyAllowAllBuilds","since":"10.9.0","value":true,"off":[false,0,null,""]} ↗
  • excludeWildcards (✅ verified): {"since":"10.17.0","trailingOnly":false} ↗
  • onlyBuiltDependencies (✅ verified): {"since":"6.32.1","workspaceFileSince":"10.5.0","removedIn":"11.0.0"} ↗
  • ignoredBuiltDependencies (✅ verified): {"since":"10.1.0","workspaceFileSince":"10.5.0"} ↗
  • npmrcBuildSettings (✅ verified): {"allowAll":{"key":"dangerously-allow-all-builds","off":["false","null","undefined"],"since":"10.9.0"},"until":"11.0.0","projectKeys":[{"since":"10.13.0","value":["dangerouslyAllowAllBuilds","onlyBuiltDependencies","onlyBuiltDependenciesFile","neverBuiltDependencies"]},{"since":"10.26.0","value":["dangerouslyAllowAllBuilds","onlyBuiltDependencies","onlyBuiltDependenciesFile","neverBuiltDependencies","allowBuilds"]}]} ↗
  • yamlMergeKeys (✅ verified): true ↗
  • latestVersion (✅ verified): 12.16.1 ↗
  • npmrcIgnored (✅ verified): pnpm 11+ reads only auth and registry settings from .npmrc, ignores the package.json "pnpm" field and no longer reads npm_config_* variables ↗
  • buildPermissions (✅ verified): {"setting":"permissions","capability":"build","since":"12.11.0","allow":true,"deny":false} ↗
  • legacyAllowList (✅ verified): 10.0.0+: onlyBuiltDependencies (package.json pnpm field; pnpm-workspace.yaml since 10.5.0)
    10.26.0+: allowBuilds; onlyBuiltDependencies and ignoredBuiltDependencies deprecated
    11.0.0+: allowBuilds only; onlyBuiltDependencies, neverBuiltDependencies and ignoredBuiltDependencies removed ↗
  • strictDepBuilds (✅ verified): 10.3.0+: false
    11.0.0+: true ↗
  • strictMode (✅ verified): 11.0.0+: minimumReleaseAgeStrict defaults to false
    11.0.4+: strict whenever minimumReleaseAge is set explicitly
    12.0.0+: explicit values treated as non-strict (regression)
    12.3.0+: strict whenever minimumReleaseAge is set explicitly ↗
  • ignoreMissingTime (✅ verified): minimumReleaseAgeIgnoreMissingTime defaults to true: packages whose registry metadata has no publish time skip the age check ↗
  • lockfileVerification (❓ uncertain): 10.16.0+: frozen-lockfile installs do not re-check versions already in the lockfile
    11.1.3+: lockfile entries are re-checked; trustLockfile: true (11.3.0) turns this off ❓ ↗
  • unknownWorkspaceKeys (✅ verified): pnpm 11 and earlier silently ignore misspelled pnpm-workspace.yaml settings; pnpm 12 warns ↗
  • tarballResolution (✅ verified): {"field":"tarball"} ↗
  • rootLifecycleScripts (✅ verified): {"events":["preinstall","install","postinstall","preprepare","prepare","postprepare"],"skippedBy":"ignoreScripts","allowListApplies":false} ↗
  • managesOwnVersion (✅ verified): {"since":"10.0.0","field":"packageManager"} ↗

Yarn (Berry)

  • environmentNames (✅ verified): {"prefix":"YARN_","match":"any-case"} ↗
  • registrySettings (✅ verified): {"file":".yarnrc.yml","path":["npmRegistryServer"],"applies":"all","effect":"replaces"}, {"file":".yarnrc.yml","path":["npmScopes","*","npmRegistryServer"],"applies":"scope","effect":"replaces"} ↗
  • yamlMergeKeys (✅ verified): false ↗
  • classicUserFile (✅ verified): {"until":"2.0.0","file":".yarnrc"} ↗
  • yarnPath (❓ uncertain): {"key":"yarnPath","releaseFile":"yarn-<version>.cjs","variables":["YARN_YARN_PATH","YARN_IGNORE_PATH"]} ❓ ↗
  • yarnPathRuns (✅ verified): {"file":".yarnrc.yml","key":"yarnPath","classicSince":"1.18.0"} ↗
  • denyList (✅ verified): {"file":"package.json","setting":"dependenciesMeta.<package>.built","value":false,"since":"2.0.0"} ↗
  • projectInstall (✅ verified): {"commands":["install"],"bare":true} ↗
  • commandLine (✅ verified): {"add":[["yarn","add"]],"run":[{"command":["yarn","dlx"],"packageOptions":["-p","--package"]}],"create":[{"command":["yarn","create"],"packageOptions":["-p","--package"]}],"createNames":"prefix-unless-prefixed","workspaceCommands":[{"command":["yarn","workspace"],"operands":1}],"valueOptions":["--mode"]} ↗
  • packageSpecs (✅ verified): {"git":[],"local":["link:","portal:","file:"],"workspace":["workspace:"]} ↗
  • registryOverrides (✅ verified): {"registryOptions":[],"registryVariables":["YARN_NPM_REGISTRY_SERVER"],"configOptions":[],"configVariables":["YARN_RC_FILENAME"]} ↗
  • registryFetch (✅ verified): {"protocol":"npm:","patch":"patch:","patchEnd":"#","params":"?"} ↗
  • lockfileFormat (✅ verified): {"installScripts":null,"registry":"npm:","workspace":"workspace:","patch":"patch:","file":"file:","directory":["portal:","link:"],"gitCommit":"#commit=","tarball":"\\.(?:tar\\.gz|tgz)$"} ↗
  • durationStrings (✅ verified): {"since":"4.11.0","syntax":"compact","before":"no effect"} ↗
  • scriptsSwitch (✅ verified): {"setting":"enableScripts","allow":true,"deny":false} ↗
  • excludeWildcards (✅ verified): {"since":"4.10.0","trailingOnly":false} ↗
  • berryLockfileMarker (❓ uncertain): __metadata ❓ ↗
  • classicLockfileHeader (✅ verified): # yarn lockfile v1 ↗
  • latestVersion (✅ verified): 4.18.1 ↗
  • bypassFlag (✅ verified): --no-time-gate on yarn add and yarn up (4.15.0+) ↗
  • directoryOptions (✅ verified): {"options":[{"name":"--cwd","moves":"directory","position":"first"},{"name":"--cwd","moves":"directory","position":"last","command":["yarn","add"]}],"variables":[]} ↗
  • configCommands (✅ verified): {"command":["yarn","config"],"writes":["set","unset"]} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--no-time-gate","weakens":"delay","values":"any"}],"variables":[{"name":"YARN_NPM_MINIMAL_AGE_GATE","weakens":"delay","values":"delay"},{"name":"YARN_NPM_PREAPPROVED_PACKAGES","weakens":"delay","values":"any"},{"name":"YARN_ENABLE_SCRIPTS","weakens":"scripts","values":{"except":["false","0"]}}]} ↗
  • perScopeGate (✅ verified): {"scopes":"npmScopes","setting":"npmMinimalAgeGate","since":"4.17.0","unset":"1d"} ↗
  • upgradeMigration (✅ verified): When the lockfile predates the new defaults and the key is unset, yarn install writes enableScripts: true, approvedGitRepositories: ["**"] and npmMinimalAgeGate: 0 into .yarnrc.yml ↗
  • missingPublishTime (✅ verified): Versions without a publish time are quarantined while the gate is on ↗
  • unknownSettings (❓ uncertain): Unknown keys in the project .yarnrc.yml throw (unless enableStrictSettings is false), so settings newer than the pinned Yarn break installs ❓ ↗

Bun

  • environmentNames (✅ verified): {"prefix":"","match":"exact"} ↗
  • registrySettings (✅ verified): {"file":"bunfig.toml","path":["install","registry"],"applies":"all","effect":"replaces","urlKey":"url"}, {"file":"bunfig.toml","path":["install","scopes","*"],"applies":"scope","effect":"replaces","urlKey":"url"} ↗
  • projectInstall (✅ verified): {"commands":["install"],"bare":false} ↗
  • commandLine (✅ verified): {"add":[["bun","add"]],"run":[{"command":["bunx"],"packageOptions":["-p","--package"]},{"command":["bun","x"],"packageOptions":["-p","--package"]}],"create":[{"command":["bun","create"],"packageOptions":[]}],"createNames":"prefix","valueOptions":["--omit","--filter","--ca","--cafile","--registry","--network-concurrency","--backend","--concurrent-scripts","--cache-dir","--config","--cwd","--env-file","--minimum-release-age"]} ↗
  • packageSpecs (✅ verified): {"git":["github:","git+ssh://","git+https://"],"local":[],"workspace":[],"scp":true} ↗
  • registryOverrides (✅ verified): {"registryOptions":["--registry"],"registryVariables":["BUN_CONFIG_REGISTRY"],"configOptions":["--config","-c"],"configVariables":[]} ↗
  • lockfileFormat (✅ verified): {"installScripts":"hasInstallScript","installScriptsSince":"1.4.4","git":["git+","github:"],"directory":["file:","link:"],"workspace":"workspace:","tarball":"\\.(?:tar\\.gz|tgz)$"} ↗
  • durationStrings (✅ verified): {"since":"1.4.4","syntax":"compact-or-words"} ↗
  • excludeWildcards (✅ verified): {"since":null,"trailingOnly":false} ↗
  • latestVersion (✅ verified): 1.4.4 ↗
  • trustedDependenciesReplacesDefaults (✅ verified): Adding trustedDependencies replaces the built-in trusted list, so default-trusted packages that are not listed stop running scripts ↗
  • lockedVersionsNotRechecked (✅ verified): minimumReleaseAge only affects new resolutions; versions already in bun.lock are kept ↗
  • bunxCooldown (✅ verified): bunx applies --minimum-release-age only since 1.4.4 ↗
  • directoryOptions (✅ verified): {"options":[{"name":"--cwd","moves":"directory"}],"variables":[]} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--minimum-release-age","weakens":"delay","values":"delay"},{"name":"--trust","weakens":"scripts","values":"any"}],"variables":[]} ↗

Deno

  • denyList (✅ verified): {"file":"deno.json","setting":"allowScripts.deny","value":"npm:<package>","since":"2.6.0"} ↗
  • commandLine (✅ verified): {"add":[["deno","add"],["deno","install"]],"run":[{"command":["deno","x"],"packageOptions":["--package","-p"],"binaryPath":true},{"command":["dx"],"packageOptions":["--package","-p"],"binaryPath":true},{"command":["denox"],"packageOptions":["--package","-p"],"binaryPath":true},{"command":["dnx"],"packageOptions":["--package","-p"],"binaryPath":true}],"create":[],"createNames":"prefix","fileOptions":["--entrypoint","-e"],"valueOptions":["--name","-n","--root","--os","--arch","-L","--log-level"],"commandOptions":[{"command":["deno","x"],"valueOptions":["--package","-p","--config","-c","--import-map","--cert","--min-dep-age","--location","--seed","--preload","--require","--conditions","--inspect-publish-uid"]},{"command":["dx"],"valueOptions":["--package","-p","--config","-c","--import-map","--cert","--min-dep-age","--location","--seed","--preload","--require","--conditions","--inspect-publish-uid"]},{"command":["denox"],"valueOptions":["--package","-p","--config","-c","--import-map","--cert","--min-dep-age","--location","--seed","--preload","--require","--conditions","--inspect-publish-uid"]},{"command":["dnx"],"valueOptions":["--package","-p","--config","-c","--import-map","--cert","--min-dep-age","--location","--seed","--preload","--require","--conditions","--inspect-publish-uid"]}]} ↗
  • lockfileFormat (✅ verified): {"installScripts":"scripts","installScriptsSinceLockfile":"5","sources":null,"peerSeparator":"_"} ↗
  • durationStrings (✅ verified): {"since":null,"syntax":"iso8601"} ↗
  • ageObjectKey (✅ verified): age ↗
  • excludeWildcards (✅ verified): {"since":"2.9.2","trailingOnly":true} ↗
  • npmSpecifierPrefix (✅ verified): npm: ↗
  • allowAllScripts (✅ verified): {"setting":"allowScripts","since":"2.6.0","value":true} ↗
  • latestVersion (✅ verified): 2.9.8 ↗
  • npmrcFormat (⚠️ disputed): ⚠️ whole days only, e.g. min-release-age=3 ↗ / a duration with a unit, e.g. min-release-age=72h ↗
  • fileLinkSkipped (⚠️ disputed): ⚠️ file: and link: dependencies in the project package.json are silently skipped ↗ / file: and link: specifiers in registry metadata of npm packages are skipped ↗
  • denoXCooldown (✅ verified): deno x honors minimumDependencyAge only since 2.9.4 ↗
  • installOverrides (✅ verified): {"options":[{"name":"--minimum-dependency-age","weakens":"delay","values":"delay"},{"name":"--min-dep-age","weakens":"delay","values":"delay"},{"name":"--allow-scripts","weakens":"scripts","values":"any"}],"variables":[]} ↗
  • dxRunsScripts (✅ verified): dx defaults to --allow-all and runs lifecycle scripts once the download prompt is accepted ↗

uv

  • environmentNames (✅ verified): {"prefix":"","match":"exact"} ↗
  • registrySettings (✅ verified): {"file":"pyproject.toml","path":["tool","uv","index"],"applies":"all","effect":"adds","urlKey":"url","entries":{"nameKey":"name","rules":[{"key":"explicit","value":true,"effect":"pinned"},{"key":"default","value":true,"effect":"replaces"}],"first":"adds","others":"adds","pins":{"file":"pyproject.toml","tables":[["tool","uv","sources"]],"key":"index"}}}, {"file":"pyproject.toml","path":["tool","uv","index-url"],"applies":"all","effect":"replaces"}, {"file":"pyproject.toml","path":["tool","uv","extra-index-url"],"applies":"all","effect":"adds"}, {"file":"pyproject.toml","path":["tool","uv","find-links"],"applies":"all","effect":"adds"}, {"file":"pyproject.toml","path":["tool","uv","pip","index-url"],"applies":"all","effect":"replaces"}, {"file":"pyproject.toml","path":["tool","uv","pip","extra-index-url"],"applies":"all","effect":"adds"}, {"file":"pyproject.toml","path":["tool","uv","pip","find-links"],"applies":"all","effect":"adds"}, {"file":"uv.toml","path":["index"],"applies":"all","effect":"adds","urlKey":"url","entries":{"nameKey":"name","rules":[{"key":"explicit","value":true,"effect":"pinned"},{"key":"default","value":true,"effect":"replaces"}],"first":"adds","others":"adds","pins":{"file":"pyproject.toml","tables":[["tool","uv","sources"]],"key":"index"}}}, {"file":"uv.toml","path":["index-url"],"applies":"all","effect":"replaces"}, {"file":"uv.toml","path":["extra-index-url"],"applies":"all","effect":"adds"}, {"file":"uv.toml","path":["find-links"],"applies":"all","effect":"adds"}, {"file":"uv.toml","path":["pip","index-url"],"applies":"all","effect":"replaces"}, {"file":"uv.toml","path":["pip","extra-index-url"],"applies":"all","effect":"adds"}, {"file":"uv.toml","path":["pip","find-links"],"applies":"all","effect":"adds"} ↗
  • pylockCreatedBy (✅ verified): uv ↗
  • configTables (✅ verified): {"pyproject.toml":"tool.uv","uv.toml":""} ↗
  • pyprojectTable (✅ verified): tool.uv ↗
  • configPrecedence (✅ verified): uv.toml wins over [tool.uv] in the same directory; only the nearest directory with either is read, and in a workspace only the root ↗
  • configFileOrder (✅ verified): uv.toml, pyproject.toml ↗
  • workspaceRootOnly (✅ verified): true ↗
  • buildSwitch (✅ verified): {"setting":"no-build","value":true,"since":"0.2.12","covers":["registry","git","remoteTarball","file","directory"]} ↗
  • durationStrings (✅ verified): {"since":"0.9.17","syntax":"words-or-iso8601"} ↗
  • durationUnits (✅ verified): hours, days, weeks ↗
  • excludeWildcards (✅ verified): {"since":null,"trailingOnly":false} ↗
  • excludeValue (✅ verified): false ↗
  • missingUploadTime (✅ verified): A file from an index that gives no upload time is treated as unavailable while a delay is set ↗
  • registryOnly (✅ verified): The delay applies only to packages read from a registry, not to git, URL or path dependencies ↗
  • requiredVersion (✅ verified): {"table":"tool.uv","key":"required-version","since":"0.5.14"} ↗
  • lockfileFormat (❓ uncertain): {"sources":{"registry":"registry","git":"git","remoteTarball":"url","file":"path","directory":"directory","editable":"editable","virtual":"virtual"},"sdist":"sdist","wheels":"wheels","packages":"package"} ❓ ↗
  • ignoredByToolCommands (✅ verified): uv tool install, uv tool run and uvx ignore pyproject.toml and uv.toml in the project and read only user and system configuration ↗
  • lockedSettings (✅ verified): {"settings":["exclude-newer","exclude-newer-package"],"lock":"uv lock","failing":["uv sync --locked","uv lock --check"]} ↗
  • lockOptions (✅ verified): {"table":"options","timestamp":"exclude-newer","span":"exclude-newer-span","packages":"exclude-newer-package","packageTimestamp":"timestamp","packageSpan":"span","placeholder":"0001-01-01T00:00:00Z"} ↗
  • lockComparison (✅ verified): {"spans":"fieldwise","absolute":"earlier","packages":"locked-or-recorded","dateOnly":"next-day-system-time-zone"} ↗
  • spanSyntax (✅ verified): {"friendlyUnits":{"years":["years","year","yrs","yr","y"],"months":["months","month","mos","mo"],"weeks":["weeks","week","wks","wk","w"],"days":["days","day","d"],"hours":["hours","hour","hrs","hr","h"],"minutes":["minutes","minute","mins","min","m"],"seconds":["seconds","second","secs","sec","s"],"milliseconds":["milliseconds","millisecond","millis","milli","msecs","msec","ms"],"microseconds":["microseconds","microsecond","micros","micro","usecs","usec","us"],"nanoseconds":["nanoseconds","nanosecond","nanos","nano","nsecs","nsec","ns"]},"rejectedUnits":["years","months"]} ↗
  • commandLine (✅ verified): {"add":[["uv","add"],["uv","pip","install"],["uv","tool","install"]],"run":[{"command":["uvx"],"packageOptions":["--from"],"extraPackageOptions":["-w","--with","--with-editable"]},{"command":["uv","tool","run"],"packageOptions":["--from"],"extraPackageOptions":["-w","--with","--with-editable"]},{"command":["uv","run"],"packageOptions":[],"extraPackageOptions":["-w","--with","--with-editable"],"packageArgument":false,"scriptUrls":true}],"create":[],"valueOptions":["--cache-dir","--config-file","--color","--allow-insecure-host","--trusted-host","--directory","--project","--python-preference","--python-fetch","--preview-features","--preview-feature","--index","--default-index","-i","--index-url","--extra-index-url","-f","--find-links","-P","--upgrade-package","--upgrade-group","--reinstall-package","--index-strategy","--keyring-provider","--resolution","--prerelease","--prerelease-package","--fork-strategy","-C","--config-setting","--config-settings","--config-settings-package","--no-build-isolation-package","--exclude-newer","--exclude-newer-package","--link-mode","--no-sources-package","--refresh-package","--no-build-package","--no-binary-package","-c","--constraints","--constraint","--overrides","--override","--excludes","--exclude","-b","--build-constraints","--build-constraint","-r","--requirements","--requirement","--group","--extra","--no-editable-package","-p","--python","-t","--target","--prefix","--python-version","--python-platform","--output-format","--torch-backend","--optional","--bounds","--rev","--tag","--branch","--package","--script","--no-install-package","--only-install-package","-w","--with","--with-editable","--with-requirements","--no-extra","--no-group","--only-group","--env-file","--max-recursion-depth","--from","--with-executables-from"],"parsing":{"groupedShortOptions":true},"addPackageOptions":["-w","--with","--with-editable","--with-executables-from"],"editableOptions":["--with-editable"],"commaSeparatedOptions":["-w","--with","--with-editable","--with-executables-from"],"interpreterNames":["python","pythonw","cpython","pypy","graalpy","pyodide"],"commandOptions":[{"command":["uv","pip","install"],"valueOptions":["-e","--editable","--no-binary","--only-binary"],"editableOptions":["-e","--editable"]},{"command":["uv","add"],"valueOptions":["-m","--marker"]}]} ↗
  • registryOverrides (✅ verified): {"registryOptions":["--index","--default-index","-i","--index-url","--extra-index-url","-f","--find-links"],"registryVariables":["UV_INDEX","UV_DEFAULT_INDEX","UV_INDEX_URL","UV_EXTRA_INDEX_URL","UV_FIND_LINKS"],"configOptions":["--config-file"],"configVariables":["UV_CONFIG_FILE"]} ↗
  • selection (✅ verified): {"prereleases":{"onFlags":["--pre"],"modeOptions":["--prerelease"],"packageModeOptions":["--prerelease-package"],"onModes":["allow"],"offModes":["disallow"],"modeVariables":["UV_PRERELEASE"]},"buildFromSource":{"onFlags":["--no-binary"],"offFlags":["--binary"],"onPackages":["--no-binary-package"],"flagVariables":["UV_NO_BINARY"],"onPackageVariables":["UV_NO_BINARY_PACKAGE"]},"commands":[{"command":["uv","pip","install"],"buildFromSource":{"onLists":["--no-binary"],"offLists":["--only-binary"]}}]} ↗
  • latestVersion (✅ verified): 0.13.6 ↗
  • directoryOptions (✅ verified): {"options":[{"name":"--directory","moves":"directory"},{"name":"--project","moves":"project","ignoredBy":[["uv","pip"]]}],"variables":[{"name":"UV_WORKING_DIR","moves":"directory"},{"name":"UV_WORKING_DIRECTORY","moves":"directory"},{"name":"UV_PROJECT","moves":"project","ignoredBy":[["uv","pip"]]}]} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--exclude-newer","weakens":"delay","values":"delay"},{"name":"--exclude-newer-package","weakens":"delay","values":"any"}],"variables":[{"name":"UV_EXCLUDE_NEWER","weakens":"delay","values":"delay"}]} ↗
  • pipTable (✅ verified): {"table":"pip","keys":{"exclude-newer":"exclude-newer","exclude-newer-package":"exclude-newer-package","no-binary-package":"no-binary"}} ↗

pip

  • environmentNames (✅ verified): {"prefix":"PIP_","match":"prefix-then-any-case"} ↗
  • configCommand (✅ verified): {"command":"config","writes":["set","unset","edit"]} ↗
  • configSections (✅ verified): {"global":"global","commandsOverride":true} ↗
  • pylockCreatedBy (✅ verified): pip ↗
  • requirementsOptions (✅ verified): -i, --index-url, --pypi-url, --extra-index-url, --no-index, -c, --constraint, -r, --requirement, -e, --editable, -f, --find-links, --no-binary, --only-binary, --prefer-binary, --require-hashes, --no-require-hashes, --pre, --all-releases, --only-final, --trusted-host, --use-feature ↗
  • requirementsParser (✅ verified): {"longOptions":["--index-url","--pypi-url","--extra-index-url","--no-index","--constraint","--requirement","--editable","--find-links","--no-binary","--only-binary","--prefer-binary","--require-hashes","--no-require-hashes","--pre","--all-releases","--only-final","--trusted-host","--use-feature","--hash","--config-settings"],"shortOptions":["-i","-c","-r","-e","-f","-C"],"abbreviations":true} ↗
  • buildSwitch (❓ uncertain): {"setting":"--only-binary","value":":all:","since":"7.0.0","covers":["registry"]} ❓ ↗
  • configFileNames (✅ verified): pip.conf, pip.ini ↗
  • configFileVariable (✅ verified): PIP_CONFIG_FILE ↗
  • environmentVariable (✅ verified): PIP_UPLOADED_PRIOR_TO ↗
  • durationStrings (✅ verified): {"since":"26.1.0","syntax":"iso8601"} ↗
  • missingUploadTime (✅ verified): Installation fails when an index gives no upload time while --uploaded-prior-to is set ↗
  • lockfileFormat (✅ verified): {"packages":"packages","vcs":"vcs","directory":"directory","archive":"archive","sdist":"sdist","wheels":"wheels","index":"index","createdBy":"created-by","sources":{"git":"vcs","remoteTarball":"archive","directory":"directory"}} ↗
  • requirementsForms (✅ verified): name==version with --hash options, name @ URL for an archive, a local archive or project path, and VCS URLs (name @ git+https://… or -e git+…) ↗
  • requirementsFormat (✅ verified): {"vcs":{"git":["git+"],"other":["hg+","svn+","bzr+"]},"direct":" @ ","editable":["-e","--editable"],"egg":"#egg=","comment":"#","continuation":"\\"} ↗
  • requirementsIncludes (✅ verified): {"requirements":["-r","--requirement"],"constraints":["-c","--constraint"]} ↗
  • requirementsPaths (✅ verified): {"separators":["/","\\"],"currentDirectory":".","archiveExtensions":[".zip",".whl",".tar.bz2",".tbz",".tar.gz",".tgz",".tar",".tar.xz",".txz",".tlz",".tar.lz",".tar.lzma"],"urlSchemes":["http","https","ftp"],"fileScheme":"file:"} ↗
  • lockfilePattern (✅ verified): ^pylock\.([^.]+)\.toml$ ↗
  • commandLine (✅ verified): {"add":[["pip","install"],["pip3","install"]],"run":[],"create":[],"valueOptions":["-r","--requirement","-c","--constraint","--build-constraint","--requirements-from-script","-e","--editable","--group","-t","--target","--platform","--python-version","--implementation","--abi","--root","--prefix","--src","--source","--source-dir","--source-directory","--upgrade-strategy","-C","--config-settings","--progress-bar","--root-user-action","--report","-i","--index-url","--pypi-url","--extra-index-url","-f","--find-links","--refresh-package","--uploaded-prior-to","--no-binary","--only-binary","--all-releases","--only-final","--python","--log","--log-file","--local-log","--keyring-provider","--proxy","--retries","--resume-retries","--timeout","--default-timeout","--exists-action","--trusted-host","--cert","--client-cert","--cache-dir","--use-feature","--use-deprecated"],"flagOptions":["--no-deps","--no-dependencies","--only-deps","--only-dependencies","--dry-run","--user","--no-user","-U","--upgrade","--force-reinstall","-I","--ignore-installed","--ignore-requires-python","--no-build-isolation","--use-pep517","--check-build-dependencies","--break-system-packages","--compile","--no-compile","--no-warn-script-location","--no-warn-conflicts","--require-hashes","--no-require-hashes","--no-clean","--no-index","--pre","--prefer-binary","-h","--help","--debug","--isolated","--require-virtualenv","--require-venv","-v","--verbose","-V","--version","-q","--quiet","--no-input","--no-proxy-env","--no-cache-dir","--disable-pip-version-check","--no-color","--no-python-version-warning"],"parsing":{"abbreviations":true,"groupedShortOptions":true},"editableOptions":["-e","--editable"]} ↗
  • registryOverrides (✅ verified): {"registryOptions":["-i","--index-url","--pypi-url","--extra-index-url","-f","--find-links"],"registryVariables":["PIP_INDEX_URL","PIP_PYPI_URL","PIP_EXTRA_INDEX_URL","PIP_FIND_LINKS"],"configOptions":[],"configVariables":["PIP_CONFIG_FILE"]} ↗
  • selection (✅ verified): {"prereleases":{"onFlags":["--pre"],"onLists":["--all-releases"],"offLists":["--only-final"],"flagVariables":["PIP_PRE"],"onListVariables":["PIP_ALL_RELEASES"],"offListVariables":["PIP_ONLY_FINAL"]},"buildFromSource":{"onLists":["--no-binary"],"offLists":["--only-binary"],"onListVariables":["PIP_NO_BINARY"],"offListVariables":["PIP_ONLY_BINARY"]}} ↗
  • pipxSelection (✅ verified): {"prereleases":{"flagVariables":["PIP_PRE"],"onListVariables":["PIP_ALL_RELEASES"],"offListVariables":["PIP_ONLY_FINAL"]},"buildFromSource":{"onListVariables":["PIP_NO_BINARY"],"offListVariables":["PIP_ONLY_BINARY"]}} ↗
  • pipxCommandLine (✅ verified): {"add":[["pipx","install"]],"run":[{"command":["pipx","run"],"packageOptions":["--spec"],"extraPackageOptions":["--with"],"scriptSuffixes":[".py"]}],"create":[],"valueOptions":["-i","--index-url","--pip-args","--preinstall","--lock","--include-resources-from","--upgrade-strategy","--suffix","--python","--fetch-python","--app","--cooldown","--backend","--output","--python-args"],"flagOptions":["-q","--quiet","-v","--verbose","--skip-maintenance","--global","-f","--force","-U","--upgrade","--include-deps","--system-site-packages","--fetch-missing-python","-e","--editable","--no-cache","--refresh","--no-path-check","--path","--pypackages","--version"],"parsing":{"abbreviations":true,"groupedShortOptions":true},"addPackageOptions":["--preinstall"]} ↗
  • pipxRegistryOverrides (✅ verified): {"registryOptions":["-i","--index-url"],"registryVariables":[],"configOptions":["--pip-args"],"configVariables":[]} ↗
  • latestVersion (✅ verified): 26.2.2 ↗
  • configCommands (✅ verified): {"command":["pip","config"],"writes":["set","unset","edit"]}, {"command":["pip3","config"],"writes":["set","unset","edit"]} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--uploaded-prior-to","weakens":"delay","values":"delay"}],"variables":[{"name":"PIP_UPLOADED_PRIOR_TO","weakens":"delay","values":"delay"}]} ↗

Poetry

  • environmentNames (✅ verified): {"prefix":"","match":"exact"} ↗
  • installedPackage (✅ verified): {"name":"poetry","commands":[["pipx","install"],["pip","install"]]} ↗
  • pylockCreatedBy (✅ verified): poetry-plugin-export ↗
  • configTable (✅ verified): {"solver":"solver","installer":"installer"} ↗
  • pyprojectTable (✅ verified): tool.poetry ↗
  • configLocation (✅ verified): poetry.toml is read only from the directory of the pyproject.toml Poetry found (the current directory or the nearest parent with one) ↗
  • buildSwitch (✅ verified): {"setting":"installer.only-binary","value":[":all:"],"since":"2.0.0","covers":["registry"]} ↗
  • excludeFormat (⚠️ disputed): ⚠️ comma-separated string ↗ / TOML array ↗
  • excludeWildcards (✅ verified): {"since":null,"trailingOnly":false} ↗
  • missingUploadTime (✅ verified): A release whose source gives no upload times is not filtered by solver.min-release-age ↗
  • lockedVersionsKept (❓ uncertain): poetry lock and poetry add keep versions already in poetry.lock even when they are newer than the delay allows; poetry update and poetry lock --regenerate resolve them again ❓ ↗
  • requiredVersion (✅ verified): {"table":"tool.poetry","key":"requires-poetry","since":"2.0.0"} ↗
  • lockfileFormat (❓ uncertain): {"sources":{"git":"git","remoteTarball":"url","file":"file","directory":"directory","registry":"legacy"},"packages":"package","source":"source","files":"files"} ❓ ↗
  • commandLine (✅ verified): {"add":[["poetry","add"]],"run":[],"create":[],"valueOptions":["-C","--directory","-P","--project","-G","--group","-E","--extras","--optional","--python","--platform","--markers","--source"],"parsing":{"groupedShortOptions":true}} ↗
  • registryOverrides (✅ verified): {"registryOptions":["--source"],"registryVariables":[],"configOptions":[],"configVariables":[]} ↗
  • versionConstraints (✅ verified): {"separator":"@","latest":"latest","caret":"^","tilde":"~","any":"*"} ↗
  • selection (✅ verified): {"prereleases":{"onFlags":["--allow-prereleases"]},"buildFromSource":{"onListVariables":["POETRY_INSTALLER_NO_BINARY"],"offListVariables":["POETRY_INSTALLER_ONLY_BINARY"],"listBooleans":true}} ↗
  • latestVersion (✅ verified): 2.5.1 ↗
  • directoryOptions (✅ verified): {"options":[{"name":"-C","moves":"directory"},{"name":"--directory","moves":"directory"},{"name":"-P","moves":"project"},{"name":"--project","moves":"project"}],"variables":[]} ↗
  • registrySettings (✅ verified): {"file":"pyproject.toml","path":["tool","poetry","source"],"applies":"all","effect":"replaces","urlKey":"url","entries":{"nameKey":"name","rules":[{"key":"priority","value":"supplemental","effect":"adds"},{"key":"priority","value":"explicit","effect":"pinned"}],"first":"replaces","others":"replaces","pypiName":"pypi","pins":{"file":"pyproject.toml","tables":[["tool","poetry","dependencies"],["tool","poetry","group","*","dependencies"]],"key":"source"}}} ↗
  • configCommands (✅ verified): {"command":["poetry","config"],"operands":2,"options":["--unset","--migrate"]}, {"command":["poetry","source"],"writes":["add","remove"]} ↗
  • installOverrides (✅ verified): {"options":[],"variables":[{"name":"POETRY_SOLVER_MIN_RELEASE_AGE","weakens":"delay","values":"delay"},{"name":"POETRY_SOLVER_MIN_RELEASE_AGE_EXCLUDE","weakens":"delay","values":"any"},{"name":"POETRY_SOLVER_MIN_RELEASE_AGE_EXCLUDE_SOURCE","weakens":"delay","values":"any"}]} ↗

PDM

  • environmentNames (✅ verified): {"prefix":"","match":"exact"} ↗
  • pylockCreatedBy (✅ verified): pdm ↗
  • configTables (✅ verified): {"pyproject.toml":"tool.pdm.resolution"} ↗
  • pyprojectTable (✅ verified): tool.pdm ↗
  • buildSwitch (✅ verified): {"setting":"only-binary","value":":all:","since":"2.15.0","covers":["registry"]} ↗
  • durationStrings (✅ verified): {"since":"2.26.8","syntax":"compact"} ↗
  • durationUnits (✅ verified): hours, days, weeks ↗
  • excludeWildcards (✅ verified): {"since":null,"trailingOnly":false} ↗
  • excludeValue (✅ verified): false ↗
  • missingUploadTime (✅ verified): A distribution without an upload time is treated as unavailable while a cutoff applies to its package ↗
  • lockfileFormat (❓ uncertain): {"packages":"package","files":"files","file":"file","vcs":["git","hg","svn","bzr"],"url":"url","path":"path","editable":"editable"} ❓ ↗
  • lockedSettings (✅ verified): {"settings":"table","lock":"pdm lock","failing":["pdm lock --check","pdm install --check"]} ↗
  • lockHash (✅ verified): {"key":["metadata","content_hash"],"separator":":","inputs":["metadata","lock_inputs"],"inputsSetting":["tool","pdm","resolution","lock_inputs"],"workspace":["tool","pdm","workspace"],"project":["project"],"fields":[{"name":"sources","path":["tool","pdm","source"],"missing":[]},{"name":"dependencies","path":["project","dependencies"],"missing":[]},{"name":"optional-dependencies","path":["project","optional-dependencies"],"missing":{}},{"name":"requires-python","path":["project","requires-python"],"missing":""},{"name":"resolution","path":["tool","pdm","resolution"],"missing":{}}],"groups":{"name":"dev-dependencies","tables":[["dependency-groups"],["tool","pdm","dev-dependencies"]],"separators":"[^A-Za-z0-9]+"}} ↗
  • uvMode (❓ uncertain): {"file":"pdm.toml","key":"use_uv"} ❓ ↗
  • directoryOptions (✅ verified): {"options":[{"name":"-p","moves":"project"},{"name":"--project","moves":"project"}],"variables":[{"name":"PDM_PROJECT","moves":"project"}]} ↗
  • commandLine (✅ verified): {"add":[["pdm","add"]],"run":[],"create":[],"valueOptions":["-c","--config","--pep582","-L","--lockfile","-G","--group","-k","--skip","-e","--editable","-p","--project","--venv","--override"],"flagOptions":["-V","--version","-h","--help","-v","--verbose","-q","--quiet","--no-cache","-I","--ignore-python","-n","--non-interactive","-g","--global","-d","--dev","--no-sync","--frozen-lockfile","--no-lock","--save-compatible","--save-safe-compatible","--save-wildcard","--save-exact","--save-minimum","--update-reuse","--update-eager","--update-all","--update-reuse-installed","--pre","--prerelease","--stable","-u","--unconstrained","--no-editable","--no-self","-x","--fail-fast","--no-isolation","--dry-run"],"parsing":{"abbreviations":true,"groupedShortOptions":true},"editableOptions":["-e","--editable"]} ↗
  • registrySettings (✅ verified): {"file":"pyproject.toml","path":["tool","pdm","source"],"applies":"all","effect":"adds","urlKey":"url","entries":{"nameKey":"name","rules":[{"key":"type","value":"find_links","effect":"adds"},{"key":"name","value":"pypi","effect":"replaces"}],"first":"adds","others":"adds","pypiName":"pypi"}} ↗
  • registryOverrides (✅ verified): {"registryOptions":[],"registryVariables":["PDM_PYPI_URL"],"configOptions":["-c","--config"],"configVariables":["PDM_CONFIG_FILE"]} ↗
  • configCommands (✅ verified): {"command":["pdm","config"],"operands":2,"options":["-d","--delete","-e","--edit"]} ↗
  • selection (✅ verified): {"prereleases":{"onFlags":["--pre","--prerelease"],"offFlags":["--stable"]},"buildFromSource":{"onListVariables":["PDM_NO_BINARY"],"offListVariables":["PDM_ONLY_BINARY"]}} ↗
  • latestVersion (✅ verified): 2.29.5 ↗

Pipenv

  • environmentNames (✅ verified): {"prefix":"PIPENV_","match":"exact"}, {"prefix":"PIP_","match":"prefix-then-any-case"} ↗
  • pylockCreatedBy (✅ verified): pipenv ↗
  • configTables (✅ verified): {"Pipfile":"pipenv"} ↗
  • durationStrings (✅ verified): {"since":"2026.6.2","syntax":"compact"} ↗
  • durationUnits (✅ verified): days ↗
  • missingUploadTime (✅ verified): An index without upload times makes the setting accepted but without effect ↗
  • resolverBypass (❓ uncertain): {"table":"pipenv","keys":["resolver_backend","resolver"],"value":"pure-python"} ❓ ↗
  • lockfileFormat (✅ verified): {"meta":"_meta","git":"git","file":"file","path":"path","editable":"editable","hashes":"hashes","version":"version"} ↗
  • commandLine (✅ verified): {"add":[["pipenv","install"]],"run":[],"create":[],"valueOptions":["--pypi-mirror","--python","--extra-pip-args","--resolver","--categories","--extras","--config-settings","-i","--index","-r","--requirements","-e","--editable"],"flagOptions":["-h","--help","--version","--where","--venv","--py","--envs","--rm","--bare","--man","--support","-v","--verbose","-q","--quiet","--clear","--site-packages","--no-site-packages","--pre","-d","--dev","--all","--ignore-pipfile","--skip-lock","--system","--deploy"],"parsing":{"abbreviations":true,"groupedShortOptions":true},"editableOptions":["-e","--editable"]} ↗
  • registryOverrides (✅ verified): {"registryOptions":["-i","--index","--pypi-mirror"],"registryVariables":["PIPENV_PYPI_MIRROR"],"configOptions":["--extra-pip-args"],"configVariables":["PIPENV_DOTENV_LOCATION"]} ↗
  • directoryOptions (✅ verified): {"options":[],"variables":[{"name":"PIPENV_PIPFILE","moves":"project","file":"Pipfile"}]} ↗
  • registrySettings (✅ verified): {"file":"Pipfile","path":["source"],"applies":"all","effect":"replaces","urlKey":"url","entries":{"nameKey":"name","rules":[],"first":"replaces","others":"pinned","pins":{"file":"Pipfile","tables":[["*"]],"key":"index"},"searchAll":["pipenv","install_search_all_sources"]}} ↗
  • selection (✅ verified): {"prereleases":{"onFlags":["--pre"]},"buildFromSource":{"onListVariables":["PIP_NO_BINARY"],"offListVariables":["PIP_ONLY_BINARY"]}} ↗
  • latestVersion (✅ verified): 2026.10.4 ↗

Composer

  • environmentNames (✅ verified): {"prefix":"","match":"exact"} ↗
  • latestVersion (✅ verified): 2.11.1 ↗
  • durationStrings (✅ verified): {"since":"2.11.0","syntax":"unit-word","numbers":"seconds","trim":false} ↗
  • durationUnits (✅ verified): days ↗
  • excludeWildcards (✅ verified): {"since":"2.11.0","trailingOnly":false} ↗
  • denyList (✅ verified): {"file":"composer.json","setting":"config.allow-plugins","value":false,"since":"2.2.0"} ↗
  • cooldownTime (✅ verified): {"published":"published-time","author":"time","requireSetting":"require-published-time","authorTimeRepositories":["vcs","path","artifact"]} ↗
  • lockedVersions (✅ verified): composer install installs the locked versions without the cooldown; a partial update keeps every other locked version, a full composer update re-evaluates them all ↗
  • olderVersions (❓ uncertain): Composer 2.10 reads policy.cooldown as a custom dependency policy without sources, which blocks nothing; older versions ignore config.policy as an unknown config key ❓ ↗
  • contentHash (✅ verified): {"file":"composer.lock","key":"content-hash","settings":["config.policy"],"since":"2.11.0","command":"composer update --lock"} ↗
  • pluginApiVersion (✅ verified): {"key":"plugin-api-version","cooldownApi":"2.11.0"} ↗
  • lockfileFormat (✅ verified): {"sections":["packages","packages-dev"],"name":"name","version":"version","installScripts":"type","pluginType":"composer-plugin","pluginTypes":["composer-plugin","composer-installer"],"optionalPlugin":["extra","plugin-optional"],"source":"source","dist":"dist","pathType":"path","archiveTypes":["zip","tar","gzip","xz","phar","rar"]} ↗
  • legacyLockPlugins (✅ verified): {"below":"2.2.0","missing":"1.1.0","allowsAllUntil":"2.10.0"} ↗
  • manifestSyntax (✅ verified): {"comments":false,"trailingCommas":false} ↗
  • sourceInstall (✅ verified): {"source":"source","dist":"dist"} ↗
  • registryDistHosts (✅ verified): api.github.com, gitlab.com, bitbucket.org, codeberg.org ↗
  • repositoryArchiveHosts (✅ verified): {"wpackagist.org":["downloads.wordpress.org"]} ↗
  • branchVersions (✅ verified): {"prefix":"dev-","suffix":"-dev"} ↗
  • repositoryTypes (✅ verified): {"vcs":["vcs","git","github","gitlab","bitbucket","git-bitbucket","svn","hg","fossil","perforce"],"directory":["path"],"file":["artifact"],"inline":["package"],"registry":["composer"],"disable":"packagist.org"} ↗
  • weakeningSettings (✅ verified): {"path":["config","policy"],"when":"false","effect":"turns off every dependency policy, the cooldown and malware blocking included"}, {"path":["config","policy","cooldown"],"when":"false","effect":"turns off the cooldown"}, {"path":["config","policy","cooldown","block"],"when":"php-false","effect":"stops the cooldown from withholding new versions"}, {"path":["config","policy","malware"],"when":"false","effect":"turns off blocking of versions flagged as malware"}, {"path":["config","policy","malware","block"],"when":"php-false","effect":"stops blocking versions flagged as malware"}, {"path":["config","policy","malware","block-scope"],"when":"update","effect":"blocks versions flagged as malware only on update, so composer install still installs them from composer.lock"} ↗
  • transportSettings (✅ verified): {"path":["config","secure-http"],"weakensWhen":false,"effect":"allows downloads over plain HTTP"}, {"path":["config","disable-tls"],"weakensWhen":true,"effect":"downloads without TLS and turns off secure-http"} ↗
  • allowAllPlugins (✅ verified): {"setting":"config.allow-plugins","value":true,"patterns":["*","*/*"]} ↗
  • repositoryWeakening (✅ verified): {"key":"require-published-time","when":"false","effect":"lets the cooldown count from the time the package author wrote into composer.json"}, {"key":"filter","when":"false","list":"malware","effect":"skips the malware list that the repository advertises"} ↗
  • environmentOverrides (✅ verified): {"name":"COMPOSER_POLICY","values":["0","false","off"],"effect":"turns off every dependency policy, the cooldown included"}, {"name":"COMPOSER_NO_BLOCKING","values":["1","true","on","false","off"],"effect":"turns off all policy blocking, the cooldown and malware blocking included"}, {"name":"COMPOSER_NO_SECURITY_BLOCKING","values":["1","true","on","false","off"],"effect":"turns off all policy blocking, the cooldown and malware blocking included"}, {"name":"COMPOSER_POLICY_COOLDOWN_PERIOD","values":"delay","effect":"replaces the cooldown period"}, {"name":"COMPOSER_POLICY_COOLDOWN_BLOCK","values":["0","false","off"],"effect":"stops the cooldown from withholding new versions"}, {"name":"COMPOSER_POLICY_MALWARE_BLOCK","values":["0","false","off"],"effect":"stops blocking versions flagged as malware"} ↗
  • packagistApi (✅ verified): {"url":"https://repo.packagist.org","metadataPath":"/p2/{name}.json","devSuffix":"~dev","notFoundStatus":404,"packagesField":"packages","minifiedField":"minified","minifiedValue":"composer/2.0","unsetValue":"__unset","versionField":"version","normalizedField":"version_normalized","timeField":"time","publishedField":"published-time","typeField":"type","abandonedField":"abandoned","packagePage":"https://packagist.org/packages/{name}"} ↗
  • metadataMinifier (✅ verified): {"firstEntry":"whole","emptyIsFirst":true,"unsetValue":"__unset"} ↗
  • versionConstraints (✅ verified): {"and":[","," "],"or":["||","|"],"hyphen":" - ","wildcards":["*","x","X"],"tilde":"~","caret":"^","operators":[">=","<=","<>","!=","==",">","<","="],"stabilityFlag":"@","branchPrefix":"dev-","branchSuffix":"-dev","alias":" as ","reference":"#"} ↗
  • stabilities (✅ verified): {"order":["stable","RC","beta","alpha","dev"],"priorities":{"stable":0,"RC":5,"beta":10,"alpha":15,"dev":20},"minimumStability":"stable","modifiers":{"a":"alpha","alpha":"alpha","b":"beta","beta":"beta","rc":"RC","p":"patch","pl":"patch","patch":"patch","stable":"stable"}} ↗
  • versionComparison (✅ verified): {"separators":["-","_","+"],"specialForms":[["dev",0],["alpha",1],["a",1],["beta",2],["b",2],["RC",3],["rc",3],["#",4],["pl",5],["p",5]],"numberOrder":4} ↗
  • commandLine (✅ verified): {"add":[["composer","require"],["composer","r"],["composer","global","require"],["composer","global","r"]],"run":[],"create":[{"command":["composer","create-project"],"packageOptions":[]}],"valueOptions":["-d","--working-dir","--prefer-install","--audit-format","--ignore-platform-req","--apcu-autoloader-prefix","--with","--bump-after-update","-s","--stability","--repository","--repository-url","--require","-f","--file","--before","--after"],"parsing":{"groupedShortOptions":true}} ↗
  • commandNames (✅ verified): {"commands":["about","archive","audit","browse","bump","check-platform-reqs","clear-cache","completion","config","create-project","depends","diagnose","dump-autoload","exec","fund","global","help","init","install","licenses","list","outdated","policy","prohibits","reinstall","remove","repository","require","run-script","search","self-update","show","status","suggests","update","validate","_complete"],"aliases":{"home":"browse","clearcache":"clear-cache","cc":"clear-cache","why":"depends","dumpautoload":"dump-autoload","i":"install","why-not":"prohibits","rm":"remove","uninstall":"remove","repo":"repository","r":"require","run":"run-script","selfupdate":"self-update","info":"show","u":"update","upgrade":"update"},"matching":"symfony-console","hidden":["_complete"]} ↗
  • commandArguments (✅ verified): {"require":"require","update":"update","createProject":"create-project","global":"global","pairSeparators":[":","="," "],"platformPackages":"^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9]+(?:[_.-][a-z0-9]+)*|composer(?:-(?:plugin|runtime)-api)?)$","namePattern":"^[a-z0-9]+(?:[_.-][a-z0-9]+)*/[a-z0-9]+(?:(?:[_.]|-{1,2})[a-z0-9]+)*$","updateLockWords":["lock","nothing","mirrors"],"withOption":"--with","requireOption":"--require","stabilityOptions":["--stability","-s"]} ↗
  • registryOverrides (✅ verified): {"registryOptions":["--repository","--repository-url"],"registryVariables":[],"configOptions":[],"configVariables":["COMPOSER","COMPOSER_HOME"]} ↗
  • installOverrides (✅ verified): {"options":[{"name":"--no-blocking","weakens":"protection","values":"any","effect":"turns off all of Composer's policy blocking for the command, the cooldown and the blocking of versions flagged as malware included"},{"name":"--no-security-blocking","weakens":"protection","values":"any","effect":"turns off all of Composer's policy blocking for the command, the cooldown and the blocking of versions flagged as malware included"},{"name":"--no-cooldown","weakens":"delay","values":"any"},{"name":"--no-secure-http","weakens":"protection","values":"any","effect":"turns off secure-http while Composer installs the project package","protects":"secure-http lets Composer download only over HTTPS, which keeps that download from being read or changed on the way"}],"variables":[{"name":"COMPOSER_NO_BLOCKING","weakens":"protection","values":{"except":["","0"]},"effect":"turns off all of Composer's policy blocking for the command, the cooldown and the blocking of versions flagged as malware included"},{"name":"COMPOSER_NO_SECURITY_BLOCKING","weakens":"protection","values":{"except":["","0"]},"effect":"turns off all of Composer's policy blocking for the command, the cooldown and the blocking of versions flagged as malware included"},{"name":"COMPOSER_POLICY","weakens":"protection","values":["0","false","off"],"effect":"turns off every dependency policy of Composer for the command, the cooldown and the blocking of versions flagged as malware included"},{"name":"COMPOSER_POLICY_COOLDOWN_PERIOD","weakens":"delay","values":"delay"},{"name":"COMPOSER_POLICY_COOLDOWN_BLOCK","weakens":"delay","values":["0","false","off"]},{"name":"COMPOSER_POLICY_MALWARE_BLOCK","weakens":"protection","values":["0","false","off"],"effect":"turns off the blocking of versions flagged as malware"}]} ↗
  • configCommands (✅ verified): {"command":["composer","config"],"operands":2,"options":["--unset","--editor","-e"],"unread":{"file":"COMPOSER_HOME/config.json, or the file --file names","options":["--global","-g","--file","-f"]}}, {"command":["composer","repository"],"writes":["add","remove","rm","delete","set-url","seturl","enable","disable"],"unread":{"file":"COMPOSER_HOME/config.json, or the file --file names","options":["--global","-g","--file","-f"]}}, {"command":["composer","policy"],"writes":["add-source"],"unread":{"file":"COMPOSER_HOME/config.json, or the file --file names","options":["--global","-g","--file","-f"]}}, {"command":["composer","global","config"],"operands":2,"options":["--unset","--editor","-e"],"unread":{"file":"a file of COMPOSER_HOME"}}, {"command":["composer","global","repository"],"writes":["add","remove","rm","delete","set-url","seturl","enable","disable"],"unread":{"file":"a file of COMPOSER_HOME"}}, {"command":["composer","global","policy"],"writes":["add-source"],"unread":{"file":"a file of COMPOSER_HOME"}} ↗
  • applicationOptions (✅ verified): {"name":"help","shortcuts":["h"],"value":"none"}, {"name":"quiet","shortcuts":["q"],"value":"none"}, {"name":"verbose","shortcuts":["v","vv","vvv"],"value":"none"}, {"name":"version","shortcuts":["V"],"value":"none"}, {"name":"ansi","shortcuts":[],"value":"negatable"}, {"name":"no-interaction","shortcuts":["n"],"value":"none"}, {"name":"profile","shortcuts":[],"value":"none"}, {"name":"no-plugins","shortcuts":[],"value":"none"}, {"name":"no-scripts","shortcuts":[],"value":"none"}, {"name":"working-dir","shortcuts":["d"],"value":"required"}, {"name":"no-cache","shortcuts":[],"value":"none"} ↗
  • scriptCommands (✅ verified): {"scripts":"scripts","aliases":"scripts-aliases","events":["pre-install-cmd","post-install-cmd","pre-update-cmd","post-update-cmd","pre-status-cmd","post-status-cmd","pre-autoload-dump","post-autoload-dump","post-root-package-install","post-create-project-cmd","pre-archive-cmd","post-archive-cmd"],"validName":"^[^:]+(?::[^:]+)*$"} ↗
  • scriptAliases (✅ verified): {"key":"scripts-aliases","since":"2.7.0"} ↗
  • rootStability (✅ verified): {"minimumStability":"minimum-stability","preferStable":"prefer-stable","values":["stable","rc","beta","alpha","dev"]} ↗
  • installPreference (✅ verified): {"setting":"preferred-install","default":"dist","dist":"dist","source":"source","auto":"auto","everything":"*"} ↗
  • sourceFallback (✅ verified): {"since":"2.10.0","setting":"source-fallback","removedIn":"2.11.0"} ↗
  • registrySourceHosts (✅ verified): {"api.github.com":"github.com","gitlab.com":"gitlab.com","bitbucket.org":"bitbucket.org","codeberg.org":"codeberg.org"} ↗
  • sourceHostAliases (✅ verified): {"www.github.com":"github.com"} ↗
  • directoryOptions (✅ verified): {"options":[{"name":"--working-dir","moves":"directory"},{"name":"-d","moves":"directory"}],"variables":[],"lookup":"first-token"} ↗

Renovate

  • configLocation (✅ verified): {"from":"repository-root","branch":"default"} ↗
  • durationStrings (✅ verified): {"since":null,"syntax":"words"} ↗
  • minimumReleaseAgePresets (✅ verified): {"presets":["config:best-practices","security:minimumReleaseAgeNpm"],"value":"3 days","since":"42.0.0","datasource":"npm"} ↗
  • excludeRule (✅ verified): {"list":"packageRules","match":"matchPackageNames","value":null} ↗
  • securityUpdatesSetting (✅ verified): vulnerabilityAlerts, minimumReleaseAge ↗
  • excludeWildcards (✅ verified): {"since":"38.0.0","trailingOnly":false} ↗
  • ruleDescription (✅ verified): description ↗
  • packageJsonConfig (✅ verified): {"file":"package.json","key":"renovate"} ↗
  • durationUnits (✅ verified): hours, days ↗
  • presets (✅ verified): config:best-practices extends security:minimumReleaseAgeNpm (since 42.0.0): "3 days" and internalChecksFilter "strict" for the npm datasource, except pin, replacement, lockFileMaintenance, bump, lockfileUpdate and rollback ↗
  • datasources (✅ verified): {"npm":"npm","pypi":"pypi","packagist":"packagist"} ↗
  • packagistReleaseTime (✅ verified): {"field":"published-time","fallback":"time"} ↗
  • negativeMatch (✅ verified): ! ↗
  • packageRuleMatching (✅ verified): {"negation":"!","allPatterns":"*","packageMatchers":["matchPackageNames","matchDepNames"],"datasourceMatcher":"matchDatasources","updateTypeMatcher":"matchUpdateTypes"} ↗
  • packageRulesOrder (✅ verified): {"presetsFirst":true,"overridesTopLevel":true,"laterWins":true} ↗
  • delayedUpdateTypes (✅ verified): major, minor, patch ↗
  • internalPresets (✅ verified): {"prefixes":[":","default:","abandonments:","config:","customManagers:","docker:","global:","group:","helpers:","mergeConfidence:","monorepo:","packages:","preview:","replacements:","schedule:","security:","workarounds:"],"settingDelay":["config:best-practices","security:minimumReleaseAgeCrate","security:minimumReleaseAgeNpm","security:minimumReleaseAgePypi"]} ↗
  • pypiPresets (✅ verified): {"presets":["security:minimumReleaseAgePypi"],"value":"3 days","since":"44.8.0","datasource":"pypi"} ↗
  • pnpmSecurityExclusions (❓ uncertain): {"managers":["pnpm"],"file":"pnpm-workspace.yaml","setting":"minimumReleaseAgeExclude","comment":"# Renovate security update: ","versionSeparator":" || "} ❓ ↗
  • pythonManagers (✅ verified): {"uv":"pep621","poetry":"poetry","pip":"pip_requirements","pdm":"pep621","pipenv":"pipenv"} ↗
  • managers (✅ verified): {"npm":"npm","pnpm":"npm","yarn":"npm","bun":"bun","deno":"deno","uv":"pep621","pdm":"pep621","poetry":"poetry","pip":"pip_requirements","pipenv":"pipenv","composer":"composer","github-actions":"github-actions"} ↗
  • managerCategories (✅ verified): {"npm":["js"],"bun":["js"],"deno":["js"],"pep621":["python"],"pip_requirements":["python"],"poetry":["python"],"pipenv":["python"],"composer":["php"],"github-actions":["ci"]} ↗
  • managerMatching (✅ verified): {"managerMatcher":"matchManagers","categoryMatcher":"matchCategories","customPrefix":"custom.","stringIsList":true} ↗
  • githubActions (✅ verified): {"manager":"github-actions","datasource":"github-tags","digestDatasource":"github-digest"} ↗
  • actionsMatching (✅ verified): {"fileMatcher":"matchFileNames","fileStringIsList":false,"depTypeMatcher":"matchDepTypes","depTypeStringIsList":true,"depType":"action"} ↗
  • actionsTimestamps (✅ verified): {"github-tags":"the commit date of a lightweight tag or the tagger date of an annotated tag, or the date of a GitHub release of that version when that is newer","github-digest":"the commit date","missing":"held"} ↗
  • passesDelayToManager (✅ verified): earlier: []
    44.34.0+: poetry ↗
  • missingTimestamp (✅ verified): earlier: updates without a release timestamp pass the check
    42.0.0+: minimumReleaseAgeBehaviour timestamp-required: such updates are held ↗
  • internalChecksFilter (✅ verified): Defaults to "strict" since 33.0.0; with "none" or "flexible" branches and PRs are created before the delay ends and only automerge waits ↗
  • independentOfPackageManager (✅ verified): minimumReleaseAge is set independently of the package manager's own release-age configuration ↗
  • digestBypassFixed (⚠️ disputed): ⚠️ 44.3.1 ↗ / 44.10.0 ↗

Dependabot

  • configLocation (✅ verified): {"from":"repository-root","branch":"default"} ↗
  • directories (✅ verified): {"keys":["directory","directories"],"relativeTo":"repository-root","globsIn":"directories"} ↗
  • yamlMergeKeys (❓ uncertain): false ❓ ↗
  • cooldownKeys (✅ verified): {"days":"default-days","exclude":"exclude","semverDays":["semver-major-days","semver-minor-days","semver-patch-days"]} ↗
  • excludeWildcards (✅ verified): {"since":"0.0.0","trailingOnly":false} ↗
  • excludeMatching (✅ verified): {"starMatchesSlash":true,"caseSensitive":true} ↗
  • cooldownInclude (✅ verified): {"key":"include","everything":"*"} ↗
  • ecosystems (✅ verified): {"npm":["npm","pnpm","yarn"],"bun":["bun"],"deno":["deno"],"pip":["pip","poetry","pipenv"],"uv":["uv"],"composer":["composer"]} ↗
  • yamlAliases (✅ verified): {"accepted":false} ↗
  • yamlScalars (✅ verified): {"library":"psych","version":"5.5.0","integers":"legacy"} ↗
  • githubActions (✅ verified): {"ecosystem":"github-actions","semverDays":false} ↗
  • actionsReleaseDate (❓ uncertain): the publication date of the GitHub release of the tag, else the date of the tag, else the date of the commit; with no date the update does not wait ❓ ↗
  • dayRange (⚠️ disputed): ⚠️ 1 to 90 days ↗ / 0 removes the cooldown ↗
  • maximumDays (✅ verified): 90 ↗
  • missingPublishDate (✅ verified): Updates proceed when the registry gives no publication date (fail open); for Docker only Docker Hub tag_last_pushed is used ↗
  • transitiveGating (❓ uncertain): Regular updates pass the cooldown to npm (11.10+), pnpm (10.16+) and Yarn Berry to hold back transitive dependencies; the Bun updater passes none ❓ ↗
  • composerReleaseTime (✅ verified): {"field":"time","ignores":"published-time","composerVersion":"2.10.3"} ↗
  • composerContentHash (✅ verified): {"composerVersion":"2.10.3","hashesPolicy":false,"file":"composer.lock","key":"content-hash"} ↗
  • semverKeysScope (✅ verified): semver-major/minor/patch-days apply only to SemVer ecosystems such as npm, Bun and Deno; others use default-days ↗

Environment

How repositories pin tool versions (Corepack, devEngines, Volta, asdf) and how GitHub Actions installs them.

  • corepack.packageManagerField (✅ verified): {"key":"packageManager","managers":["npm","pnpm","yarn"]} ↗
  • corepack.devEnginesSince (✅ verified): 0.32.0 ↗
  • corepack.envFileSince (✅ verified): 0.32.0 ↗
  • corepack.bundledWithNode (✅ verified): earlier: false
    14.19.0+: true
    25.0.0+: false ↗
  • corepack.package (✅ verified): corepack ↗
  • corepack.toolPackages (✅ verified): {"npm":["npm"],"pnpm":["pnpm"],"yarn":["yarn","@yarnpkg/cli-dist"]} ↗
  • corepack.defaults (⚠️ disputed): ⚠️ {"since":"0.13.0","locations":[{"platforms":["linux","darwin"],"directories":[{"from":{"env":"COREPACK_HOME","emptyCounts":true},"path":""},{"from":{"env":"XDG_CACHE_HOME","emptyCounts":true},"path":"node/corepack"},{"from":{"env":"LOCALAPPDATA","emptyCounts":true},"path":"node/corepack"},{"from":"home","path":".cache/node/corepack"}],"file":"lastKnownGood.json"},{"platforms":["win32"],"directories":[{"from":{"env":"COREPACK_HOME","emptyCounts":true},"path":""},{"from":{"env":"XDG_CACHE_HOME","emptyCounts":true},"path":"node/corepack"},{"from":{"env":"LOCALAPPDATA","emptyCounts":true},"path":"node/corepack"},{"from":"home","path":"AppData/Local/node/corepack"}],"file":"lastKnownGood.json"}]} ↗ / {"since":"0.13.0","locations":[{"platforms":["linux","darwin"],"directories":[{"from":{"env":"COREPACK_HOME"},"path":""},{"from":"home","path":".cache/node/corepack"}],"file":"lastKnownGood.json"},{"platforms":["win32"],"directories":[{"from":{"env":"COREPACK_HOME"},"path":""},{"from":{"env":"LOCALAPPDATA"},"path":"node/corepack"}],"file":"lastKnownGood.json"}]} ↗
  • corepack.enableNpm (✅ verified): {"command":"enable","npmOnlyWhenNamed":true} ↗
  • corepack.manualInstall (✅ verified): {"package":"corepack","command":"npm install -g corepack","enable":"corepack enable"} ↗
  • installScriptPackages.esbuild (✅ verified): {"name":"esbuild","versions":["0.28.2"],"script":"postinstall: node install.js","kind":"not-needed","does":"it only puts the binary, which esbuild takes from an optional dependency for the platform, in place of the esbuild command and checks that it runs","withoutScript":"the esbuild command starts through a small Node.js script instead of the binary itself (install.js never makes that change on Windows or with Yarn anyway), and the install no longer checks that the binary runs","needsOptionalDependencies":true} ↗
  • installScriptPackages.fsevents (✅ verified): {"name":"fsevents","versions":["2.3.3"],"script":"install: node-gyp rebuild","kind":"not-needed","does":"it is the node-gyp rebuild that npm adds because the source has a binding.gyp, while the package already contains the built fsevents.node","withoutScript":"nothing changes","needsOptionalDependencies":false} ↗
  • installScriptPackages.lefthook (✅ verified): {"name":"lefthook","versions":["2.2.2"],"script":"postinstall: node postinstall.js","kind":"project-task","does":"it runs lefthook install, which installs the git hooks of the repository","withoutScript":"the install no longer installs the git hooks","needsOptionalDependencies":false,"projectStep":{"command":"lefthook install","after":"clone"}} ↗
  • node.bundledNpm (✅ verified): {"line":"0.6","latest":"0.6.21","bundles":[["0.6.3","1.1.0-alpha-2"],["0.6.4","1.1.0-alpha-6"],["0.6.6","1.1.0-beta-4"],["0.6.7","1.1.0-beta-10"],["0.6.8","1.1.0-2"],["0.6.9","1.1.0-3"],["0.6.11","1.1.1"],["0.6.12","1.1.4"],["0.6.13","1.1.9"],["0.6.14","1.1.12"],["0.6.15","1.1.16"],["0.6.16","1.1.19"],["0.6.17","1.1.21"],["0.6.19","1.1.24"],["0.6.20","1.1.37"]]}, {"line":"0.7","latest":"0.7.12","bundles":[["0.7.0","1.1.0-2"],["0.7.2","1.1.0-3"],["0.7.4","1.1.1"],["0.7.6","1.1.8"],["0.7.7","1.1.15"],["0.7.8","1.1.18"],["0.7.9","1.1.23"],["0.7.10","1.1.25"],["0.7.11","1.1.26"],["0.7.12","1.1.30"]]}, {"line":"0.8","latest":"0.8.28","bundles":[["0.8.0","1.1.32"],["0.8.1","1.1.33"],["0.8.2","1.1.36"],["0.8.3","1.1.43"],["0.8.4","1.1.45"],["0.8.5","1.1.46"],["0.8.6","1.1.48"],["0.8.7","1.1.49"],["0.8.8","1.1.59"],["0.8.9","1.1.61"],["0.8.10","1.1.62"],["0.8.12","1.1.63"],["0.8.13","1.1.65"],["0.8.15","1.1.66"],["0.8.16","1.1.69"],["0.8.17","1.2.0"],["0.8.18","1.2.2"],["0.8.19","1.2.10"],["0.8.20","1.2.11"],["0.8.22","1.2.14"],["0.8.23","1.2.18"],["0.8.24","1.2.24"],["0.8.25","1.2.30"]]}, {"line":"0.9","latest":"0.9.12","bundles":[["0.9.0","1.1.44"],["0.9.1","1.1.59"],["0.9.2","1.1.61"],["0.9.3","1.1.64"],["0.9.4","1.1.70"],["0.9.6","1.2.0"],["0.9.7","1.2.2"],["0.9.8","1.2.3"],["0.9.9","1.2.10"],["0.9.10","1.2.12"]]}, {"line":"0.10","latest":"0.10.48","bundles":[["0.10.0","1.2.14"],["0.10.1","1.2.15"],["0.10.3","1.2.17"],["0.10.4","1.2.18"],["0.10.7","1.2.21"],["0.10.8","1.2.23"],["0.10.9","1.2.24"],["0.10.10","1.2.25"],["0.10.11","1.2.30"],["0.10.12","1.2.32"],["0.10.13","1.3.2"],["0.10.14","1.3.5"],["0.10.16","1.3.8"],["0.10.19","1.3.11"],["0.10.22","1.3.14"],["0.10.23","1.3.17"],["0.10.24","1.3.21"],["0.10.25","1.3.24"],["0.10.26","1.4.3"],["0.10.27","1.4.8"],["0.10.28","1.4.9"],["0.10.29","1.4.14"],["0.10.30","1.4.21"],["0.10.31","1.4.23"],["0.10.32","1.4.28"],["0.10.41","1.4.29"],["0.10.44","2.15.0"],["0.10.45","2.15.1"]]}, {"line":"0.11","latest":"0.11.16","bundles":[["0.11.0","1.2.15"],["0.11.1","1.2.18"],["0.11.2","1.2.21"],["0.11.3","1.2.25"],["0.11.4","1.3.4"],["0.11.5","1.3.6"],["0.11.6","1.3.8"],["0.11.8","1.3.13"],["0.11.9","1.3.15"],["0.11.10","1.3.22"],["0.11.11","1.3.25"],["0.11.12","1.4.3"],["0.11.13","1.4.9"],["0.11.14","2.0.0"],["0.11.15","2.1.6"],["0.11.16","2.3.0"]]}, {"line":"0.12","latest":"0.12.18","bundles":[["0.12.0","2.5.1"],["0.12.2","2.7.4"],["0.12.3","2.9.1"],["0.12.4","2.10.1"],["0.12.5","2.11.2"],["0.12.7","2.11.3"],["0.12.8","2.14.9"],["0.12.13","2.15.0"],["0.12.14","2.15.1"],["0.12.18","2.15.11"]]}, {"line":"4","latest":"4.9.1","bundles":[["4.0.0","2.14.2"],["4.1.0","2.14.3"],["4.1.1","2.14.4"],["4.2.0","2.14.7"],["4.2.4","2.14.12"],["4.4.0","2.14.20"],["4.4.2","2.15.0"],["4.4.3","2.15.1"],["4.4.5","2.15.5"],["4.4.7","2.15.8"],["4.5.0","2.15.9"],["4.6.2","2.15.11"]]}, {"line":"5","latest":"5.12.0","bundles":[["5.0.0","3.3.6"],["5.1.0","3.3.12"],["5.6.0","3.6.0"],["5.8.0","3.7.3"],["5.10.0","3.8.3"],["5.11.0","3.8.6"]]}, {"line":"6","latest":"6.17.1","bundles":[["6.0.0","3.8.6"],["6.2.0","3.8.9"],["6.2.1","3.9.3"],["6.2.2","3.9.5"],["6.3.0","3.10.3"],["6.8.0","3.10.8"],["6.9.2","3.10.9"],["6.9.3","3.10.10"]]}, {"line":"7","latest":"7.10.1","bundles":[["7.0.0","3.10.8"],["7.1.0","3.10.9"],["7.2.1","3.10.10"],["7.4.0","4.0.5"],["7.5.0","4.1.2"],["7.8.0","4.2.0"]]}, {"line":"8","latest":"8.17.0","bundles":[["8.0.0","5.0.0"],["8.1.0","5.0.3"],["8.2.0","5.3.0"],["8.7.0","5.4.2"],["8.9.0","5.5.1"],["8.9.4","5.6.0"],["8.12.0","6.4.1"],["8.17.0","6.13.4"]]}, {"line":"9","latest":"9.11.2","bundles":[["9.0.0","5.5.1"],["9.4.0","5.6.0"]]}, {"line":"10","latest":"10.24.1","bundles":[["10.0.0","5.6.0"],["10.3.0","6.1.0"],["10.8.0","6.2.0"],["10.10.0","6.4.1"],["10.16.0","6.9.0"],["10.17.0","6.11.3"],["10.18.0","6.13.4"],["10.20.0","6.14.4"],["10.22.0","6.14.6"],["10.23.0","6.14.8"],["10.23.1","6.14.10"],["10.23.3","6.14.11"],["10.24.1","6.14.12"]]}, {"line":"11","latest":"11.15.0","bundles":[["11.0.0","6.4.1"],["11.6.0","6.5.0-next.0"],["11.7.0","6.5.0"],["11.10.0","6.7.0"]]}, {"line":"12","latest":"12.22.12","bundles":[["12.0.0","6.9.0"],["12.7.0","6.10.0"],["12.8.0","6.10.2"],["12.10.0","6.10.3"],["12.11.0","6.11.3"],["12.13.0","6.12.0"],["12.13.1","6.12.1"],["12.14.0","6.13.4"],["12.16.2","6.14.4"],["12.18.1","6.14.5"],["12.18.3","6.14.6"],["12.19.0","6.14.8"],["12.20.1","6.14.10"],["12.20.2","6.14.11"],["12.22.1","6.14.12"],["12.22.2","6.14.13"],["12.22.4","6.14.14"],["12.22.6","6.14.15"],["12.22.10","6.14.16"]]}, {"line":"13","latest":"13.14.0","bundles":[["13.0.0","6.12.0"],["13.1.0","6.12.1"],["13.2.0","6.13.1"],["13.4.0","6.13.4"],["13.7.0","6.13.6"],["13.9.0","6.13.7"],["13.12.0","6.14.4"]]}, {"line":"14","latest":"14.21.3","bundles":[["14.0.0","6.14.4"],["14.3.0","6.14.5"],["14.6.0","6.14.6"],["14.7.0","6.14.7"],["14.9.0","6.14.8"],["14.15.2","6.14.9"],["14.15.4","6.14.10"],["14.15.5","6.14.11"],["14.16.1","6.14.12"],["14.17.0","6.14.13"],["14.17.4","6.14.14"],["14.17.6","6.14.15"],["14.19.0","6.14.16"],["14.19.2","6.14.17"],["14.21.3","6.14.18"]]}, {"line":"15","latest":"15.14.0","bundles":[["15.0.0","7.0.2"],["15.0.1","7.0.3"],["15.1.0","7.0.8"],["15.3.0","7.0.14"],["15.4.0","7.0.15"],["15.5.0","7.3.0"],["15.6.0","7.4.0"],["15.7.0","7.4.3"],["15.8.0","7.5.1"],["15.9.0","7.5.3"],["15.11.0","7.6.0"],["15.12.0","7.6.3"],["15.13.0","7.7.6"]]}, {"line":"16","latest":"16.20.2","bundles":[["16.0.0","7.10.0"],["16.1.0","7.11.2"],["16.2.0","7.13.0"],["16.3.0","7.15.1"],["16.4.0","7.18.1"],["16.5.0","7.19.1"],["16.6.1","7.20.3"],["16.8.0","7.21.0"],["16.9.0","7.21.1"],["16.10.0","7.24.0"],["16.11.0","8.0.0"],["16.12.0","8.1.0"],["16.13.1","8.1.2"],["16.14.0","8.3.1"],["16.14.1","8.5.0"],["16.15.0","8.5.5"],["16.15.1","8.11.0"],["16.17.0","8.15.0"],["16.18.0","8.19.2"],["16.19.0","8.19.3"],["16.20.0","8.19.4"]]}, {"line":"17","latest":"17.9.1","bundles":[["17.0.0","8.1.0"],["17.1.0","8.1.2"],["17.2.0","8.1.4"],["17.3.0","8.3.0"],["17.4.0","8.3.1"],["17.5.0","8.4.1"],["17.6.0","8.5.1"],["17.7.0","8.5.2"],["17.8.0","8.5.5"],["17.9.1","8.11.0"]]}, {"line":"18","latest":"18.20.8","bundles":[["18.0.0","8.6.0"],["18.1.0","8.8.0"],["18.2.0","8.9.0"],["18.3.0","8.11.0"],["18.4.0","8.12.1"],["18.6.0","8.13.2"],["18.7.0","8.15.0"],["18.8.0","8.18.0"],["18.9.0","8.19.1"],["18.10.0","8.19.2"],["18.13.0","8.19.3"],["18.14.0","9.3.1"],["18.14.2","9.5.0"],["18.16.0","9.5.1"],["18.17.0","9.6.7"],["18.18.0","9.8.1"],["18.19.0","10.2.3"],["18.19.1","10.2.4"],["18.20.0","10.5.0"],["18.20.3","10.7.0"],["18.20.5","10.8.2"]]}, {"line":"19","latest":"19.9.0","bundles":[["19.0.0","8.19.2"],["19.1.0","8.19.3"],["19.3.0","9.2.0"],["19.5.0","9.3.1"],["19.6.0","9.4.0"],["19.7.0","9.5.0"],["19.8.0","9.5.1"],["19.9.0","9.6.3"]]}, {"line":"20","latest":"20.20.2","bundles":[["20.0.0","9.6.4"],["20.2.0","9.6.6"],["20.3.0","9.6.7"],["20.4.0","9.7.2"],["20.5.0","9.8.0"],["20.6.0","9.8.1"],["20.7.0","10.1.0"],["20.10.0","10.2.3"],["20.11.0","10.2.4"],["20.12.0","10.5.0"],["20.13.0","10.5.2"],["20.14.0","10.7.0"],["20.16.0","10.8.1"],["20.17.0","10.8.2"]]}, {"line":"21","latest":"21.7.3","bundles":[["21.0.0","10.2.0"],["21.2.0","10.2.3"],["21.3.0","10.2.4"],["21.7.0","10.5.0"]]}, {"line":"22","latest":"22.23.4","bundles":[["22.0.0","10.5.1"],["22.1.0","10.7.0"],["22.3.0","10.8.1"],["22.5.0","10.8.2"],["22.9.0","10.8.3"],["22.10.0","10.9.0"],["22.13.0","10.9.2"],["22.18.0","10.9.3"],["22.21.0","10.9.4"],["22.22.2","10.9.7"],["22.22.3","10.9.8"],["22.23.3","10.9.9"]]}, {"line":"23","latest":"23.11.1","bundles":[["23.0.0","10.9.0"],["23.4.0","10.9.2"]]}, {"line":"24","latest":"24.22.2","bundles":[["24.0.0","11.3.0"],["24.3.0","11.4.2"],["24.5.0","11.5.1"],["24.8.0","11.6.0"],["24.10.0","11.6.1"],["24.11.1","11.6.2"],["24.13.1","11.8.0"],["24.14.0","11.9.0"],["24.14.1","11.11.0"],["24.15.0","11.12.1"],["24.16.0","11.13.0"],["24.18.0","11.16.0"],["24.19.0","11.17.0"],["24.20.0","11.19.0"],["24.22.0","11.19.1"]]}, {"line":"25","latest":"25.9.0","bundles":[["25.0.0","11.6.2"],["25.4.0","11.7.0"],["25.5.0","11.8.0"],["25.6.1","11.9.0"],["25.7.0","11.10.1"],["25.8.0","11.11.0"],["25.8.2","11.11.1"],["25.9.0","11.12.1"]]}, {"line":"26","latest":"26.13.0","bundles":[["26.0.0","11.12.1"],["26.1.0","11.13.0"],["26.3.0","11.16.0"],["26.4.0","11.17.0"],["26.6.0","11.18.0"],["26.7.0","11.19.0"],["26.8.2","11.19.1"],["26.11.0","11.20.0"]]} ↗
  • node.releaseSchedule (✅ verified): {"line":4,"start":"2015-09-08","lts":"2015-10-12","end":"2018-04-30","codename":"argon"}, {"line":5,"start":"2015-10-29","end":"2016-06-30"}, {"line":6,"start":"2016-04-26","lts":"2016-10-18","end":"2019-04-30","codename":"boron"}, {"line":7,"start":"2016-10-25","end":"2017-06-30"}, {"line":8,"start":"2017-05-30","lts":"2017-10-31","end":"2019-12-31","codename":"carbon"}, {"line":9,"start":"2017-10-01","end":"2018-06-30"}, {"line":10,"start":"2018-04-24","lts":"2018-10-30","end":"2021-04-30","codename":"dubnium"}, {"line":11,"start":"2018-10-23","end":"2019-06-01"}, {"line":12,"start":"2019-04-23","lts":"2019-10-21","end":"2022-04-30","codename":"erbium"}, {"line":13,"start":"2019-10-22","end":"2020-06-01"}, {"line":14,"start":"2020-04-21","lts":"2020-10-27","end":"2023-04-30","codename":"fermium"}, {"line":15,"start":"2020-10-20","end":"2021-06-01"}, {"line":16,"start":"2021-04-20","lts":"2021-10-26","end":"2023-09-11","codename":"gallium"}, {"line":17,"start":"2021-10-19","end":"2022-06-01"}, {"line":18,"start":"2022-04-19","lts":"2022-10-25","end":"2025-04-30","codename":"hydrogen"}, {"line":19,"start":"2022-10-18","end":"2023-06-01"}, {"line":20,"start":"2023-04-18","lts":"2023-10-24","end":"2026-04-30","codename":"iron"}, {"line":21,"start":"2023-10-17","end":"2024-06-01"}, {"line":22,"start":"2024-04-24","lts":"2024-10-29","end":"2027-04-30","codename":"jod"}, {"line":23,"start":"2024-10-16","end":"2025-06-01"}, {"line":24,"start":"2025-05-06","lts":"2025-10-28","end":"2028-04-30","codename":"krypton"}, {"line":25,"start":"2025-10-15","end":"2026-06-01"}, {"line":26,"start":"2026-05-05","lts":"2026-10-28","end":"2029-04-30","codename":"lithium"}, {"line":27,"start":"2027-04-22","lts":"2027-10-20","end":"2030-04-30"} ↗
  • node.nvmrc (✅ verified): {"file":".nvmrc","comment":"#","newest":["node","stable"],"newestLts":"lts/*","ltsPrefix":"lts/","previousLtsPrefix":"lts/-"} ↗
  • node.nodeVersionFile (✅ verified): {"file":".node-version"} ↗
  • node.engines (✅ verified): {"key":"engines","runtimeKey":"node"} ↗
  • node.inheritedVersionFiles (✅ verified): .nvmrc, .node-version, .tool-versions ↗
  • docker.imageReference (✅ verified): {"defaultHost":"docker.io","hosts":["docker.io","index.docker.io","registry-1.docker.io"],"officialNamespace":"library","defaultTag":"latest"} ↗
  • docker.syntax (✅ verified): {"comment":"#","escapeDirective":"escape","escapeCharacters":["\\","`"],"globalArgInstruction":"ARG"} ↗
  • docker.copySources (✅ verified): {"relativeTo":"context","parentNavigation":"removed","trailingSlash":"ignored"} ↗
  • docker.environment (✅ verified): {"instruction":"ENV","inheritedByStages":true,"spaceForm":true} ↗
  • docker.dockerfileNames (✅ verified): {"defaultName":"Dockerfile","suffix":".Dockerfile"} ↗
  • docker.dockerfilePrefix (❓ uncertain): Dockerfile. ❓ ↗
  • docker.containerfile (✅ verified): Containerfile ↗
  • docker.nodeImage (✅ verified): {"image":"node","bundles":"npm","variants":["alpine","slim","alpine3.23","alpine3.24","bookworm","bookworm-slim","trixie","trixie-slim"]} ↗
  • docker.nodeImageTags (❓ uncertain): {"tags":{"latest":"26","current":"26","lts":"26"}} ❓ ↗
  • docker.pythonImage (✅ verified): {"image":"python","bundles":"pip","variants":["alpine","slim","trixie","slim-trixie","bookworm","slim-bookworm","alpine3.23","alpine3.24"]} ↗
  • docker.pythonImageTags (❓ uncertain): {"tags":{"3":"3.15","latest":"3.15"}} ❓ ↗
  • devEngines (✅ verified): {"key":"devEngines","packageManagerKey":"packageManager","runtimeKey":"runtime"} ↗
  • devEnginesSince (✅ verified): 10.9.0 ↗
  • volta.manifest (✅ verified): {"key":"volta","tools":["node","npm","pnpm","yarn"]} ↗
  • volta.maintained (✅ verified): false ↗
  • asdf.toolVersionsFile (✅ verified): .tool-versions ↗
  • asdf.plugins (✅ verified): {"nodejs":"node","pnpm":"pnpm","yarn":"yarn","bun":"bun","deno":"deno","python":"python","uv":"uv","poetry":"poetry"} ↗
  • githubActions.workflows (✅ verified): {"directory":".github/workflows","extensions":[".yml",".yaml"]} ↗
  • githubActions.jobId (✅ verified): {"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$"} ↗
  • githubActions.setupNode (✅ verified): {"action":"actions/setup-node","installs":["node"],"inputs":[{"name":"node-version","kind":"version","tool":"node"},{"name":"node-version-file","kind":"version-file","tool":"node"}]} ↗
  • githubActions.setupNodeVersions (✅ verified): {"newest":["latest","current","node","*"],"newestLts":"lts/*","ltsPrefix":"lts/","previousLtsPrefix":"lts/-"} ↗
  • githubActions.setupNodeVersionFile (✅ verified): {"packageJson":"package.json","packageJsonOrder":["volta.node","devEngines.runtime","engines.node"],"textPattern":"^(?:node(js)?\\s+)?v?(?<version>[^\\s]+)$"} ↗
  • githubActions.jobContainer (✅ verified): {"key":"container","imageKey":"image","envKey":"env"} ↗
  • githubActions.environmentKeys (✅ verified): {"key":"env","levels":["workflow","job","step"]} ↗
  • githubActions.yamlAliases (✅ verified): {"accepted":true} ↗
  • githubActions.pnpmActionSetup (✅ verified): {"action":"pnpm/action-setup","installs":["pnpm"],"inputs":[{"name":"version","kind":"version","tool":"pnpm"}]} ↗
  • githubActions.pnpmSetup (✅ verified): {"action":"pnpm/setup","installs":["pnpm"],"inputs":[{"name":"version","kind":"version","tool":"pnpm"},{"name":"runtime","kind":"runtime"},{"name":"node-version-file","kind":"version-file","tool":"node"}]} ↗
  • githubActions.setupBun (✅ verified): {"action":"oven-sh/setup-bun","installs":["bun"],"inputs":[{"name":"bun-version","kind":"version","tool":"bun"},{"name":"bun-version-file","kind":"version-file","tool":"bun"}]} ↗
  • githubActions.setupDeno (✅ verified): {"action":"denoland/setup-deno","installs":["deno"],"inputs":[{"name":"deno-version","kind":"version","tool":"deno"},{"name":"deno-version-file","kind":"version-file","tool":"deno"}]} ↗
  • githubActions.setupPython (✅ verified): {"action":"actions/setup-python","installs":["python"],"inputs":[{"name":"python-version","kind":"version","tool":"python"},{"name":"python-version-file","kind":"version-file","tool":"python"},{"name":"pip-version","kind":"version","tool":"pip"}]} ↗
  • githubActions.setupUv (✅ verified): {"action":"astral-sh/setup-uv","installs":["uv"],"inputs":[{"name":"version","kind":"version","tool":"uv"},{"name":"version-file","kind":"version-file","tool":"uv"}]} ↗
  • githubActions.installPoetry (✅ verified): {"action":"snok/install-poetry","installs":["poetry"],"inputs":[{"name":"version","kind":"version","tool":"poetry"}]} ↗
  • githubActions.actionsPoetry (✅ verified): {"action":"abatilo/actions-poetry","installs":["poetry"],"inputs":[{"name":"poetry-version","kind":"version","tool":"poetry"}]} ↗
  • githubActions.codeScanningUpload (✅ verified): {"action":"github/codeql-action/upload-sarif","inputs":{"sarifFile":"sarif_file","category":"category"},"permissions":{"always":{"security-events":"write"},"privateRepositories":{"actions":"read","contents":"read"}}} ↗
  • githubActions.stopCommands (✅ verified): {"stop":"::stop-commands::{token}","resume":"::{token}::"} ↗
  • githubActions.annotations (✅ verified): {"commands":{"error":"error","warning":"warning","note":"notice"},"properties":{"file":"file","line":"line","title":"title"},"escape":[["%","%25"],["\r","%0D"],["\n","%0A"]],"escapeProperty":[[":","%3A"],[",","%2C"]]} ↗
  • githubActions.annotationLimits (✅ verified): {"perLevelPerStep":10,"perJob":50} ↗
  • githubActions.checkRuns (✅ verified): {"endpoints":{"create":"/repos/{repository}/check-runs","update":"/repos/{repository}/check-runs/{id}","list":"/repos/{repository}/commits/{ref}/check-runs"},"query":{"checkName":"check_name","filter":"filter","latest":"latest"},"apiVersion":"2022-11-28","permission":{"checks":"write"},"summaryMaxLength":65535,"annotationsPerRequest":50,"annotationLevels":{"error":"failure","warning":"warning","note":"notice"},"annotationTitleMaxLength":255,"annotationMessageMaxBytes":64000,"variables":{"apiUrl":"GITHUB_API_URL","repository":"GITHUB_REPOSITORY","sha":"GITHUB_SHA","eventPath":"GITHUB_EVENT_PATH"},"pullRequestHeadSha":["pull_request","head","sha"]} ↗
  • githubActions.stepSummary (✅ verified): {"variable":"GITHUB_STEP_SUMMARY","maxBytes":1048576} ↗
  • npmRegistry.api (✅ verified): {"url":"https://registry.npmjs.org/","packagePath":"/{escaped name}","timeField":"time","distTagsField":"dist-tags","defaultTag":"latest","versionsField":"versions","scriptsField":"scripts","deprecatedField":"deprecated","installScripts":["preinstall","install","postinstall"]} ↗
  • npmRegistry.notFoundStatus (❓ uncertain): 404 ❓ ↗
  • npmRegistry.search (❓ uncertain): {"path":"/-/v1/search","maxSize":250,"weeklyDownloadsField":"downloads.weekly"} ❓ ↗
  • pypiIndex.api (✅ verified): {"url":"https://pypi.org/simple/","accept":"application/vnd.pypi.simple.v1+json","notFoundStatus":404,"filesField":"files","filenameField":"filename","uploadTimeField":"upload-time","yankedField":"yanked","versionsField":"versions","statusField":"project-status","statusValueField":"status","statusReasonField":"reason"} ↗
  • pypiIndex.projectStatus (✅ verified): {"blocked":["quarantined"],"warned":["archived","deprecated"]} ↗
  • claudeCode.hooks (✅ verified): {"settingsFile":".claude/settings.json","event":"PreToolUse","matcherSeparator":"|","input":{"event":"hook_event_name","tool":"tool_name","command":"tool_input.command","cwd":"cwd"},"output":{"container":"hookSpecificOutput","event":"hookEventName","decision":"permissionDecision","reason":"permissionDecisionReason"},"decisions":{"deny":"deny","ask":"ask"},"blockingExitCode":2,"onFailure":{"field":"onFailure","value":"block","since":"2.1.295"},"projectDir":"${CLAUDE_PROJECT_DIR}","settings":{"hooks":"hooks","matcher":"matcher","handlers":"hooks","type":"type","commandType":"command","command":"command","args":"args"}} ↗
  • claudeCode.hookContext (❓ uncertain): {"field":"additionalContext","withoutDecision":true,"inlineLimit":10000} ❓ ↗
  • claudeCode.sessionStart (✅ verified): {"event":"SessionStart","matchers":["startup","resume"],"projectDirVariable":"CLAUDE_PROJECT_DIR","firstResponseWaits":true,"missingScriptWithBlock":"blocks","blockedNotice":"failed; blocking because onFailure is \"block\"","cloudSetupScriptRunsBeforeClaudeCode":true} ↗
  • claudeCode.shellTools (✅ verified): {"tool":"Bash","shell":"bash"}, {"tool":"PowerShell","shell":"powershell"}, {"tool":"Monitor","shell":"bash"} ↗
  • claudeCode.commandlessInputs (✅ verified): {"tool":"Monitor","input":"tool_input.ws"} ↗
  • mcp.revisions (✅ verified): {"legacy":["2025-11-25","2025-06-18","2025-03-26","2024-11-05"],"modern":["2026-07-28"]} ↗
  • mcp.lifecycle (✅ verified): {"initialize":"initialize","initialized":"notifications/initialized","ping":"ping","request":{"protocolVersion":"protocolVersion","capabilities":"capabilities","clientInfo":"clientInfo"},"result":{"protocolVersion":"protocolVersion","capabilities":"capabilities","serverInfo":"serverInfo","instructions":"instructions"}} ↗
  • mcp.stateless (✅ verified): {"metaField":"_meta","protocolVersion":"io.modelcontextprotocol/protocolVersion","clientCapabilities":"io.modelcontextprotocol/clientCapabilities","clientInfo":"io.modelcontextprotocol/clientInfo","serverInfo":"io.modelcontextprotocol/serverInfo","discover":"server/discover","discoverResult":{"supportedVersions":"supportedVersions","capabilities":"capabilities","instructions":"instructions"},"resultType":{"field":"resultType","complete":"complete"},"caching":{"ttl":"ttlMs","scope":"cacheScope","publicScope":"public"},"unsupportedVersionData":{"supported":"supported","requested":"requested"}} ↗
  • mcp.tools (✅ verified): {"list":"tools/list","call":"tools/call","capability":"tools","fieldsSince":{"annotations":"2025-03-26","title":"2025-06-18","structuredContent":"2025-06-18"}} ↗
  • mcp.cancellation (✅ verified): {"method":"notifications/cancelled","requestId":"requestId"} ↗
  • mcp.errorCodes (✅ verified): {"parseError":-32700,"invalidRequest":-32600,"methodNotFound":-32601,"invalidParams":-32602,"internalError":-32603,"unsupportedProtocolVersion":-32022} ↗
  • mcp.errorId (✅ verified): {"optionalSince":"2025-11-25"} ↗
  • mcp.stdio (✅ verified): {"delimiter":"\n","batchRevisions":["2025-03-26"]} ↗
  • mcp.clients.claudeCode (✅ verified): {"addCommand":["claude","mcp","add"],"separator":"--","scopeOption":"--scope","projectScope":"project","transportOption":"--transport","stdioTransport":"stdio","projectFile":".mcp.json","serversKey":"mcpServers","projectDirVariable":"CLAUDE_PROJECT_DIR","projectDirReference":"${CLAUDE_PROJECT_DIR:-.}"} ↗
  • mcp.clients.claudeDesktop (✅ verified): {"configFiles":{"darwin":"~/Library/Application Support/Claude/claude_desktop_config.json","win32":"%APPDATA%\\Claude\\claude_desktop_config.json","linux":"~/.config/Claude/claude_desktop_config.json"},"serversKey":"mcpServers"} ↗
  • mcp.clients.vscode (✅ verified): {"file":".vscode/mcp.json","serversKey":"servers","typeField":"type","stdioType":"stdio","cwdField":"cwd","workspaceFolder":"${workspaceFolder}","addOption":"--add-mcp"} ↗
  • git.ignore (✅ verified): {"file":".gitignore","excludeFile":".git/info/exclude","indexFile":".git/index","trackedFilesIgnored":false} ↗
  • git.ignoreCase (✅ verified): {"configFile":".git/config","section":"core","key":"ignorecase","trueValues":["yes","on","true","1"]} ↗
  • git.repositoryEntry (✅ verified): {"entry":".git","submoduleEntry":"file"} ↗
  • windows.commandShims (✅ verified): {"extensions":[".cmd",".ps1"],"batchExtension":".cmd","argumentsVariable":"%*"} ↗
  • windows.batchArguments (✅ verified): {"extensions":[".bat",".cmd"]} ↗
  • osv.api (✅ verified): {"url":"https://api.osv.dev","queryBatchPath":"/v1/querybatch","vulnerabilityPath":"/v1/vulns/{id}","recordPage":"https://osv.dev/vulnerability/{id}","queriesField":"queries","resultsField":"results","vulnsField":"vulns","idField":"id","nextPageTokenField":"next_page_token","pageTokenField":"page_token","maxQueriesPerBatch":1000} ↗
  • osv.paging (✅ verified): {"perQuery":1000,"perBatch":3000} ↗
  • osv.ids (✅ verified): {"pattern":"^[a-zA-Z0-9:_.-]+$"} ↗
  • osv.service (✅ verified): {"rateLimit":null,"freshnessMinutes":15,"freshnessShare":0.995,"responseLimitBytes":33554432} ↗
  • osv.withdrawn (✅ verified): {"field":"withdrawn","inQueryResponses":false,"inRecordResponses":true} ↗
  • osv.malicious (✅ verified): {"idPrefix":"MAL-","database":"OpenSSF Malicious Packages","license":"Apache-2.0"} ↗
  • osv.ecosystems (✅ verified): {"npm":"npm","pypi":"PyPI","packagist":"Packagist"} ↗
  • osv.versionMatching (✅ verified): {"packagist":{"ignoredPrefixes":["v","V"]}} ↗
  • python.nameNormalization (✅ verified): {"separators":"[-_.]+","replacement":"-"} ↗
  • python.namePattern (✅ verified): ^([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9._-]*[A-Za-z0-9])$ ↗
  • python.projectFile (✅ verified): pyproject.toml ↗
  • python.wheelExtension (✅ verified): .whl ↗
  • python.sourceDistributionExtensions (✅ verified): .tar.gz, .zip, .tar.bz2, .tbz, .tgz, .tar, .tar.xz, .txz, .tlz, .tar.lz, .tar.lzma ↗
  • python.bundledPip (✅ verified): {"line":"3.9","latest":"3.9.25","bundles":[["3.9.0","20.2.3"],["3.9.5","21.1.1"],["3.9.6","21.1.3"],["3.9.7","21.2.3"],["3.9.8","21.2.4"],["3.9.11","22.0.4"],["3.9.17","23.0.1"]]}, {"line":"3.10","latest":"3.10.22","bundles":[["3.10.0","21.2.3"],["3.10.1","21.2.4"],["3.10.3","22.0.4"],["3.10.6","22.2.1"],["3.10.7","22.2.2"],["3.10.9","22.3.1"],["3.10.11","23.0.1"]]}, {"line":"3.11","latest":"3.11.18","bundles":[["3.11.0","22.3.0"],["3.11.1","22.3.1"],["3.11.4","23.1.2"],["3.11.5","23.2.1"],["3.11.8","24.0.0"]]}, {"line":"3.12","latest":"3.12.16","bundles":[["3.12.0","23.2.1"],["3.12.2","24.0.0"],["3.12.5","24.2.0"],["3.12.8","24.3.1"],["3.12.10","25.0.1"]]}, {"line":"3.13","latest":"3.13.18","bundles":[["3.13.0","24.2.0"],["3.13.1","24.3.1"],["3.13.3","25.0.1"],["3.13.4","25.1.1"],["3.13.6","25.2.0"],["3.13.10","25.3.0"],["3.13.13","26.0.1"],["3.13.14","26.1.2"],["3.13.15","26.2.1"],["3.13.17","26.2.2"]]}, {"line":"3.14","latest":"3.14.10","bundles":[["3.14.0","25.2.0"],["3.14.1","25.3.0"],["3.14.4","26.0.1"],["3.14.5","26.1.1"],["3.14.6","26.1.2"],["3.14.7","26.2.1"],["3.14.9","26.2.2"]]}, {"line":"3.15","latest":"3.15.2","bundles":[["3.15.0","26.2.1"],["3.15.1","26.2.2"]]} ↗
  • python.hatch (✅ verified): {"pyprojectTable":"tool.hatch","configFile":"hatch.toml"} ↗
  • python.virtualEnvironment (✅ verified): {"marker":"pyvenv.cfg","scripts":[{"platform":"posix","directory":"bin","names":["activate","activate.fish","activate.csh","Activate.ps1"]},{"platform":"windows","directory":"Scripts","names":["activate.bat","Activate.ps1"]}]} ↗
  • python.interpreter (✅ verified): {"executables":["python","python3","py"],"moduleOption":"-m","commandOption":"-c","valueOptions":["-W","-X","--check-hash-based-pycs"],"groupedShortOptions":true} ↗

Notes

Context recorded with verified facts.

npm

  • cooldown.configFiles: Any npm config layer works: project .npmrc (read only at the project root and not for global installs), ~/.npmrc, the global npmrc, npm_config_min_release_age or the CLI. package.json cannot set it. ↗
  • cooldown.unit: Type is null or Number; 0 turns the delay off. Fractional days are not documented. ↗
  • cooldown.default: Unchanged in npm 12. ↗
  • cooldown.securityUpdates: npm audit fix keeps the vulnerable version, warns that the fix was blocked (since 11.18.0) and exits non-zero. Add the package to min-release-age-exclude or relax the delay. ↗
  • installScripts.defaultPolicy: strict-allow-scripts (default false) turns a dependency script that allowScripts does not cover "from a warning into a hard error ... instead of running with a notice", so from 11.16.0 such scripts still run. npm 11.21.1 ran esbuild's postinstall on 2026-10-29 ("has install scripts not yet covered by allowScripts"); npm 12.2.1 blocked it ("had install scripts blocked"). The v11 install-scripts command page says scripts are blocked by default, which the config definition, the 11.16.0 pull request, the GitHub changelog and the test contradict. npm 12 also blocks implicit node-gyp builds and prepare scripts of git, file and link dependencies. ↗
  • installScripts.allowList.file: Only the root package.json counts; allowScripts in dependencies is ignored. npx, npm exec and global installs use the allow-scripts config instead. ↗
  • installScripts.disableAll: Default false. Overrides allowScripts and dangerously-allow-all-scripts. npm run/test/start still run the named script, but not its pre/post scripts. ↗
  • sources.git.values: root allows only git dependencies listed in the project package.json. ↗
  • sources.remoteTarball.values: Tarballs on the configured registry hostname are always allowed. The 2026-05-22 GitHub changelog mentions only all and none; the config reference also lists root. ↗
  • sources.file.values: The 2026-05-22 GitHub changelog mentions only all and none; the config reference also lists root. ↗
  • sources.file.default: npm 12 did not change the default. ↗
  • sources.directory.values: The 2026-05-22 GitHub changelog mentions only all and none; the config reference also lists root. ↗
  • sources.directory.default: npm 12 did not change the default. ↗
  • project.lockfiles: npm 11 and earlier prefer npm-shrinkwrap.json over package-lock.json when both exist; npm 12 no longer reads or writes npm-shrinkwrap.json (same format, rename it). ↗
  • project.workspaces: An array of folder paths or globs. ↗
  • user.files: userconfig defaults to ~/.npmrc ("The location of user-level configuration settings. This may be overridden by the npm_config_userconfig environment variable or the --userconfig command line option"); ~ is resolved against `this.env.HOME || homedir()`. Same in 11.21.1. The project .npmrc is loaded first and may set userconfig= itself. Only the keys above the first [section] header are settings (extra.npmrcFormat). ↗
  • user.settings: Every config definition is read from any config file; only prefix is refused in a project .npmrc. allowScripts in package.json is project-only: at user level the allow-list is the allow-scripts key (allow only, every name becomes true; resolve-allow-scripts.js), used where the root package.json has no allowScripts and for npx, npm exec and npm install -g. The source keys use the later of the disputed first versions. ↗
  • user.unknownKeys: Unknown .npmrc (file) configs warn by default, matching pre-npm-12 behavior, but error when strict-npmrc is set. ↗
  • user.invalidValueFails: A value of the wrong type is reported as invalid config and the default is used. ↗
  • user.weakening: A key in the project .npmrc replaces the user value, lists included (prototype chain, no merging); the CLI and npm_config_* variables beat both. dangerously-allow-all-scripts is on for every value but false, null and undefined: npm reads .npmrc values and npm_config_* variables with parseField (https://github.com/npm/cli/blob/v11.21.1/workspaces/config/lib/parse-field.js), which trims them, turns an empty value of a Boolean setting into true and only "true", "false", "null" and "undefined" into their values, and leaves 0, 1, yes or no as strings; load() does not run the nopt type check (validate() runs only in npm config), and arborist tests the flat option for truth (!this.options.dangerouslyAllowAllScripts in workspaces/arborist/lib/arborist/rebuild.js at 11.21.1). ↗
  • user.variables: Environment variables starting with npm_config_ are interpreted as configuration parameters; config values are case-insensitive, so NPM_CONFIG_FOO=bar works the same. loadEnv in workspaces/config/lib/index.js (11.21.1 and 12.2.1) skips variables whose value is empty and reads them in the order of the environment, so of two spellings the later one wins. userconfig defaults to ~/.npmrc (definitions.js), and npm exports the resolved path as npm_config_userconfig to every command it runs (see extra.childEnvironment), so that value names the default file. ↗
  • extra.environmentNames: loadEnv takes every variable whose name matches /^npm_config_/i, cuts the prefix and lowercases the rest (with _ as - but for a leading _), so NPM_CONFIG_REGISTRY and Npm_Config_Registry set registry as npm_config_registry does (decision D-143). ↗
  • extra.localPrefix: loadLocalPrefix: --prefix on the command line is the local prefix. Otherwise npm walks up from the current directory (walk-up-path yields the directory and each parent up to the root, with no other stop; "for (const p of walkUp(this.cwd))") and takes the first directory with a package.json file or a node_modules directory ("hasPackageJson || await dirExists(p, 'node_modules')"). Unless workspaces are set to false on the command line ("this.#get('workspaces', 'cli')", so --no-workspaces or --workspaces=false; .npmrc and npm_config_workspaces do not count) or npm runs in global mode, it walks on: each higher directory with a package.json is read with @npmcli/package-json normalize, and one that cannot be read or normalized (".catch(() => ({ content: {} }))") or has no workspaces is passed over; the first whose mapped workspaces include that directory ("w === this.localPrefix", the same path) becomes the prefix, and a .npmrc of the workspace is skipped ("ignoring workspace config at ${this.localPrefix}/.npmrc"). Without a match the prefix is the current directory ("this.localPrefix = this.cwd"). loadProjectConfig reads "resolve(this.localPrefix, '.npmrc')" as the project configuration, except in global mode and when that path is the userconfig file. Workspaces (@npmcli/map-workspaces 6.0.0, the version npm 12.2.1 locks, with glob 13.0.6 and minimatch 10.2.5, https://github.com/npm/map-workspaces/blob/v6.0.0/lib/index.js): an array of patterns or an object with a packages array, else EWORKSPACESCONFIG, and an entry that is not text throws too; the leading ! are removed and an odd number of them negates, then a leading ./ or leading slashes ("pattern.replace(/^\.?\/+/, '')"); a pattern drops the earlier negated patterns it matches as text, and each negated pattern drops the patterns it matches as text and is given to glob as ignore, with **/node_modules/**; glob gets every pattern with a trailing / (directories only) and its defaults: * and ** do not match a name that starts with a dot, ** does not follow symlinked directories, and matching ignores case on macOS and Windows; a match without package.json (ENOENT, ENOTDIR) is no workspace, another error and two workspaces of one name throw, and npm stops. normalize (https://github.com/npm/package-json/blob/v8.0.0/lib/normalize.js, steps bin and binDir) throws for a bin list with an entry that is not text and for directories.bin that is not text when bin is not set. No .git or home directory stops the walk. ↗
  • extra.childEnvironment: setEnvs gives the scripts and commands npm runs (npm run, npx, npm exec) every setting that is not its default as npm_config_<key> in lower case with - as _, whichever file or flag set it, unless the definition has envExport: false (allow-scripts, min-release-age and min-release-age-exclude in 11.21.1 and 12.2.1); keys npm does not know, such as pnpm keys in .npmrc, are exported too. userconfig is always exported, because its default is the literal ~/.npmrc and the value the resolved path. It also sets npm_execpath to the npm it runs. The same in 10.9.4 and 12.2.1 (12.x and 11.x also export npm_config_node_gyp and npm_config_npm_version). ↗
  • extra.denyList: A false entry in the root package.json allowScripts is an explicit denial: deny wins over allow, and denied packages are skipped silently, also under strict-allow-scripts ("const verdict = isScriptAllowed(node, policy); if (verdict === true || verdict === false) { continue }", the same in 11.16.0 check-allow-scripts.js). npm install-scripts deny writes a name-only false entry. ↗
  • extra.trustedPublishing: Publishing from GitHub-hosted runners with OIDC instead of a token. Provenance is generated automatically, only for a public package from a public repository. A new trusted publisher configuration expires unless its first publish succeeds within 2 days. It can be limited to npm stage publish (the default for configurations created after 2026-09-03). ↗
  • extra.stagedPublishing: Staging needs no 2FA, so CI can do it; approving or rejecting needs 2FA (CLI or npmjs.com). Staging a package that does not exist yet creates it with the public placeholder version 0.0.0-stage. Pre-release versions need an explicit --tag. --provenance also applies to npm stage publish. Rejecting the only staged version of such a new package also unpublished the placeholder (observed 2026-10-29 with npm 11.21.1), and after a whole package is unpublished its name is blocked for 24 hours (https://github.com/npm/documentation/blob/main/content/policies/unpublish.mdx). ↗
  • extra.trustCommand: Configures a trusted publisher from the CLI; needs 2FA on the account and write access, and the package must already exist. At least one permission flag is required. ↗
  • extra.tarballIdentity: What npm installs for an entry of package-lock.json is the tarball of resolved (after replace-registry-host), whatever its version field says: #extractOrLink in workspaces/arborist/lib/arborist/reify.js extracts <name>@<resolved> when resolved is set, and <name>@<version> only without it (12.2.1; the same code in 10.9.9). The allowScripts matcher of npm 12.2.1 takes the name and version of a registry package from resolved with this function (getTrustedRegistryIdentity in workspaces/arborist/lib/script-allowed.js: "Never use node.packageName / node.version here: those read from the tarball's own package.json and can be forged"): the path part after the last /-/ must be the file name of the URL, the part before it ends with the name, with the scope before it when that starts with @ (separated by / or %2f), and the file name is <name>-<version>.tgz with a version that semver.parse reads (semver 7.8.5 in npm 12.2.1: three numbers without leading zeros, an optional pre-release and build, an optional leading v, at most 256 characters; the version drops the v and the build). A path in another layout gives no name and version. versionFromTgz reads the whole URL, so a query or a fragment after the file name (.tgz?x=1, .tgz#x) gives none either, while npm still fetches the tarball: pacote 22.0.0 (the version npm 12.2.1 locks) fetches resolved as it is, or, when replace-registry-host replaces its host, new URL(path, registry) without query or fragment (lib/remote.js), and minipass-fetch 6.0.0 requests pathname and search, never the fragment (lib/request.js). The registry serves the file the path names, with its percent-escapes decoded as an HTTP server reads a path (decision D-136). ↗
  • extra.lockfileFormat: Entries under packages: resolved is the registry tarball URL, the git URL with its commit (git+ssh://… or git+https://…#sha), file:<path> for local tarballs and directories, or the link target when link is true. hasInstallScript marks a preinstall, install or postinstall script (prepare scripts of non-registry sources are not flagged). npm tells registry tarballs from other URLs with the registryTarball pattern (workspaces/arborist/lib/install-scripts.js), so a tarball URL on a registry host looks like a registry package. An entry without resolved is installed as <name>@<version> (workspaces/arborist/lib/arborist/reify.js, #extractOrLink, in 11.19.1 and 12.2.1), so its version field is the source then. Entries keep the dependency fields of their package.json: dependencies, optionalDependencies and peerDependencies for every package, devDependencies for the root (workspaces/arborist/lib/shrinkwrap.js, pkgMetaKeys and the isTop branch, in 11.21.1 and 12.2.1); a dependency declared there as a URL comes from that URL even when it is a registry tarball. ↗
  • extra.overrides: Only the root package.json counts. Keys are package names, optionally with a version or range (name@range), and nest to any depth to scope an override under a parent; "." inside a nested object overrides the parent package itself; values take any dependency specifier, including tarball URLs, and $name refers to the spec of a direct dependency. Overrides are not written to package-lock.json (checked with npm 11.21.1), so a URL override of a registry tarball looks like a registry package there. With replace-registry-host at its default npmjs, npm writes the configured registry in place of registry.npmjs.org in resolved URLs (workspaces/config/lib/definitions/definitions.js). ↗
  • extra.npmrcScope: Only the .npmrc at the root of the project npm runs in is read. Inside a workspace package npm moves the prefix to the workspace root (using-npm/workspaces.md) and warns "ignoring workspace config" for the package .npmrc (workspaces/config/lib/index.js). The project .npmrc "is not read in global mode, such as when running npm install -g" (same page, v11.21.1 and v12.2.1). ↗
  • extra.npmrcFormat: npm reads .npmrc with the ini package: 7.0.0 in npm 12.2.1, and 6.0.0, whose lib/ini.js is the same, in npm 11.10.0 to 11.21.1 (package-lock.json of npm/cli). A line whose first non-blank character is # or ; is a comment. An unquoted key or value ends at the first # or ; that is not escaped with a backslash, so ignore-scripts=true # note sets true; a value in double quotes is parsed as a JSON string and one in single quotes loses its quotes, both keeping # and ;. A line without = sets the key to true. A [name] header at the start of a line, with nothing but spaces after it, starts a section: the keys below it belong to that section until the next header. npm applies only the top-level keys as settings (#loadObject in workspaces/config/lib/index.js at v12.2.1), so a key below a header has no effect. ↗
  • extra.npmrcListSyntax: Array values are written by adding [] after the key, one line per value, e.g. min-release-age-exclude[]=@myorg/*. ↗
  • extra.allowAllScripts: Boolean, default false: runs every dependency install script whether or not allowScripts approves it; --ignore-scripts still wins. First present in the 11.16.0 definitions. ↗
  • extra.excludeWildcards: min-release-age-exclude takes package names or minimatch globs from its first version. ↗
  • extra.latestVersion: Marked as the latest GitHub release on 2026-10-28; the 11.x line is still maintained (11.21.1). ↗
  • extra.beforeInteraction: before is a date: npm installs only versions available on or before it. In 11.10.0 to 11.14.x the definitions of min-release-age and before name each other as exclusive, and npm stops with "--min-release-age cannot be provided when using --before" (or the reverse) once both are set in its config sources (#loadObject in workspaces/config/lib/index.js and definitions.js at v11.14.1). Since 11.15.0 both may be set: "If before and min-release-age are both set in the same source, before wins"; across sources the usual precedence applies (cli > env > project > user > global), so a before in the project .npmrc replaces its own min-release-age (definitions.js at v11.15.0 and v12.2.1; release notes of 11.15.0). ↗
  • extra.strictAllowScripts: strict-allow-scripts=true makes the install fail on a dependency with install scripts that allowScripts does not cover, instead of running them with a notice (default false). Entries denied with false are skipped silently; --ignore-scripts and --dangerously-allow-all-scripts override it. ↗
  • extra.strictAllowScriptsEffect: npm 12.2.1 still defines strict-allow-scripts (default false): "If true, turn the install-script policy from a warning into a hard error: any dependency with install scripts that is not covered by allowScripts will fail the install instead of being blocked with a warning." Dependencies denied with false are still skipped silently; --ignore-scripts and --dangerously-allow-all-scripts override it. So the same .npmrc line keeps npm 11.16 to 11.x from running such scripts and makes npm 12 stop the install at them. The 11.16.0 effect is the one in strictAllowScripts (definitions.js at v11.16.0). ↗
  • extra.unknownNpmrcKeys: Matters for generated .npmrc files: keys npm does not know (e.g. pnpm-only keys) print a warning on every npm command. The 12.0.0 entry: unknown CLI flags "now throw instead of warning. (Unknown .npmrc configs still warn by default; opt into erroring with the new strict-npmrc config.)"; lib/base-cmd.js at 12.2.1 does the same. ↗
  • extra.commandLine: Aliases of install (add, i and the typo aliases in, ins, inst, insta, instal, isnt, isnta, isntal, isntall), install-test (it), exec (x) and init (create, innit), the same in 11.19.1. install-test takes the same arguments as install (docs/lib/content/commands/npm-install-test.md). npm exec and npx take the packages to download from --package; -p means --package only in npx (in npm it is --parseable); without --package the first positional argument names the package, and -c/--call takes a command string that runs with the packages, shell operators included (npm-exec.md). npm init <initializer> runs npm exec create-<initializer>: foo → create-foo, @usr → @usr/create, @usr/foo@2.0.0 → @usr/create-foo@2.0.0 (npm-init.md). ↗
  • extra.valueOptions: npm options that always take a value: every definition whose type does not include Boolean, as --name, and the short forms -C (prefix), -L (location), -c (call), -m (message) and -w (workspace). Options whose type includes Boolean (such as color and browser) may stand alone, so they are taken for flags. ↗
  • extra.flagOptions: npm options whose type includes Boolean, which may stand alone: the definitions of 12.2.1 and of 11.21.1 (where shrinkwrap is one too; 12.2.1 adds ignore-existing, ignore-extension, ignore-patch-failures, allow-unused-patches, keep-edit-dir and strict-npmrc). With valueOptions they are every npm option, so an abbreviated option can be resolved as npm resolves it. ↗
  • extra.parsing: The shorthands npm passes to nopt: the list in definitions/index.js and the short names of the definitions (the same in 11.21.1). nopt (node_modules/nopt/lib/nopt-lib.js, versions 8.1.0 in npm 10.9.4, 9.0.0 in 11.21.1 and 10.0.1 in 12.2.1, same parse and resolveShort) strips every leading dash, so -reg, --reg and -registry work; takes an exact option first, then an exact shorthand, then a word of one-letter shorthands (-gD), then an unambiguous prefix of an option name (abbrev), then a prefix of a shorthand; and reads --no-<name> as a negated flag that takes no value. After the shorthands (resolveShort) nopt strips every leading no- in any case, each one inverting the flag, and then takes <name> as an exact option or an unambiguous prefix (abbrevs), so --no-ign is --no-ignore-scripts where no other option starts with ign (npm 11; npm 12 has ignore-existing too) and --no-no-ignore-scripts sets ignore-scripts to true; a negated flag takes a following true or false, inverted (definitions/index.js and definitions.js at v12.2.1 and lib/nopt-lib.js of nopt 10.0.1, read again 2026-11-01). npm 10 expands abbreviations silently, npm 11 warns "Expanding --regis to --registry. This will stop working in the next major version of npm." and npm 12 refuses them with EUNKNOWNCONFIG (abbrevHandler in workspaces/config/lib/index.js of 11.21.1 and 12.2.1). Shorthands are expanded only on the command line, not in .npmrc or npm_config_ variables. npx turns -p into --package and expands exact shorthands itself before npm exec reads the rest (bin/npx-cli.js). ↗
  • extra.versionSelection: tag (default latest): "If you ask npm to install a package and don't tell it a specific version, then it will install the specified tag"; like any setting it comes from --tag, npm_config_tag or .npmrc. A name without a version is name@* (npm-package-arg 14.0.0, lib/npa.js). npm-pick-manifest 12.0.0 (node_modules/npm-pick-manifest/lib/index.js) picks the version of that dist-tag when the range is * or the version satisfies the range, unless it is deprecated; otherwise the highest satisfying version, preferring versions that are not deprecated; prereleases match a range only when it names one, so name@* with latest on a prerelease installs that prerelease. npm exec and npm init pick with the same settings. ↗
  • extra.packageSpecs: Forms of npm install <spec>: a folder; a tarball file, whose name must end in .tar, .tar.gz or .tgz; a tarball URL, which must start with http:// or https://; a git remote URL with the protocol git, git+ssh, git+http, git+https or git+file; <githubname>/<githubrepo> or github:<githubname>/<githubrepo>; gist:, bitbucket: and gitlab: shorthands; <alias>@npm:<name>. The file: prefix for local paths is documented in docs/lib/content/configuring-npm/package-json.md (Local Paths). ↗
  • extra.registryConfig: userconfig, the location of user-level settings, defaults to ~/.npmrc; registry is the base URL of the npm registry (default https://registry.npmjs.org/); a per-project .npmrc can set it like any config key (docs/lib/content/using-npm/config.md). npm config set @myco:registry=http://reg.example.com associates a scope with a registry, and any npm install of a package with that scope then requests it from there (https://docs.npmjs.com/cli/v12/using-npm/scope#associating-a-scope-with-a-registry). ↗
  • extra.registryOverrides: registry is a URL; userconfig and globalconfig are the user and global configuration files. Putting --foo bar on the command line sets the foo configuration parameter, and environment variables that start with npm_config_ are configuration parameters too, without regard to case (docs/lib/content/using-npm/config.md); @scope:registry is the key of a scope's registry (https://docs.npmjs.com/cli/v12/using-npm/scope). ↗
  • extra.configCommands: npm config set sets keys (in the user configuration unless location is given), delete (also rm and del) removes keys from every configuration file, edit opens a configuration file in an editor and fix repairs invalid items; get and list (ls) only read (the switch in exec, and docs/lib/content/commands/npm-config.md). npm set <key>=<value> runs npm config set with its arguments and fails without any (lib/commands/set.js); npm get only reads (lib/commands/get.js). npm pkg set, delete and fix write package.json back, get only reads (lib/commands/pkg.js). Other spellings of these commands come from commandNames. ↗
  • extra.commandNames: deref resolves a command name: camelCase to kebab-case (installTest is install-test), an exact command, a direct alias, else a unique abbreviation of the commands and alias names (abbrev), whose aliases are followed to the command (npm install-cl is install-clean, then ci). So npm c, npm con, npm conf and npm confi are npm config, and npm pk is npm pkg. ↗
  • extra.installOverrides: Settings that a single npm command can change on its command line or in its environment: "Putting --foo bar on the command line sets the foo configuration parameter", "--flag without specifying any value will set the value to true", "Any environment variables that start with npm_config_ will be interpreted as a configuration parameter", case-insensitive, and an environment configuration without a value is true (docs/lib/content/using-npm/config.md at v12.2.1). Types in definitions.js at v12.2.1: ignore-scripts Boolean, default false ("If true, npm does not run scripts specified in package.json files"); min-release-age null or Number of days; before null or Date; min-release-age-exclude a list exempt from min-release-age and before; dangerously-allow-all-scripts Boolean, which bypasses the allowScripts policy; allow-scripts a list of packages whose install scripts may run. A value other than true for ignore-scripts, any true value of dangerously-allow-all-scripts (the false values as in user.variables), any allow-scripts, before or min-release-age-exclude, and a min-release-age shorter than the policy weaken what depcurfew apply wrote. ↗
  • extra.directoryOptions: prefix (short C, so -C dir is --prefix dir): "The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder." loadLocalPrefix in workspaces/config/lib/index.js (v12.2.1) reads it only from the command line ("this.#get('prefix', 'cli')"), takes it as the local prefix as given and does not walk up, so npm_config_prefix and .npmrc do not move a command; the project .npmrc is the one in that folder. ↗
  • extra.booleanWords: nopt, which parses the npm command line, also supports "--bool true or --bool false": a Boolean option followed by the word true or false takes it as its value and skips it, and a --no- prefix inverts the value (parse in lib/nopt-lib.js at v10.0.1, used by npm 12.2.1, and the same code at v9.0.0, used by npm 11.21.1). ↗
  • extra.installCommands: Commands that install packages into the project and their aliases: install (add, i, typo aliases, install-test and it), ci (clean-install, ic, install-clean, isntall-clean) with install-ci-test (cit, clean-install-test, sit), and update (up, upgrade, udpate; u only from npm 12, so left out). The same in v10.9.9 (lib/utils/cmd-list.js). npm also accepts unique abbreviations of command names, which are not listed. ↗
  • extra.globalOption: global (short g) "Operates in global mode, so that packages are installed into the prefix folder instead of the current working directory" and sets location to global; npm install -g npm@<version> replaces the npm that runs (docs/lib/content/commands/npm-install.md: "In global mode (ie, with -g or --global appended to the command)"). ↗
  • extra.unknownConfigKeys: npm 10 loads every key of an .npmrc without checking whether it knows it (#loadObject only checks deprecated and exclusive keys), so a setting it does not have yet, such as min-release-age, is ignored without any message. checkUnknown first appears in v11.2.0 (workspaces/config/lib/index.js), which warns: Unknown project config "<key>". This will stop working in the next major version of npm. The 11.2.0 changelog does not name the change; the version comes from reading the code at the tags. npm 12 collects unknown keys to fail the command (v12.2.1), with the exact behavior not read. ↗
  • extra.cleanInstall: npm ci (the clean commands of installCommands): "The project must have an existing package-lock.json"; "If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock"; "It will never write to package.json or package-lock.json: installs are essentially frozen." lib/commands/ci.js at v12.2.1 loads the lockfile (loadVirtual), builds the ideal tree, throws "`npm ci` can only install packages when your package.json and package-lock.json are in sync" when validateLockfile finds a difference, and reifies with packageLock: true and save: false. So npm ci installs exactly the versions package-lock.json records, and a release-age delay cannot change which versions it installs; the settings of its params (ignore-scripts, allow-scripts, strict-allow-scripts, allow-git, allow-remote, allow-file, allow-directory) still apply. ↗
  • extra.scriptsOff: ignore-scripts (Boolean, default false; definitions.js at v12.2.1: "If true, npm does not run scripts specified in package.json files") is one of the params of npm ci and npm install (lib/commands/ci.js). On the command line --ignore-scripts sets it; "Any environment variables that start with npm_config_ will be interpreted as a configuration parameter", with underscores for dashes, and "Config values are case-insensitive, so NPM_CONFIG_FOO=bar will work the same". depcurfew counts only the value true (and the flag without a value) as off: parseField turns only "true" into true, and loadEnv skips empty values (user.variables). ↗
  • extra.nodeEngines: engines.node of npm/cli package.json, the same at the tags v11.0.0, v11.10.0, v11.16.0, v11.19.1 and v11.21.1 (^20.17.0 || >=22.9.0) and at v12.0.0 and v12.2.1 (^22.22.2 || ^24.15.0 || >=26.0.0, https://github.com/npm/cli/blob/v12.2.1/package.json). On a Node.js outside the range npm only warns that it does not support it: lib/cli/entry.js at v11.19.1 runs log.warn('cli', validateEngines.unsupportedMessage) when !satisfies(node, engines), for a Node.js "still unsupported and untested and might not work reliably", and lib/cli/validate-engines.js prints "ERROR: npm ... is known not to run on Node.js ..." when it fails with a SyntaxError. So npm install -g npm@11 on Node.js 18 installs an npm that is not meant to run there. ↗
  • extra.rootLifecycleScripts: A bare npm install in a project runs the lifecycle scripts of the project itself with runScript, outside arborist and its allowScripts gate: "const runRootLifecycle = !args.length && !isGlobalInstall && !ignoreScripts", preinstall before reify and install, postinstall, prepublish, preprepare, prepare and postprepare after it. npm ci does the same "if (!ignoreScripts)" (lib/commands/ci.js), and so do install.js and ci.js at v11.16.0. collectUnreviewedScripts in workspaces/arborist/lib/unreviewed-scripts.js skips "node.isProjectRoot || node.isWorkspace", so strict-allow-scripts never stops at them. using-npm/scripts.md: prepare "Runs on local npm install without package arguments (runs with flags like --production or --omit=dev, but does not run when installing specific packages like npm install express)". ↗
  • extra.omitOptional: omit: [Array, "dev", "optional", "peer"], "Dependency types to omit from the installation tree on disk"; include: "Dependency types specified in --include will not be omitted, regardless of the order in which omit/include are specified on the command-line"; optional: deprecated, "Alias for --include=optional or --omit=optional" (buildOmitList: obj.optional === false pushes optional to omit, true to include; omit then drops what include lists). --no-optional sets optional to false. Each is one key: the value of the highest layer that sets it wins (command line, then npm_config_* variables in any case, then the project .npmrc). parseField in workspaces/config/lib/parse-field.js splits a list from the environment at two line breaks ("list types get put in the environment separated by double-\n"), so NPM_CONFIG_OMIT=optional omits them and dev,optional is one unknown value. ↗

pnpm

  • cooldown.configFiles: pnpm-workspace.yaml works in every version that has the setting. The global config.yaml exists only from 11.0.0 ("the new global config.yaml"); pnpm 10 reads user-level settings from ~/.npmrc and <configDir>/rc instead (see user.files). pnpm 10 also reads minimum-release-age from .npmrc; pnpm 11+ reads only auth and registry settings from .npmrc and ignores the package.json "pnpm" field. ↗
  • cooldown.unit: Integer number of minutes, e.g. 1440 = 1 day; no duration strings. ↗
  • cooldown.default: The built-in 1440 is non-strict: pnpm adds immature versions to minimumReleaseAgeExclude instead of failing (see strictMode). ↗
  • cooldown.securityUpdates: No setting bypasses the delay. Since 11.0.0, pnpm audit --fix adds the minimum patched version of each advisory to minimumReleaseAgeExclude (since 11.22.0 only while it is still inside the window). ↗
  • installScripts.defaultPolicy: Unreviewed builds only warn in pnpm 10; strictDepBuilds is true by default since 11.0.0, so they fail the install. Prepare scripts of git-hosted dependencies are blocked since 10.26.0. ↗
  • installScripts.allowList.setting: Replaced onlyBuiltDependencies, which was removed in 11.0.0 (see legacyAllowList). Since 12.11.0, permissions.<package>.build takes precedence over allowBuilds (extra.buildPermissions). ↗
  • installScripts.disableAll: Default false; --ignore-scripts on the CLI. Also skips the project's own scripts. ↗
  • sources.git.setting: Blocks git repositories and tarball URLs for transitive dependencies only; no setting blocks them as direct dependencies. ↗
  • sources.remoteTarball.setting: Blocks git repositories and tarball URLs for transitive dependencies only; no setting blocks them as direct dependencies. ↗
  • project.workspaces: Globs with ! exclusions. Without packages only the root is in the workspace; pnpm still reads settings from the file in single-package projects. pnpm ignores workspaces in package.json. ↗
  • user.files: getConfigDir: $XDG_CONFIG_HOME/pnpm when it is set, else ~/Library/Preferences/pnpm on macOS, %LOCALAPPDATA%/pnpm/config on Windows (~/.config/pnpm without LOCALAPPDATA) and ~/.config/pnpm elsewhere; the same in 10.34.9 (config/config/src/dirs.ts) and 12.17.0 (pnpm/crates/config-dir/src/lib.rs). pnpm 10 reads <configDir>/rc, INI with kebab-case keys (config/config/src/index.ts at 10.34.9; first version not tracked), and also ~/.npmrc for every setting, which beats rc: loadNpmConf reads the command line, npm_config_* variables, the project and workspace .npmrc, ~/.npmrc (userconfig, path.resolve(os.homedir(), ".npmrc") in https://github.com/pnpm/npm-conf/blob/v3.0.3/lib/defaults.js) and the global npmrc, and only then is rc added as "pnpm-global", below all of them (index.ts at 10.34.9). From 11.0.0 the settings file is <configDir>/config.yaml with camelCase keys (11.0.0 changelog: "the new global config.yaml"), and ~/.npmrc and <configDir>/auth.ini carry only auth, registry and network settings. The 11.x and 12.x docs page cli/config.md still names a global rc file for registry and auth settings, which that code no longer reads. ↗
  • user.settings: pnpm 10 reads the kebab-case keys from rc as from any .npmrc (config/config/src/types.ts: only-built-dependencies at 10.0.0, strict-dep-builds at 10.3.0, minimum-release-age and minimum-release-age-exclude at 10.16.0, block-exotic-subdeps at 10.26.0); since 10.13.0 build settings from these files apply only to projects whose package.json "pnpm" field and pnpm-workspace.yaml set none of dangerouslyAllowAllBuilds, onlyBuiltDependencies(File), neverBuiltDependencies or allowBuilds, and always to global installs. pnpm 11+ applies a config.yaml key only when isConfigFileKey accepts it and it is camelCase: the minimumReleaseAge keys and blockExoticSubdeps since 11.0.0, strictDepBuilds since 11.0.7 (in excludedPnpmKeys in 11.0.0-11.0.6). allowBuilds is project-only from 11.0.0 and dropped with a warning, so pnpm 11+ has no user-level allow-list. pnpm 12 silently drops blockExoticSubdeps from config.yaml although its key gate accepts it (clear_workspace_resolution_fields in pnpm/crates/config/src/workspace_yaml/workspace_scope.rs, 12.0.0 to 12.17.0). pnpm self-update takes the minimumReleaseAge settings only from config.yaml, the environment and the command line, never from the project. ↗
  • user.weakening: A key in pnpm-workspace.yaml replaces the user value, lists included (applyWorkspaceSetting: pnpmConfig[key] = value); PNPM_CONFIG_* variables and the command line beat both. In pnpm 10 the same keys in ~/.npmrc beat rc, and since 10.13.0 build settings from either file reach only projects without build settings of their own, and global installs (config/config/src/index.ts at 10.34.9; before 10.13.0 dangerously-allow-all-builds also joined a project's onlyBuiltDependencies). In config.yaml, dangerouslyAllowAllBuilds also overrides a project's allowBuilds: false in pnpm 11 and 12.0.0-12.11.x (see extra.allowAllBuilds). pnpm 10 has no default delay and its strict-dep-builds and block-exotic-subdeps default to false, so 0 or false there weakens nothing; trustLockfile is a global key since it appeared in 11.3.0. The switch that allows every build is on for any value pnpm does not read as off, because pnpm tests it for truth (see extra.allowAllBuilds): in config.yaml only false, 0, null and an empty string are off, so "false", yes and "true" (strings for js-yaml) are on; in rc and ~/.npmrc pnpm 10 parses values with parseField of @pnpm/npm-conf (lib/util.js at https://github.com/pnpm/npm-conf/blob/v3.0.2/lib/util.js, the same in 3.0.3, which pnpm 10.28.0 and 10.34.9 use), which turns only "false", "null" and "undefined" into falsy values, an empty value of a Boolean setting into true, and leaves yes, 1 and 0 as strings, which are true. ↗
  • user.variables: pnpm 11 reads pnpm_config_<key> in lower case or PNPM_CONFIG_<KEY> in upper case, not mixed case (getEnvKeySuffix), over pnpm-workspace.yaml and under the command line; pnpm 12 reads the same two forms (pnpm/crates/config/src/env_overlay.rs at 12.17.0). pnpm 11+ ignores npm_config_* except npm_config_userconfig, which then moves only the auth .npmrc. The 11.0.0 release notes (https://github.com/pnpm/pnpm/releases/tag/v11.0.0): "pnpm no longer reads npm_config_* environment variables", "Added support for loading environment variables whose names start with pnpm_config_ into config"; pnpm 10.34.9 reads pnpm_config_ only for verify-deps-before-run (config/config/src/index.ts). pnpm 10 reads npm_config_* in any case, skipping empty values (addEnv in lib/conf.js of @pnpm/npm-conf 3.0.3), under pnpm-workspace.yaml (npmrcPrecedence), and parses them with the same parseField as .npmrc, so npm_config_dangerously_allow_all_builds is off only for false, null and undefined (1 and yes stay true strings); its npm_config_userconfig defaults to ~/.npmrc (lib/defaults.js). pnpm 11 parses a Boolean pnpm_config_ value with parseBoolean of env.ts, which takes only true as true (false gives false, any other text no value). XDG_CONFIG_HOME and LOCALAPPDATA move the config directory (user.files). ↗
  • extra.environmentNames: pnpm 11 reads pnpm_config_<key> only with the prefix and the key in lower case, or PNPM_CONFIG_<KEY> with both in upper case (getEnvKeySuffix with isLowerSnakeCase and isUpperSnakeCase), so Pnpm_Config_Registry sets nothing; pnpm 12 looks up PNPM_CONFIG_<KEY> and then pnpm_config_<key> (read_env in pnpm/crates/config/src/env_overlay/string_reader.rs, https://github.com/pnpm/pnpm/blob/v12.17.0/pnpm/crates/config/src/env_overlay/string_reader.rs). pnpm 10 reads npm_config_* in any case: addEnv in lib/conf.js of @pnpm/npm-conf 3.0.3 filters with /^npm_config_/i, and envKeyToSetting lowercases the key (https://github.com/pnpm/npm-conf/blob/v3.0.3/lib/envKeyToSetting.js). Decision D-143. ↗
  • extra.denyList: allowBuilds: { pkg: false } records a denial: the build is decided, not reported as unreviewed and does not fail strictDepBuilds ("A recorded build the policy denies was decided on purpose"). pnpm 10.26 maps false to ignoredBuiltDependencies, which only silences the report. Under dangerouslyAllowAllBuilds a denied package still builds before pnpm 12.12.0. ↗
  • extra.projectInstall: Commands that install the dependencies of the project: "pnpm install is used to install all dependencies for a project", "Aliases: i". pnpm add (commandLine.add) adds packages. pnpm without a command does not install. ↗
  • extra.commandLine: From cli/add.md, cli/pnx.md, cli/create.md and pnpm-cli.md at that commit. pnx (pnpm 12) has the aliases pnpm dlx and pnpx; pnpm 10 documents pnpm dlx with the alias pnpx (versioned_docs/version-10.x/cli/dlx.md). --shell-mode (-c) runs the command inside a shell, e.g. pnx --package cowsay -c 'echo hi | cowsay'. pnpm create maps foo and create-foo to create-foo, @scope to @scope/create and @scope/foo to @scope/create-foo, and runs it with pnx. --registry and --allow-build are shown with =, the other value options with a separate value. --package belongs to pnx only and is listed there. -F is the short form of --filter (filtering.md). --reporter takes the name of a reporter (cli/install.md) and --loglevel a level (the loglevel setting in settings/cli.md, given as a flag); both take a separate value too. ↗
  • extra.packageSpecs: Sources of pnpm add: the npm registry, jsr:, crate: and pypi: (other registries), workspace packages (the workspace: range protocol, docs/workspaces.md), local directories (./dir is saved as link:, file:./dir is copied), local tarballs ending in .tar, .tar.gz or .tgz, remote tarballs starting with http:// or https://, and git repositories as user/repo (github: by default), github:, bitbucket:, gitlab:, gist: or a full URL such as git+ssh://… or https://github.com/….git. ↗
  • extra.registryOverrides: registry and @scope:registry are read from the command line over .npmrc (docs/npmrc.md in pnpm/pnpm.io). Every pnpm_config_<key> or PNPM_CONFIG_<KEY> variable whose key is a setting sets it (src/env.ts, parseEnvVars), registry included. The user-level .npmrc, which may set any registry, is the file named by --npmrc-auth-file, --userconfig, pnpm_config_npmrc_auth_file, pnpm_config_userconfig, npmrcAuthFile in the global config.yaml or npm_config_userconfig (getNpmrcAuthFile; src/loadNpmrcFiles.ts reads it in place of ~/.npmrc). pnpm 10 reads npm_config_* variables as npm does. ↗
  • extra.parsing: pnpm parses its command line with @pnpm/nopt 0.3.1 (github.com/pnpm/nopt, lib/nopt.js), a fork of nopt: every leading dash is stripped, an exact shorthand or a word of one-letter shorthands is expanded, and an unambiguous prefix of an option of the command is taken for that option, so pnpm add --reg=<url> sets registry; --no-<name> is a negated flag: lib/nopt.js strips every leading no- in any case, each one inverting it, before the prefix is resolved, so --no-ign is --no-ignore-scripts when no other option of the command starts with ign (parse-cli-args, shorthands.ts and pnpm/nopt read again 2026-11-01). Options pnpm does not know make it stop with an error (pnpm11/pnpm/src/main.ts, dropUnknownOptions). --config.<key>=<value> sets the setting <key> (separateConfigDotArgs, normalizeOptions), also in pnpm 10.34.9 (cli/parse-cli-args/src/index.ts). The shorthands are pnpm11/pnpm/src/shorthands.ts; pnpm 10.34.9 has the same without y. ↗
  • extra.booleanWords: The nopt fork pnpm imports (@pnpm/nopt, imported by pnpm11/cli/parse-cli-args/src/index.ts at v12.16.1) reads a Boolean option followed by the word true or false as that value and skips the word, inverted after --no- (parse in lib/nopt.js). ↗
  • extra.directoryOptions: -C <path>, --dir <path>: "Run as if pnpm was started in <path> instead of the current working directory." -C is the shorthand of --dir (parsing.shorthands). pnpm11/cli/parse-cli-args/src/index.ts at v12.16.1 takes dir from the options nopt parsed from the whole command line ("let dir = parsedOpts['dir']") and looks for the workspace from it ("findWorkspaceDir((dir ?? process.cwd()) as string)"). -w, --workspace-root ("Run as if pnpm was started in the root of the workspace") is not listed: it names no directory. ↗
  • extra.configCommands: pnpm config (aliases: c) manages the configuration files: set <key> <value>, get <key>, delete <key> and list; get and list only read. pnpm pkg "Manages the contents of package.json from the command line": get, set, delete and fix, no aliases (docs/cli/pkg.md). ↗
  • extra.installOverrides: pnpm add takes --ignore-scripts ("Same as the ignoreScripts setting") and --allow-build, which lists packages allowed to run postinstall scripts (docs/cli/add.md in pnpm/pnpm.io; a ! prefix denies one instead, still asked about). Any setting can be given as --config.<key>=<value>, the key kept as written (normalizeOptions in pnpm11/cli/parse-cli-args/src/index.ts at v12.16.1), so both spellings are listed and the scanner reads the key without --config.. pnpm_config_<key> and PNPM_CONFIG_<KEY> set the setting of the camel-cased key; a Boolean only from the exact words true and false, a number with Number (parseEnvVars in env.ts). pnpm 10 reads npm_config_* variables as npm does (registryOverrides). minimumReleaseAgeStrict false installs a younger version when no older one matches (user.weakening). ↗
  • extra.minimumReleaseAgeStrict: When false, pnpm falls back to a version that does not meet minimumReleaseAge; when true, resolution fails. It defaults to true when minimumReleaseAge is set explicitly, except in 11.0.0-11.0.3 and 12.0.0-12.2.x (see strictMode): pnpm 11.0.0 and 12.0.0 installed a version 4 hours old with minimumReleaseAge: 4320 on 2026-10-29, and 12.0.0 added it to minimumReleaseAgeExclude. ↗
  • extra.cooldownExactVersions: pnpm 10.17.0: "Don't ignore the minimumReleaseAge check, when the package is requested by exact version". pnpm 10.16.0 installed typescript@7.1.0-dev.20261029.1, 4 hours old, with minimumReleaseAge: 4320 on 2026-10-29. ↗
  • extra.lockfileDocuments: A lockfile whose first line is --- has two YAML documents: a boot document with configDependencies and packageManagerDependencies, written when the project has config dependencies, declares devEngines.packageManager or pins pnpm 12 or newer; then the project lockfile (importers, packages, snapshots), which is always the last document. Seen with pnpm 12.16.1 and packageManager pnpm@12.16.1 on 2026-10-29. ↗
  • extra.lockfileFormat: lockfileVersion 9.0 (pnpm 9 to 12). Registry packages are keyed name@version; git dependencies name@git+<repo>#<commit> with resolution type git, or a tarball from a git host (gitHosted: true; older lockfiles lack the flag, so the host decides); tarball URLs name@https://…; local tarballs name@file:….tgz; local directories have resolution type directory; link: and workspace: dependencies appear only under importers. requiresBuild was removed in lockfile v9, so install scripts are not recorded. A tarball URL under the configured registry is resolved as that registry package and version (resolving/npm-resolver/src/parseBareSpecifier.ts in v10.34.9), so it is keyed name@version and keeps the URL only in the importer specifier; seen in lockfiles written by pnpm 10.34.9 and 12.16.1. ↗
  • extra.npmrcPrecedence: pnpm 10 applies pnpm-workspace.yaml settings over .npmrc and npm_config_* variables; command-line options win over both (same order on v10.16.0). The 10.18.3 changelog says pnpm config set --location=project writes to pnpm-workspace.yaml "matching read priority". The 10.x docs do not state the order. ↗
  • extra.npmrcCooldownKey: pnpm 10 reads minimum-release-age from .npmrc as a number and maps it to minimumReleaseAge (minutes), so the value means the same in both files; pnpm-workspace.yaml wins when both set it (npmrcPrecedence). pnpm 11.0.0 stopped reading it from .npmrc (ignoredSince). ↗
  • extra.sharedWorkspaceLockfile: Same name and default in pnpm 11 and 12, where it is read only from pnpm-workspace.yaml. ↗
  • extra.ignoredSince: Structured form of npmrcIgnored: from 11.0.0 on, other .npmrc settings and the package.json "pnpm" field have no effect. ↗
  • extra.allowAllBuilds: off: the values that leave it off. pnpm tests the value for truth and checks no type: pnpm 10 and 11 read pnpm-workspace.yaml with js-yaml (extra.yamlMergeKeys) and copy each key as it is (getOptionsFromPnpmSettings at 10.28.0, applyWorkspaceSetting at 11.28.10), so a string such as "false", "no" or "true" is on; depcurfew treats every value but false, 0, null and an empty string as on. pnpm 12 reads it into an Option<bool> (dangerously_allow_all_builds in pnpm/crates/config/src/workspace_yaml/settings.rs at 12.16.1) with the YAML 1.1 words of serde-saphyr 0.0.29 (parse_yaml11_bool: true, yes, y, on and false, no, n, off, in any case and also quoted), and stops on any other value, so no value is on there that depcurfew reads as off. Boolean, default false; added in 10.9.0 ("Added a new setting, dangerouslyAllowAllBuilds, for automatically running any scripts of dependencies without the need to approve any builds", pnpm/CHANGELOG.md at v10.26.0). Packages set to false in allowBuilds (or build: false in permissions) stay blocked only from pnpm 12.12.0 (release notes at https://github.com/pnpm/pnpm/releases/tag/v12.12.0: "A package set to false in allowBuilds no longer runs its build scripts when dangerouslyAllowAllBuilds is true", "Previously, dangerouslyAllowAllBuilds ignored the denials"). pnpm 10, 11 and 12.0.0-12.11.x run them too: createAllowBuildFunction returns before it reads the lists ("if (opts.dangerouslyAllowAllBuilds) return () => true" in building/policy at 11.28.10 and builder/policy/src/index.ts at 10.34.9; allow_build_policy.rs at 12.0.0). ↗
  • extra.excludeWildcards: Globs such as @myorg/* in minimumReleaseAgeExclude since 10.17.0. ↗
  • extra.onlyBuiltDependencies: The allow-list before allowBuilds: package.json pnpm.onlyBuiltDependencies, added in 6.32.0 ("If this field exists, only mentioned packages will be able to run install scripts") and working since 6.32.1 ("released with a bug in v6.32.0"); also pnpm-workspace.yaml since 10.5.0 (10.5.0 changelog); removed in 11.0.0 (settings/build.md, see legacyAllowList). Before pnpm 10 any list, even an empty one, lets only the listed packages build (createAllowBuildFunction in @pnpm/builder.policy 3.0.0, which pnpm 9.15.0 uses). ↗
  • extra.ignoredBuiltDependencies: The record of denied builds before allowBuilds (denyList): package.json pnpm.ignoredBuiltDependencies since 10.1.0 ("for explicitly listing packages that should not be built. When a package is in the list, pnpm will not print an info message about that package not being built"), and pnpm-workspace.yaml since 10.5.0 ("Allow to set the \"pnpm\" settings from package.json via the pnpm-workspace.yaml file"). The 10.26.0 entry for allowBuilds says that allowBuilds: { core-js: false } "achieves the same result as" ignoredBuiltDependencies: [core-js]. It only silences the report: createAllowBuildFunction (builder/policy/src/index.ts at v10.25.0) does not read it, so a package onlyBuiltDependencies names still builds. Deprecated in 10.26.0 and removed in 11.0.0 (see legacyAllowList). ↗
  • extra.npmrcBuildSettings: pnpm 10 reads dangerously-allow-all-builds from the project .npmrc as from every .npmrc, with parseField of @pnpm/npm-conf, so every value but false, null and undefined is on (user.weakening). From 10.13.0 config/config/src/index.ts takes the build settings of all .npmrc files and npm_config_* variables aside (extractAndRemoveDependencyBuildOptions) and applies them only when pnpm-workspace.yaml and the "pnpm" field of package.json (from which getOptionsFromRootManifest takes onlyBuiltDependencies, onlyBuiltDependenciesFile and neverBuiltDependencies) set none of projectKeys (hasDependencyBuildOptions: a key that is not null or undefined); the list gained allowBuilds in 10.26.0 (dependencyBuildOptions.ts at 10.13.0, 10.25.0, 10.26.0 and 10.28.0; the file does not exist in 10.12.1). Before 10.13.0 the .npmrc value applies unless pnpm-workspace.yaml sets dangerouslyAllowAllBuilds itself (npmrcPrecedence). pnpm 11 reads only auth and registry settings from .npmrc (ignoredSince). ↗
  • extra.yamlMergeKeys: pnpm-workspace.yaml and the global config.yaml (readWorkspaceManifest with cfgFileName) are read with read-yaml-file, which calls load of js-yaml with its default schema, and that schema has the merge type: read-yaml-file 3.0.0 with @zkochan/js-yaml 0.0.11 in 11.28.10, read-yaml-file 2.1.0 with @zkochan/js-yaml 0.0.9 in 10.28.0 and 0.0.11 in 10.34.9 (workspace/read-manifest/src/index.ts and pnpm-lock.yaml at those tags; lib/schema/default.js of the packages). pnpm 12 reads both files with serde_saphyr::from_str (pnpm/crates/config/src/workspace_yaml/parse_settings.rs at 12.16.1), whose default MergeKeyPolicy is Merge (serde-saphyr 0.0.29). So <<: *defaults brings the keys of the anchored map into the map, and settings set that way apply (a review run with pnpm 10.28.0: pnpm config get dangerouslyAllowAllBuilds gave true and installs ran scripts). A key written in the map itself wins over a merged one whatever their order (mergeMappings of js-yaml adds only missing keys; serde-saphyr adds merged entries whose key is not seen), and earlier maps of <<: [*a, *b] win over later ones; a quoted "<<" is an ordinary key. ↗
  • extra.latestVersion: pnpm 12.0.0 shipped on 26 Aug and 11.0.0 on 28 Apr (GitHub shows no year; 2026 inferred from release order). 11.x and 10.x still receive patches. ↗
  • extra.buildPermissions: permissions.<package>.build in pnpm-workspace.yaml: true lets the package run its build scripts, false denies them; the keys take the same forms as those of allowBuilds, and the entry outranks the package's allowBuilds entry (decided_build_approvals and apply_permissions in pnpm/crates/config/src/workspace_yaml/permissions.rs at v12.16.1, which warns when a package is in both). A string is an undecided placeholder (AllowBuild::Undecided in sections.rs). Added in 12.11.0 (docs/settings/build.md and docs/cli/permissions.md); pnpm approve writes a build decision there only when the file already has permissions. ↗
  • extra.strictDepBuilds: When true, an unreviewed dependency build script fails the install. ↗
  • extra.strictMode: In non-strict mode pnpm silently writes immature picks into minimumReleaseAgeExclude. Strict mode fails CI installs with ERR_PNPM_NO_MATURE_MATCHING_VERSION. ↗
  • extra.tarballResolution: pnpm fetches a registry package of pnpm-lock.yaml (a key name@version) from the tarball URL get-npm-tarball-url builds from the name and version, unless its resolution has tarball: then from that URL, resolved against the registry (new url.URL(resolution.tarball, registry)). pnpm 11.28.10 does the same (resolveTarballUrl in pnpm11/lockfile/utils/src/pkgSnapshotToResolution.ts). assertRegistryShapedResolution (lockfile/utils/src/assertRegistryShapedResolution.ts at v10.34.9) accepts any http(s) URL there for such a key, and a relative path without a scheme or a leading slash, which "is resolved against the configured registry", while the allowBuild policy "derives a trusted package identity from that key shape". pnpm writes tarball for a registry package whose tarball is not at the URL it would build. The fetch requests the path and the query of the URL, never the fragment, and the registry serves the file the path names. ↗
  • extra.rootLifecycleScripts: pnpm 11.28.10 runs the projects' own lifecycle scripts after linking "if (!opts.ignoreScripts && !opts.virtualStoreOnly)" (runProjectLifecycleScripts), with PROJECT_LIFECYCLE_STAGES = preinstall, install, postinstall, preprepare, prepare, postprepare for a full install and only the install stages for --prod or deploy (exec/lifecycle/src/runLifecycleHooksConcurrently.ts); allowBuilds only goes to the build of dependencies (allowBuild). pnpm 10.34.9 does the same in pkg-manager/core/src/install/index.ts and, for a frozen lockfile, pkg-manager/headless/src/index.ts ("if (!opts.ignoreScripts && !opts.ignorePackageManifest) await runLifecycleHooksConcurrently([preinstall, install, postinstall, preprepare, prepare, postprepare], ...)"). pnpm 12.16.1 picks PROJECT_LIFECYCLE_STAGES for a full install with devDependencies (project_script_stages in pnpm/crates/package-manager/src/install/lifecycle/uninstall.rs). ↗
  • extra.managesOwnVersion: 10.0.0: "manage-package-manager-versions: enabled by default. pnpm now manages its own version based on the packageManager field in package.json by default" (added in 9.7.0, off by default: "pnpm will switch to the version specified in the packageManager field of package.json ... This is the same field used by Corepack"). The 11.0.0 release notes replace the setting with pmOnFail, which "directly sets the onFail behavior of both packageManager and devEngines.packageManager" (https://github.com/pnpm/pnpm/releases/tag/v11.0.0); pnpm 12 documents pmOnFail with the default download: "download and run the declared pnpm version (this is the default and matches the previous managePackageManagerVersions: true behavior)" (pnpm/docs/settings/cli.md at v12.16.1). So any pnpm 10 or later honors a pnpm pin without Corepack. ↗

Yarn (Berry)

  • cooldown.configFiles: Also YARN_NPM_MINIMAL_AGE_GATE (general YARN_ env rule) and, since 4.17.0, npmScopes.<scope>.npmMinimalAgeGate. package.json cannot set it. ↗
  • cooldown.unit: Bare numbers are minutes. Since 4.11.0 duration strings with ms, s, m, h, d or w (e.g. 3d, 1w) also work; on 4.10.x a string such as 7d silently had no effect. ↗
  • cooldown.availableSince: The setting arrived in 4.10.0 (release notes, pull request and source; the security docs page at https://yarnpkg.com/features/security says 4.12). 4.10.2 fixed it: "Bust the metadata cache" (#6908) and "support registries without publish times using minimalAgeGate" (#6907). On 2026-10-29 Yarn 4.10.1 with npmMinimalAgeGate: 4320 refused zod@3.23.8 and esbuild@0.25.0, both over a year old ("No candidates found"), while 4.10.2, 4.10.3, 4.11.0 and 4.12.0 installed them and refused a version 4 hours old. depcurfew writes the setting from 4.10.2 on. ↗
  • installScripts.defaultPolicy: Workspace scripts still run. Upgraded projects with an old lockfile get enableScripts: true written to .yarnrc.yml. Yarn 1 runs scripts unless --ignore-scripts is passed. ↗
  • installScripts.allowList.file: Root package.json only; ignored inside workspaces. ↗
  • installScripts.disableAll: Set in .yarnrc.yml; the default since 4.14.0. yarn install --mode=skip-build skips builds for one run. Berry ignores YARN_IGNORE_SCRIPTS. ↗
  • sources.git.default: Upgraded projects with an old lockfile get ["**"] written to .yarnrc.yml. ↗
  • project.lockfiles: Yarn Classic uses the same name; see berryLockfileMarker and classicLockfileHeader to tell them apart. ↗
  • project.workspaces: Array of folder glob patterns. ↗
  • user.files: Configuration.find adds .yarnrc.yml from the home folder (folderUtils.getHomeFolder: os.homedir(), else /usr/local/share) with the lowest priority, also for projects outside the home folder; the name stays .yarnrc.yml even when YARN_RC_FILENAME is set. The yarnrc page does not describe it; yarn config set -H writes the home file (https://yarnpkg.com/cli/config/set). The lookup is the same in 4.0.0, and the 2.2.0 changelog already speaks of the home configuration file; the first version was not tracked. ↗
  • user.settings: Configuration.use knows no project-only settings, so the home file sets these wherever the version has them; the first versions are those of cooldown, cooldown.exclude and sources.git, and enableScripts is checked in 4.0.0. enableScripts: false denies every dependency build script (scriptsSwitch); buildsDeny is the closest purpose, since Yarn has no strict mode. The allow-list dependenciesMeta.<package>.built is read from the root package.json only (Project.getDependencyMeta), so Yarn has no user-level allow-list. depcurfew does not write npmScopes.<scope>.npmMinimalAgeGate. ↗
  • user.unknownKeys: Configuration.use sets a key it does not know aside without an error when it comes from the home file, even with enableStrictSettings; other files throw. The 2.2.0 changelog: "Unsupported options will simply be silently ignored." ↗
  • extra.environmentNames: getEnvironmentSettings lowercases every name of process.env and takes those that start with yarn_ (ENVIRONMENT_PREFIX), and getRcFilename compares the lowercased name with yarn_rc_filename, so yarn_enable_scripts and Yarn_Enable_Scripts set enableScripts as YARN_ENABLE_SCRIPTS does (decision D-143). ↗
  • extra.registrySettings: npmRegistryServer: "Define the registry to use when fetching packages"; npmScopes: "Per-scope registry configurations", whose entries take npmRegistryServer ("See npmRegistryServer"), keyed by the scope without @. "While Yarn will automatically find them in the parent directories, they should usually be kept at the root of your project". Yarn (Berry) does not read registry= from .npmrc. ↗
  • extra.yamlMergeKeys: parseSyml reads .yarnrc.yml with load of js-yaml and FAILSAFE_SCHEMA, which has no merge type (only strings, sequences and maps), so <<: *defaults is an ordinary key named <<: Configuration.use rejects it as an unrecognized setting in a project .yarnrc.yml (enableStrictSettings, default true) and sets it aside in the home file, so merged values never apply. Every scalar is a string to Yarn, which parses it per setting (parseValue in packages/yarnpkg-core/sources/Configuration.ts). ↗
  • extra.classicUserFile: Yarn Classic (1.x, last release 1.22.22) reads .yarnrc and .npmrc from the project, its parent folders, the home folder (homeConfigLoc = ~/.yarnrc) and the global prefix (getPossibleConfigLocations in src/registries/npm-registry.js), and of .yarnrc.yml only yarnPath (yarnPathRuns), whose other settings only Yarn 2 and later read. depcurfew does not configure Yarn Classic. ↗
  • extra.yarnPathRuns: Yarn Classic 1.18.0 and later read yarnPath from .yarnrc.yml (CHANGELOG 1.18.0: "Adds support for reading yarnPath from v2-produced .yarnrc.yml files", #7350): getRcPaths in src/util/rc.js looks for .yarnrc and .yarnrc.yml in the folder and its parents, loadRcFile in src/rc.js keeps only yarnPath of a .yml file, resolved against its folder, and start() in src/cli/index.js runs node <yarnPath> before anything else, also before the check that packageManager names Yarn 1 (which only main() does). Yarn 2 and later do the same (run and runYarnPath in packages/yarnpkg-cli/sources/lib.ts at @yarnpkg/cli/4.18.1), unless YARN_IGNORE_PATH is set. So a release committed under yarnPath is the Yarn that runs, whichever Yarn starts, with or without Corepack. ↗
  • extra.denyList: With built: false in the root package.json, Yarn reports that the build "has been explicitly disabled through configuration" as an info message instead of the warning that all build scripts are disabled; built: false also wins over enableScripts: true. Only the top-level manifest counts (CHANGELOG 2.0.0). ↗
  • extra.projectInstall: The install command ("install the project dependencies") has the paths [`install`] and Command.Default, so yarn without a command installs too. yarn add (commandLine.add) adds packages. ↗
  • extra.commandLine: dlx.ts (documented at https://yarnpkg.com/cli/dlx) downloads the package named by the command, or the ones given with -p/--package, into a temporary environment and runs it. create.ts (yarn create, not on yarnpkg.com) takes -p/--package as well and runs create-<name>: @foo becomes @foo/create, @foo/app becomes @foo/create-app, foo becomes create-foo, and a name that already matches ^create(-|$) is kept (so is create alone). yarn add (https://yarnpkg.com/cli/add) takes packages as arguments; of its options only --mode takes a value. yarn workspace <workspaceName> <commandName> … runs a command within that workspace, e.g. yarn workspace components add -D react (https://yarnpkg.com/cli/workspace). ↗
  • extra.packageSpecs: Protocols besides npm: and git: exec:, file:, jsr:, link:, patch:, portal: and workspace:. link: connects an external directory (https://yarnpkg.com/protocol/link), portal: a relative path to a package folder (https://yarnpkg.com/protocol/portal) and file: copies a folder or tarball. ↗
  • extra.registryOverrides: Environment variables that start with yarn_ (any case) set the setting named by the camel-cased rest, so YARN_NPM_REGISTRY_SERVER sets npmRegistryServer, the registry packages are fetched from (https://yarnpkg.com/configuration/yarnrc#npmRegistryServer). getRcFilename reads yarn_rc_filename (any case) as the name of the configuration file instead of .yarnrc.yml. npmScopes, an object, cannot be set this way. ↗
  • extra.registryFetch: Yarn fetches a registry package of yarn.lock by its resolution: getLocatorUrl builds <registry>/<name>/-/<name>-<version>.tgz from the name of the locator and the version after npm:, cleaned by semverUtils.clean (packages/yarnpkg-core/sources/semverUtils.ts, which drops leading spaces, v and = and trailing spaces and keeps pre-release and build), and supports only a reference whose part before ? semver.valid accepts. The version field of the entry goes into the package Yarn builds from the lockfile (setupResolutions in packages/yarnpkg-core/sources/Project.ts) and is not used for the fetch. A patch: locator wraps the locator it patches, URL-encoded, up to #. An npm: reference with an __archiveUrl parameter is fetched from that URL instead (NpmHttpFetcher.ts). ↗
  • extra.lockfileFormat: Each entry has resolution: name@<locator>: npm:<version> for the registry, <repository>#commit=<sha> for git (GitHub shortcuts become https://github.com/<owner>/<repo>.git), an http(s) URL for tarballs, file:<path> (a .tgz or .tar.gz path is a tarball, anything else a directory), portal: and link: for directories, workspace: for workspace packages, and patch: around the URL-encoded original locator. No field records install scripts; dependenciesMeta.built: false is a user opt-out. ↗
  • extra.durationStrings: npmMinimalAgeGate accepts a number followed by ms, s, m, h, d or w (e.g. 3d, 1w) since 4.11.0; on 4.10.x such a string silently had no effect. ↗
  • extra.excludeWildcards: Name globs such as @scope/* or package* in npmPreapprovedPackages. ↗
  • extra.classicLockfileHeader: Written as # yarn lockfile v${LOCKFILE_VERSION} with LOCKFILE_VERSION = 1 (src/constants.js). ↗
  • extra.latestVersion: Yarn 6 is still in preview. ↗
  • extra.directoryOptions: checkCwd takes --cwd <dir> or --cwd=<dir> only as the first argument ("argv[0] === `--cwd`", "argv[0].startsWith(`--cwd=`)"), and for yarn add also as the last two words ("argv[0] === `add` && argv[argv.length - 2] === `--cwd`"; "CRA adds `--cwd` at the end of the command"), removes them and runs the command with cli.defaultContext.cwd = ppath.resolve(cwd). Yarn finds the project and its .yarnrc.yml files from that directory. ↗
  • extra.configCommands: plugin-essentials registers config get, config set and config unset next to config (commands/config/*.ts at 4.18.1). yarn config set updates the project configuration, or the home configuration with -H/--home (commands/config/set.ts); yarn config and yarn config get only print settings (commands/config.ts: "This command prints the current active configuration settings"). ↗
  • extra.installOverrides: yarn add declares noTimeGate = Option.Boolean(`--no-time-gate`), "Disable the minimum release age check for this command" (plugin-essentials/sources/commands/add.ts at 4.18.1). getEnvironmentSettings lowercases every environment variable, keeps those starting with yarn_ and camel-cases the rest into a setting (ENVIRONMENT_PREFIX), so YARN_NPM_MINIMAL_AGE_GATE sets npmMinimalAgeGate, YARN_NPM_PREAPPROVED_PACKAGES npmPreapprovedPackages and YARN_ENABLE_SCRIPTS enableScripts; the values that keep scripts off are those of user.variables. ↗
  • extra.perScopeGate: getMinimalAgeGate: for a scoped package, a number in npmScopes.<scope>.npmMinimalAgeGate (the scope name without @) replaces the global gate, longer or shorter, and 0 turns the gate off for that scope (acceptance tests "npmScopes override" in features/npmMinimalAgeGate.test.ts at 4.18.1; the code is the same in 4.17.0 and absent in 4.16.0). Each npmScopes entry is a shape whose unset properties get their defaults (parseShape and getDefaultValue in yarnpkg-core Configuration.ts), so a scope listed only for its registry gets the default of 1d (scopablePackageGateSettings in plugin-npm index.ts) instead of the global gate; read from the code, no test covers that case. ↗
  • extra.upgradeMigration: Explicit values written by depcurfew prevent the migration. ↗

Bun

  • cooldown.configFiles: Also the global $HOME/.bunfig.toml or $XDG_CONFIG_HOME/.bunfig.toml; local keys override global ones. Bun's .npmrc support has no min-release-age key. ↗
  • cooldown.cliFlag: bun install, add and update; bunx honors it only since 1.4.4. ↗
  • cooldown.unit: Plain numbers are seconds; 0 turns it off. Since 1.4.4 duration strings such as 90m, 12 hours, 3d or 2 weeks also work (the bunfig reference still documents seconds only). ↗
  • cooldown.exclude.patternSyntax: Since 1.4.4 --minimum-release-age-excludes replaces the bunfig list for one command. ↗
  • installScripts.defaultPolicy: Dependency scripts run only for Bun's built-in trusted list (npm-registry packages only since 1.4) or trustedDependencies; the root project's scripts run. First version of this policy not tracked. ↗
  • installScripts.allowList.setting: Replaces the built-in default list rather than extending it. bun pm trust and bun add --trust write it. ↗
  • installScripts.disableAll: Default false. Also --ignore-scripts or ignore-scripts=true in .npmrc. Skips the project's own scripts and trustedDependencies too. ↗
  • project.workspaces: Full glob syntax, including ! patterns. ↗
  • project.workspacesObjectKey: The object form also holds catalog and catalogs. ↗
  • user.files: "When XDG_CONFIG_HOME is set to an absolute path, Bun reads the file there and not the one in $HOME"; HOME is USERPROFILE on Windows (src/bun_core/env_var.rs). Only one file is read, with no fallback when the XDG one is missing (get_home_config_path in src/bunfig/arguments.rs). Only package manager commands read it (bun install, add, remove, update, pm, bunx and so on), before the project bunfig.toml, whose keys win. 1.2.0 already reads it, and the first version was not tracked; 1.2.0 and 1.3.0 used XDG_CONFIG_HOME whenever it was set, and the version that started requiring an absolute path was not pinned. ↗
  • user.settings: parse_install reads both from the user file as from bunfig.toml (only globalDir and globalBinDir are user-only), as in 1.3.0 (bunfig.zig). trustedDependencies exists only in package.json and bunfig has no such key, so Bun has no user-level allow-list; install.ignoreScripts only turns scripts off. Write whole seconds: duration strings need 1.4.4. ↗
  • user.unknownKeys: The parser looks up only the keys it knows (install_obj.get), so another key, such as install.minimumReleaseAge before 1.3.0, is neither read nor reported. ↗
  • user.invalidValueFails: load_global_bunfig ends the process through report_bunfig_load_failure when the user file has a value Bun cannot read, e.g. minimumReleaseAge = "3d" before 1.4.4 ("Expected number of seconds for minimumReleaseAge"), so every package manager command fails; 1.3.0 crashed the same way. A file Bun cannot read at all is skipped. ↗
  • user.weakening: Both files fill one set of options, the user file first, so a key in the project bunfig.toml replaces the user value; an empty minimumReleaseAgeExcludes list is skipped, so a project's [] does not clear the user list. 0 turns the delay off (src/install/PackageManager/PackageManagerOptions.rs keeps only values above 0). The command line beats both files. ↗
  • extra.environmentNames: Options::load looks up BUN_CONFIG_REGISTRY, NPM_CONFIG_REGISTRY and npm_config_registry with env.get, each spelling as written; the map behind env.get (HashTable in src/dotenv/env_loader.rs, https://github.com/oven-sh/bun/blob/bun-v1.4.4/src/dotenv/env_loader.rs) is a StringArrayHashMap outside Windows and a CaseInsensitiveAsciiStringArrayHashMap on Windows, where names are not told apart by case. Decision D-143. ↗
  • extra.registrySettings: "Put bunfig.toml in your project root, alongside your package.json"; the global $HOME/.bunfig.toml (or $XDG_CONFIG_HOME/.bunfig.toml) is loaded too, and local keys win. "The default registry is https://registry.npmjs.org/. To change it": [install] registry, a string or { url, token }. "To configure a registry for a particular scope (for example, @myorg/<package>), use install.scopes": a key per scope (myorg = "https://registry.myorg.com/" or a table with url). ↗
  • extra.projectInstall: "if your project has a package.json, you can use bun install"; the page names no alias, so none is listed. bun add (commandLine.add) adds packages. ↗
  • extra.commandLine: Options of bun add (snippets/cli/add.mdx) and bunx (snippets/cli/bunx.mdx) typed string or number; --catalog takes its name only after =. -p is --package for bunx but the flag --production for bun add, so it is listed with bunx only. The short forms -F (--filter) and -c (--config) of bun add are left out because bunx does not document them, and an option wrongly read as taking a value would hide the package after it. bunx is an alias for bun x (docs/pm/bunx.mdx). bun create <template> runs the create-<template> package from npm unless a local template has that name; it also takes GitHub repositories and local paths (docs/runtime/templating/create.mdx). ↗
  • extra.packageSpecs: Git dependencies: "Bun supports a variety of protocols, including github, git, git+ssh, and git+https", with the examples git@github.com:moment/moment.git and github:colinhacks/zod. Tarball URLs, local folders and local .tgz files are accepted too. ↗
  • extra.registryOverrides: bun add takes --registry and --config (-c), a configuration file (snippets/cli/add.mdx). BUN_CONFIG_REGISTRY sets the npm registry and environment variables take priority over bunfig.toml (pm/cli/install.mdx). ↗
  • extra.lockfileFormat: bun.lock (text, the default since 1.2) maps each package to a tuple starting with name@<spec>: name@<version> followed by the registry for npm, name@git+<repo>#<sha> and name@github:<owner>/<repo>#<sha> for git, name@https://… for tarball URLs, name@./x.tgz (without file:) for local tarballs, name@file:<dir> and name@link:<dir> for directories, name@workspace:<dir> for workspace packages. The info object carries hasInstallScript: true only since 1.4.4, with no lockfileVersion change, so a missing flag proves nothing for older files. bun.lockb is an undocumented binary format. ↗
  • extra.durationStrings: Since 1.4.4 minimumReleaseAge also takes duration strings such as 90m, 12 hours, 3d or 2 weeks; plain numbers stay seconds. ↗
  • extra.excludeWildcards: minimumReleaseAgeExcludes takes exact package names (and name@version since 1.4.4), no wildcards. ↗
  • extra.trustedDependenciesReplacesDefaults: So an empty list trusts no package: without the field Bun 1.4.4 ran esbuild's postinstall (esbuild is on the built-in list); with "trustedDependencies": [] it blocked it (bun pm untrusted listed it), tested on 2026-10-29. ↗
  • extra.directoryOptions: bun add: <ParamField path="--cwd" type="string"> "Set a specific current working directory" (Global Configuration & Context); bun install has the same option, "Set a specific cwd" (docs/snippets/cli/install.mdx at the same tag, General Configuration). ↗
  • extra.installOverrides: bun add @types/bun --minimum-release-age 259200 # seconds: "A number is in seconds", or a number with a unit such as 90m, 12 hours, 3d or 2 weeks (durationStrings). The page lists no environment variable for it. bun add --trust "adds the package to trustedDependencies in the project's package.json and installs it", so its lifecycle scripts run (docs/snippets/cli/add.mdx and docs/pm/lifecycle.mdx at bun-v1.4.4); lifecycle.mdx names no variable that turns scripts on, and ignore-scripts read from the environment "only turns scripts off". ↗

Deno

  • cooldown.setting: A number or string, or the object form { "age": ..., "exclude": [...] }. Covers npm and JSR packages. ↗
  • cooldown.configFiles: min-release-age in .npmrc since 2.8; also NPM_CONFIG_MIN_RELEASE_AGE. This page does not state precedence; denoland/deno#35458 gives CLI flag, deno.json, .npmrc, environment, built-in default. ↗
  • cooldown.cliFlag: Alias --min-dep-age since 2.9.3. deno install honors it since 2.5.5; deno add, deno remove and deno x since 2.9.4. ↗
  • cooldown.unit: Numbers are minutes; strings may be an ISO-8601 duration (P3D, PT72H), an absolute date or an RFC3339 timestamp; 0 turns it off. The .npmrc format differs (see npmrcFormat). ↗
  • cooldown.default: Since 2.9 a 24-hour minimum applies when nothing is configured; set 0 to turn it off. Whether the default covers JSR is not stated. ↗
  • cooldown.exclude.patternSyntax: Before 2.9.2 wildcard entries were stored literally and never matched. No CLI flag or .npmrc key for exclusions. ↗
  • installScripts.defaultPolicy: npm lifecycle scripts run only when approved, and only with a node_modules directory. deno x / dx runs them after its download prompt is accepted. ↗
  • installScripts.allowList.setting: deno approve-scripts writes it. --allow-scripts=npm:pkg on the CLI exists since 1.45. ↗
  • installScripts.allowList.file: Must be set at the workspace root. ↗
  • sources.git.setting: git+https: and git+ssh: dependencies are not supported in package.json. ↗
  • sources.remoteTarball.setting: Tarball URL dependencies are not supported in package.json. ↗
  • sources.file.setting: No setting. Since 2.8 file: and link: entries are silently skipped (scope disputed, see fileLinkSkipped); deno.json "links" overrides dependencies with local packages. ↗
  • sources.directory.setting: No setting; local directories behave like file: and link: entries (see fileLinkSkipped). ↗
  • project.lockfiles: The default location; lock.path in deno.json can move it and "lock": false turns it off. ↗
  • project.workspaces: Paths of members; globs and ! exclusions since Deno 2.1. ↗
  • user.files: Deno has no user configuration file of its own (deno.json is looked up from the working directory upwards). It reads .npmrc next to package.json or deno.json and in the home directory (HOME, USERPROFILE on Windows), not the file named by NPM_CONFIG_USERCONFIG and not under XDG_CONFIG_HOME. Home discovery arrived in 1.45.0 (#24021); since 2.1.8 (#27119) the project and home files are merged key by key, before that a project .npmrc hid the home one (Releases.md). This is the ~/.npmrc that npm reads. A home .npmrc Deno may not read is skipped; one that does not parse stops the command. ↗
  • user.settings: 2.8.0: "feat(npmrc): support min-release-age (#33983)". A whole number of days (cooldownUnit); the same line sets npm's min-release-age, also in days. minimumDependencyAge.exclude and allowScripts exist only in deno.json (allowScripts at the workspace root), so Deno has no user-level exclusions or script settings. ↗
  • user.cooldownUnit: NpmRc::parse reads min-release-age "in days" (min_release_age_days: Option<u64>; "npm interprets the value as a number of days"): an INI number of 0 or more, or a text that parses as a whole number after ${VAR} expansion; anything else, such as 72h or 1.5, is ignored without a message, so the age comes from the next source. The project .npmrc wins over the home file (libs/resolver/npmrc.rs), and the days count only where deno.json and --min-dep-age set nothing; those take minutes, an ISO-8601 duration or an RFC 3339 date (libs/config/util.rs, libs/cli_parser/src/defs.rs). ↗
  • user.unknownKeys: NpmRc::parse reads registry, auth, replace-registry-host, min-release-age and trust-policy keys and skips every other key without a message. ↗
  • user.invalidValueFails: A min-release-age that is not a whole number of days, such as 72h, is ignored without a message (test "invalid value is ignored"), so the age silently comes from the next source. A home .npmrc that does not parse at all stops the command (libs/resolver/npmrc.rs). ↗
  • user.weakening: The age comes from the command line, then minimumDependencyAge in deno.json, then .npmrc (the project file over the home file), then NPM_CONFIG_MIN_RELEASE_AGE, then the built-in 1440 minutes; 0 from .npmrc turns it off (apply_minimum_dependency_age_fallbacks). The same line turns npm's delay off too. ↗
  • extra.denyList: The object form "allowScripts": { "allow": [...], "deny": ["npm:pkg"] } (schema since 2.6.0: "List of npm package constraints to deny running lifecycle scripts for"); deny beats allow, and a denied package is not added to the packages whose scripts were not run, so Deno does not warn about it. ↗
  • extra.commandLine: install.md: deno install [PACKAGES] installs packages and adds them to deno.json or package.json, deno add is its alias, deno install --global installs a package or script as a binary, and deno install --entrypoint (-e) [FILES] installs what the files use. -n/--name, --root, --os and --arch take a value; --allow-scripts and --node-modules-dir are shown with =. Since Deno 2.8 a name without a prefix is an npm package; JSR packages need jsr: (add.md). x.md: deno x runs a package from npm or JSR without installing it, like npx (deno x npm:create-vite my-app); --package (-p) names the package when the binary differs (deno x -p typescript tsc), and npm:<package>/<binary> picks one binary; deno x --install-alias creates the dx alias. In Deno 2.9.8 (github.com/denoland/deno, cli/args/flags.rs) an executable whose name ends in dx, denox or dnx runs as deno x, and libs/cli_parser/src/defs.rs (X_SUBCOMMAND with COMPILE_ARGS, PERMISSION_ARGS, RUNTIME_MISC_ARGS and INSPECT_ARGS) gives the options of deno x that take a separate value; the permission flags take theirs after =. -L/--log-level is a global option with a value. ↗
  • extra.lockfileFormat: deno.lock version 5 (the default since Deno 2.3) marks npm packages with lifecycle scripts as scripts: true (hasInstallScript from the registry or a preinstall, install or postinstall script, libs/npm/resolution/graph.rs); version 4 has no such field. An npm key is name@version, followed by _ and the versions of its peer dependencies when it has some: libs/lockfile/lib.rs takes the part before the first _ as name@version (key.split_once('_')). tarball is written only for registries other than the default one. Deno rejects git and http(s) dependencies in package.json and keeps file: dependencies out of the lockfile. ↗
  • extra.durationStrings: Strings are ISO-8601 durations (P3D, PT72H), an absolute date or an RFC3339 timestamp; the last two set a fixed cut-off instead of a delay. ↗
  • extra.ageObjectKey: In the object form of minimumDependencyAge, age holds the delay and exclude the exemptions. ↗
  • extra.excludeWildcards: A trailing * matches by prefix (npm:@scope/*) since 2.9.2; earlier wildcard entries never matched. ↗
  • extra.npmSpecifierPrefix: Exclusions and allowScripts entries name npm packages as npm:<name>. ↗
  • extra.allowAllScripts: allowScripts: true allows every npm lifecycle script. Only the JSON value true does: to_allow_scripts_config (libs/config/deno_json/mod.rs at v2.9.8) gives every package for true, none for false and null, and stops with "expected string array, boolean, or object" for a string or a number, so "true" or 1 cannot turn it on silently. ↗
  • extra.installOverrides: deno install --minimum-dependency-age=P3D: deno.json and the flag accept an ISO-8601 duration such as P3D or PT72H, or an integer of minutes, and 0 turns it off; --min-dep-age is its alias (cooldown.cliFlag). deno install --allow-scripts=<packages> lets those packages run their lifecycle scripts, which Deno does not run by default (runtime/reference/cli/install.md in denoland/docs). ↗

uv

  • cooldown.setting: Limits candidate packages to those uploaded before a date or, since 0.9.17, a duration ago. Compared with the upload time of each file, not the release date. false turns off a value from a lower-priority source (since 0.11.24). ↗
  • cooldown.configFiles: Top level of uv.toml or the [tool.uv] table of pyproject.toml. uv searches the current directory and its parents and uses the first directory with uv.toml or a pyproject.toml that has [tool.uv]; uv.toml wins over [tool.uv] in the same directory, with a warning. In a workspace only the root is read. User (~/.config/uv/uv.toml) and system (/etc/uv/uv.toml) files are merged below the project file; uv tool and uvx read only those. UV_EXCLUDE_NEWER overrides the files. ↗
  • cooldown.cliFlag: Also the UV_EXCLUDE_NEWER environment variable. ↗
  • cooldown.unit: A "friendly" duration such as 24 hours, 1 week or 30 days, or an ISO 8601 duration such as P7D; months and years are rejected, a day is always 24 hours. An RFC 3339 timestamp is a fixed cutoff instead of a rolling delay. ↗
  • cooldown.availableSince: Durations ("dependency cooldowns") since 0.9.17; before that exclude-newer took only dates, which do not move with time. Tested on 2026-10-30: uv 0.9.16 printed a warning that "100000 days" is not a date and resolved with no delay at all; 0.9.17 and later held back every version. ↗
  • cooldown.default: No default: without a value every upload time is accepted. ↗
  • cooldown.exclude.setting: A table mapping package names to false (exempt), a date or a duration; package values take precedence over the global and index values. ↗
  • cooldown.exclude.availableSince: The table exists since 0.8.4 (dates); false, which exempts a package, since 0.9.25. Tested on 2026-10-30: with a false entry, uv 0.9.17 warned "data did not match any variant of untagged enum" and ignored the whole [tool.uv] table, the delay included; 0.9.25 and 0.13.6 exempted the package. ↗
  • cooldown.exclude.patternSyntax: Keys are package names, compared after name normalization. ↗
  • installScripts.defaultPolicy: no-build defaults to false: source distributions, git and directory dependencies are built, which runs their build backend. Installing a wheel runs no package code. ↗
  • installScripts.allowList.setting: With no-build = true, the packages in no-binary-package are the only ones built from source ("Allow `all` to be overridden by specific binary exclusions"). Their wheels are not used, so they are always built. ↗
  • installScripts.allowList.file: Or uv.toml; the same table as exclude-newer. ↗
  • installScripts.allowList.availableSince: Project settings no-build, no-build-package, no-binary and no-binary-package; uv sync and related commands respect them since 0.4.6. ↗
  • installScripts.disableAll: Operations that need to build a source distribution fail. Workspace members, editable requirements and wheels built earlier and kept in the cache are still used. With uv 0.13.6 on 2026-10-30, uv sync refused a git dependency and a non-editable local directory dependency as well ("marked as --no-build but has no binary distribution"), so those need an exception too. An explicit no-build = false in a higher-priority file makes uv ignore no-build-package. ↗
  • project.lockfiles: Created next to pyproject.toml. ↗
  • project.workspaces: The [tool.uv.workspace] table of the root pyproject.toml lists members and exclude (globs or paths); exclude wins over members, and the root is a member too. ↗
  • project.workspacesObjectKey: The workspace guide calls members required, while the settings reference (crates/uv-workspace/src/pyproject.rs) gives it a default of []. ↗
  • user.files: User-level configuration is <config dir>/uv/uv.toml: $XDG_CONFIG_HOME/uv, else ~/.config/uv on Linux and macOS (not ~/Library), %APPDATA%\uv, else uv in the Roaming AppData known folder, on Windows (FilesystemOptions::user in crates/uv-settings/src/lib.rs). The directory comes from the etcetera crate (crates/uv-dirs/src/lib.rs), which uses XDG_CONFIG_HOME only when it is an absolute path. Keys sit at the top level, as in [tool.uv] without the prefix; "User- and system-level configuration files cannot use the pyproject.toml format" (docs/concepts/configuration-files.md). The system file (/etc/uv/uv.toml, %PROGRAMDATA%\uv\uv.toml) is merged below it. Same path code at 0.9.0, 0.9.16 and 0.13.6; earlier versions are not tracked. ↗
  • user.settings: Settings of uv.toml are merged with project-level configuration taking precedence over the user-level configuration: a project exclude-newer or no-build wins, exclude-newer-package tables are merged with the project keys winning, and lists such as no-build-package and no-binary-package are concatenated (crates/uv-settings/src/combine.rs). uv tool and uvx read only the user and system files, so the user file is the only file that gives them these settings; uv pip applies the top-level keys unless its [pip] table overrides them. The versions are those of the values depcurfew writes: a duration in exclude-newer since 0.9.17, package = false in exclude-newer-package since 0.9.25. no-build-package takes effect only while no-build is unset. ↗
  • user.unknownKeys: uv.toml is parsed with deny_unknown_fields (OptionsWire), and fields allowed only in pyproject.toml (workspace, sources, dev-dependencies, conflicts, managed, package and others) are rejected by validate_uv_toml (crates/uv-settings/src/lib.rs, Error::PyprojectOnlyField); both are errors of the user file (see invalidValueFails). ↗
  • user.invalidValueFails: FilesystemOptions::user() returns nothing only for a missing, not-a-directory or unreadable file; a TOML or schema error (Error::UvToml) is passed on, and crates/uv/src/lib.rs stops every command that reads configuration with it, unlike an invalid pyproject.toml, which is only warned about. So a value the installed uv does not know (a duration before 0.9.17, package = false before 0.9.25, exclude-newer = false before 0.11.24) breaks every uv command instead of being dropped. A required-version mismatch is reported before a schema error. ↗
  • user.weakening: Tables are merged with the project keys winning, lists are extended and scalars come from the project when it sets them (combine.rs); with no-build = false, NoBuild::from_args ignores the package list (crates/uv-configuration/src/build_options.rs). exclude-newer = false (since 0.11.24) turns off a value from a lower-priority source, the system file included. Read from the code, not run: a [pip] exclude-newer in the user file is combined above the top-level keys for uv pip, so it can override a project exclude-newer there, and a user [[index]] with exclude-newer = false (preview, 0.11.5) exempts the packages of that index. The [pip] table configures "just the uv pip command line interface", and its settings win over the top-level ones there ("many of the settings in this section have corollaries in the top-level namespace which do apply to the uv pip interface unless they are overridden by a value in the uv.pip section", docs/concepts/configuration-files.md); PipOptions has exclude-newer (false disables it), exclude-newer-package, no-build and no-binary (a list, :all: for every package), and the top level no-binary = true builds every package from source (settings.rs). [pip] no-build = false weakens nothing: PipSettings::combine passes it to NoBuild::from_pip_args, which gives NoBuild::None (or the [pip] only-binary list) for false, and combines that with the top-level no-build and no-build-package (NoBuild::combine: All wins, None gives the other side), so it cannot turn the top-level no-build or no-build-package off; a project [tool.uv.pip] no-build wins over the user value anyway (crates/uv-cli/src/settings.rs and crates/uv-configuration/src/build_options.rs at 0.13.6, the same in crates/uv/src/settings.rs at 0.9.17). ↗
  • user.variables: "Settings provided via environment variables take precedence over persistent configuration, and settings provided via the command line take precedence over both" (docs/concepts/configuration-files.md). UV_NO_BUILD_PACKAGE since 0.6.5, UV_NO_BINARY and UV_NO_BINARY_PACKAGE since 0.5.30 (lists separated by spaces), UV_NO_CONFIG since 0.2.30, UV_CONFIG_FILE since 0.1.34. UV_NO_BUILD, UV_NO_BINARY and UV_NO_CONFIG are flags parsed with the BoolishValueParser of clap (crates/uv-cli/src/lib.rs), whose true values are y, yes, t, true, on and 1 and false values n, no, f, false, off and 0, in any case (https://github.com/clap-rs/clap/blob/v4.6.7/clap_builder/src/util/str_to_bool.rs, the clap_builder version in the Cargo.lock of uv); a false value leaves the flag unset (flag() in crates/uv-cli/src/options.rs gives None), so the files decide (with UV_NO_BUILD=0 uv 0.11.32 still refused to build in a review test on 2026-10-31). XDG_CONFIG_HOME and APPDATA move the user directory (see files). ↗
  • extra.environmentNames: The options take their variables through clap (env = EnvVars::UV_PROJECT and the others), and clap_builder Arg::env reads the variable with env::var_os(name) (https://github.com/clap-rs/clap/blob/v4.6.7/clap_builder/src/builder/arg.rs, the clap_builder version in the Cargo.lock of uv), which outside Windows finds only that spelling, so uv_project sets nothing (decision D-143). ↗
  • extra.registrySettings: ResolverInstallerSchema: index ("The package indexes to use when resolving dependencies", [[tool.uv.index]] with name and url), index-url ("The URL of the Python package index (by default: <https://pypi.org/simple>)"), extra-index-url ("Extra URLs of package indexes to use, in addition to --index-url") and find-links ("Locations to search for candidate distributions, in addition to those found in the registry indexes"); PipOptions ([tool.uv.pip]) has index-url, extra-index-url and find-links too. uv.toml takes the same keys at its top level (extra.configTables). docs/concepts/indexes.md: "Indexes are prioritized in the order in which they're defined", the default index is "always treated as lowest priority", with the default first-index strategy uv "will stop at the first index on which a given package is available", default = true replaces PyPI ("set default = true on another index entry" to "exclude PyPI from the list of indexes"), so an entry without it adds an index that is asked before the default one, and an explicit = true index is used only for packages pinned to it in tool.uv.sources. Each [[index]] entry is read as entries says (decision D-120): explicit = true counts only for the packages tool.uv.sources pins to it by name, default = true replaces PyPI, any other entry adds an index (see INDEX_ENTRIES). ↗
  • extra.pylockCreatedBy: uv export --format pylock.toml (and uv pip compile to pylock.toml) writes created-by = "uv". The project itself and workspace members are written as directory = { path = …, editable = true }, with the path relative to the lock file, "." for the project. ↗
  • extra.configTables: Settings sit in [tool.uv] in pyproject.toml and at the top level of uv.toml. uv.toml cannot hold workspace, sources and a few other project fields. ↗
  • extra.pyprojectTable: A pyproject.toml without a [tool.uv] table is ignored when uv searches for configuration. ↗
  • extra.configPrecedence: A nested pyproject.toml with any [tool.uv] table hides the configuration of its parent directories. ↗
  • extra.configFileOrder: "configuration will be read from uv.toml, and the [tool.uv] section in the accompanying pyproject.toml will be ignored"; uv prints a warning listing the ignored fields. ↗
  • extra.workspaceRootOnly: "In workspaces, uv will begin its search at the workspace root, ignoring any configuration defined in workspace members." Project fields such as tool.uv.sources of a member still apply. ↗
  • extra.buildSwitch: The project setting that forbids building source distributions. It also stops git and local directory dependencies (uv sync with uv 0.13.6 on 2026-10-30) and source archives, which also need a build; workspace members and editable requirements are still built. ↗
  • extra.durationStrings: Either a "friendly" duration (24 hours, 1 week, 30 days) or an ISO 8601 duration (PT24H, P7D, P30D). ↗
  • extra.durationUnits: Units in the documented examples: 24 hours, 1 week, 30 days. ↗
  • extra.excludeWildcards: exclude-newer-package keys are exact package names. ↗
  • extra.excludeValue: exclude-newer-package = { name = false } exempts the package from the delay. ↗
  • extra.missingUploadTime: Unless the package is exempt, or the index has its own exclude-newer value or is exempt with [[tool.uv.index]] exclude-newer = false. ↗
  • extra.requiredVersion: A PEP 440 specifier; uv exits with an error when its version does not match. Also at the top level of uv.toml. ↗
  • extra.lockedSettings: uv.lock records these in [options] (a relative exclude-newer as exclude-newer-span); after a change uv lock --check and uv sync --locked fail until uv lock runs again ("Resolving despite existing lockfile due to addition of global exclude newer", seen with uv 0.13.6 on 2026-10-30). no-build and no-binary-package are not recorded. ↗
  • extra.lockOptions: write_options writes [options] when exclude-newer is set: an absolute value as exclude-newer = "<timestamp>"; a relative one as exclude-newer = the placeholder "0001-01-01T00:00:00Z" (with the comment "This has no effect and is included for backwards compatibility when using relative exclude-newer values") and exclude-newer-span = the span as jiff prints it, ISO 8601 (P3D, P1W); since 0.11.8 exclude-newer may be missing next to exclude-newer-span. [options.exclude-newer-package] holds name = "<timestamp>", name = { timestamp = <placeholder>, span = "P3D" } or name = false. The placeholder is ExcludeNewerValue::PLACEHOLDER in crates/uv-distribution-types/src/exclude_newer.rs. ↗
  • extra.lockComparison: ExcludeNewer::compare (lock against the settings, in crates/uv-lock-operations/src/validated_lock.rs after lock.filter_exclude_newer) resolves again on an added or removed global value, a span that differs (ExcludeNewerSpan compares self.0.fieldwise() == other.0.fieldwise() in crates/uv-distribution-types/src/exclude_newer.rs, so "7 days" and P1W differ), a span added to or removed from an absolute value, and an absolute timestamp that is earlier than the locked one (a later one does not count); only a new timestamp of the same span is ignored. Per package (only names of locked packages and names the lock already records, filter_exclude_newer in crates/uv-lock/src/lock/mod.rs): a cutoff removed, a disabled one enabled, an enabled one added, or a changed value; an enabled one that is now disabled does not count. A date without a time (2026-01-01) is the start of the next day in the system time zone, so the timestamp it gives depends on the machine. Messages such as "Resolving despite existing lockfile due to change of exclude newer span from `P3D` to `P1W`" come from the Display of ExcludeNewerValueChange. ↗
  • extra.spanSyntax: jiff 0.2.37 is the version in Cargo.lock of uv 0.13.6. uv parses a relative exclude-newer with jiff's Span (FromStr of ExcludeNewerValue tries a timestamp, then a date, then a span), which reads the friendly format ("3 days", "1w", "2 weeks, 3 days", with each unit at most once, larger units first, a leading sign or a trailing "ago") and ISO 8601 (P3D, PT36H). Span prints as ISO 8601 by default, which is what uv.lock records. uv rejects years and months ("use days instead", crates/uv-distribution-types/src/exclude_newer.rs). The friendly format also has HH:MM:SS and fractions of hours and smaller units, which depcurfew does not read. ↗
  • extra.commandLine: clap arguments of uv add, uv pip install, uv tool install, uv run and uv tool run (uvx), with the global options, IndexArgs, ResolverInstallerArgs, BuildOptionsArgs and DependencyConstraintsArgs they share. --opt value, --opt=value, -o value and -ovalue all work; long options cannot be shortened. Options of uv run, uv tool run and uvx come before the command. --with, --with-editable and --with-executables-from add packages, as a list split at commas outside [...] that are not followed by !, =, <, > or ~ (comma.rs). uvx and uv tool run take the package from the first argument (name@version is ==version, name@latest the newest) unless --from names it; a first argument such as python, python3.12, pypy@3.8 or graalpy runs an interpreter (PythonRequest::try_from_tool_name in uv-python-types, implementation names cpython, pypy, graalpy and pyodide). uv run runs a command and downloads only what --with names, or a script given as an http or https URL. -e takes a path in uv pip install but is a flag in uv tool install, and --editable a flag in uv add; --no-binary and --only-binary take values in uv pip install only, -m is --marker in uv add and --module in uv run. ↗
  • extra.registryOverrides: IndexArgs (lib.rs): --index adds an index (name=url allowed), --default-index replaces PyPI, --index-url and --extra-index-url are their deprecated forms, --find-links adds a page or directory of archives; each has the variable named here. --config-file and UV_CONFIG_FILE name a uv.toml that may set any index. uv does not read pip.conf or PIP_INDEX_URL (docs/pip/compatibility.md). ↗
  • extra.selection: VersionSelectionArgs: --prerelease takes disallow, allow, if-necessary, explicit or if-necessary-or-explicit (UV_PRERELEASE); allow considers pre-releases of every package and disallow none (docs/concepts/resolution.md); --prerelease-package takes PACKAGE=MODE; the hidden --pre means allow. BuildOptionsArgs of uv add, uv run, uv tool install and uv tool run (uvx): --no-binary (UV_NO_BINARY, a boolean) installs every package from source, --binary turns it off, --no-binary-package names one package (UV_NO_BINARY_PACKAGE, separated by spaces). uv pip install takes --no-binary and --only-binary as lists separated by commas with :all: and :none:, as pip does (PipInstallArgs). ↗
  • extra.latestVersion: Released on 2026-10-26. ↗
  • extra.directoryOptions: GlobalArgs (global = true, so before or after the subcommand): --directory "Change to the given directory prior to running the command. Relative paths are resolved with the given directory as the base", env UV_WORKING_DIR; --project "Discover a project in the given directory. All pyproject.toml, uv.toml, and .python-version files will be discovered by walking up the directory tree from the project root … Other command-line arguments (such as relative paths) will be resolved relative to the current working directory … This setting has no effect when used in the uv pip interface", env UV_PROJECT. crates/uv-static/src/env_vars.rs: UV_WORKING_DIR is "Equivalent to the --directory command-line argument. UV_WORKING_DIRECTORY (added in v0.9.1) is also supported for backwards compatibility", UV_PROJECT "Equivalent to the --project command-line argument". ↗
  • extra.installOverrides: ExcludeNewerArgs: #[arg(long, env = EnvVars::UV_EXCLUDE_NEWER)] exclude_newer accepts RFC 3339 timestamps, local dates, friendly and ISO 8601 durations, and false to disable it; PackageExcludeNewerArgs adds --exclude-newer-package PACKAGE=DATE and is flattened into ResolverArgs, InstallerArgs and ResolverInstallerArgs. A date is not compared with the policy, so it is asked about. ↗
  • extra.pipTable: For uv pip commands, PipSettings::combine merges the [pip] table of a configuration file above its top-level keys ("Merge the top-level options (`tool.uv`) with the pip-specific options (`tool.uv.pip`), preferring the latter"): [pip] exclude-newer replaces the top-level value (false turns the delay off), [pip] exclude-newer-package entries win over top-level entries for the same package, and [pip] no-binary (package names, or :all:) is added to the top-level no-binary-package (NoBinary::combine in crates/uv-configuration/src/build_options.rs). [pip] no-build and only-binary are joined with the top-level no-build, so they cannot turn it off. Commands outside uv pip ignore [pip] ("These values will be ignored when running commands outside the `uv pip` namespace", PipOptions in crates/uv-settings/src/settings.rs). keys maps each top-level key depcurfew writes to the [pip] key that overrides or extends it. The same code in 0.11.32 (crates/uv/src/settings.rs). ↗

pip

  • cooldown.setting: Only files uploaded before the given time are considered; applies to packages from remote indexes, not to local files, find-links directories or VCS requirements. Isolated build environments get the same cutoff. ↗
  • cooldown.configFiles: pip reads no configuration from the project: only the global, user and site (virtual environment) pip.conf, the file named by PIP_CONFIG_FILE and PIP_* environment variables. --uploaded-prior-to is not allowed in requirements files, so a project sets it through PIP_UPLOADED_PRIOR_TO or the command line, e.g. in CI. ↗
  • cooldown.cliFlag: pip install, download, wheel, lock, index and list; environment variable PIP_UPLOADED_PRIOR_TO. ↗
  • cooldown.unit: A duration is written PnD, a whole number of days (P3D, matched by ^P(\d+)D$); P1W, PT24H and "7 days" are rejected. An ISO 8601 date or time is a fixed cutoff instead. A day is always 24 hours. ↗
  • cooldown.availableSince: pip 26.1 accepts a duration in days ("P3D for 3 days ago"); the option itself exists since 26.0 with dates only. ↗
  • cooldown.default: Off unless given. ↗
  • installScripts.defaultPolicy: pip builds a source distribution when no wheel fits, which runs its build backend; the secure-installs guide recommends --only-binary :all:. Installing a wheel runs no package code. ↗
  • installScripts.allowList.setting: After --only-binary=:all:, a package named in --no-binary may only be installed from source: a name wins over :all:, so its wheels are not used. --only-binary=:all: given after it clears the exception. ↗
  • installScripts.allowList.file: --only-binary and --no-binary are among the options a requirements file may contain. ↗
  • installScripts.allowList.format: Each use adds to the set; :all: and :none: are special values. ↗
  • installScripts.disableAll: Allowed in requirements files and pip.conf (only-binary). Enforced only for packages from indexes and find-links: VCS, local directory and direct URL source requirements are still built. ↗
  • project.lockfiles: pip lock (experimental since 25.1) writes pylock.toml; pip install -r pylock.toml is experimental since 26.1. The specification also allows pylock.<name>.toml (extra.lockfilePattern). ↗
  • project.manifests: "requirements.txt is usually what these files are named (although, that is not a requirement)"; the format is meant only for pip. ↗
  • user.files: The user file is pip.conf (pip.ini on Windows) in appdirs.user_config_dir("pip") (configuration.py), written in INI with [global] and per-command sections. Linux: $HOME/.config/pip/pip.conf, "which respects the XDG_CONFIG_HOME environment variable" (used when it is not empty after stripping spaces, vendored platformdirs _xdg.py). A relative XDG_CONFIG_HOME is used as it is, so pip reads <value>/pip/pip.conf relative to the directory each command runs in: XDGMixin.user_config_dir in src/pip/_vendor/platformdirs/_xdg.py at 26.2.2 returns the stripped value with no absolute-path check, _append_app_name_and_version (api.py) only joins the app name, and utils/appdirs.py and configuration.py (os.path.join, then os.path.exists and parser.read) make nothing absolute; 26.1.1 (platformdirs 4.5.1, Unix.user_config_dir in unix.py) does the same without stripping the value. macOS: ~/Library/Application Support/pip when that directory exists, else ~/.config/pip, where XDG_CONFIG_HOME is not used (utils/appdirs.py: _macos_user_config_dir takes platformdirs user_data_dir when os.path.isdir); since 26.2 that user_data_dir is $XDG_DATA_HOME/pip when XDG_DATA_HOME is not empty after stripping spaces, so with XDG_DATA_HOME set the Library directory is skipped and ~/.config/pip is used unless $XDG_DATA_HOME/pip exists (XDGMixin in src/pip/_vendor/platformdirs/_xdg.py at 26.2.2; src/pip/_vendor/vendor.txt names platformdirs 4.10.0 in 26.2 and 4.5.1 in 26.1.1, whose macos.py has no XDG handling). Windows: %APPDATA%\pip\pip.ini; platformdirs asks Windows for the Roaming AppData known folder, which APPDATA normally names. The legacy ~/.pip/pip.conf (%HOME%\pip\pip.ini) is loaded as well, below this file. Same path code in 25.0; earlier versions are not tracked. A command reads [global] and the section named after itself, which wins key by key (override_order ["global", self.name, ":env:"] in cli/parser.py); the options doctor --user checks (index_group and package_selection_group in cli/cmdoptions.py) belong to install, download, wheel, lock, index and list (src/pip/_internal/commands at 26.2.2). Keys are read without regard to case and with underscores as dashes, so only_binary in a file is the same setting as only-binary, and the later one wins (_normalize_name in src/pip/_internal/configuration.py at 26.2.2: name.lower().replace("_", "-"), applied to every key of every file). ↗
  • user.settings: depcurfew writes them in [global], which reaches every command that has the option (install, download, wheel, lock, index, list) and the resolver of pipenv lock; [install] reaches only pip install. "Accept --no-binary and --only-binary via pip.conf" (7.1.0); uploaded-prior-to is read from pip.conf like every long option ("To override a duration set in configuration, pass P0D on the command line", user_guide.rst). 26.1.0 because depcurfew writes a PnD duration: pip 26.0 takes dates only and aborts on P7D, and 25.x ignores the key. uv does not read pip.conf. ↗
  • user.unknownKeys: "Ignore options not present in this parser": a key that is not an option of the command is skipped without a word (same code in 25.0), so pip before 26.0 ignores uploaded-prior-to. ↗
  • user.invalidValueFails: A pip.conf that is not valid INI stops pip (ConfigurationFileCouldNotBeLoaded, configuration.py), and a value an option rejects ends the command with a usage error: pip 26.0 aborts on uploaded-prior-to = P7D in every command that has the option, as it rejected PIP_UPLOADED_PRIOR_TO=P100000D in a test on 2026-10-30 (configuration values and PIP_* variables go through the same parsing). Commands without the option ignore the key. ↗
  • user.weakening: In any section of any pip.conf: [install] beats [global], and a later file (a virtual environment pip.conf, PIP_CONFIG_FILE) beats the user file per key, an empty value removing it (cli/parser.py). :all: in one of the lists clears the other and :none: clears its own (handle_mutual_excludes). P0D overrides a configured duration, and "Local package files are allowed regardless of the --uploaded-prior-to setting", find-links directories included (user_guide.rst). A requirements file can also pass --no-binary or --only-binary, but not --uploaded-prior-to. ↗
  • user.variables: "Note that if a file exists at the location that this is set to, the user config file will not be loaded." PIP_<NAME> variables are applied after the [global] and command sections of all files, and the command line beats them (cli/parser.py, override_order). --isolated, a flag, ignores environment variables and user configuration. XDG_CONFIG_HOME (Linux) and XDG_DATA_HOME (macOS, 26.2) move the user directory (see files). ↗
  • extra.environmentNames: get_environ_vars takes the variables of os.environ whose names start with PIP_ (key.startswith("PIP_"), the prefix in upper case) and lowercases the rest (key[4:].lower()), so PIP_index_url sets index-url and pip_index_url sets nothing (decision D-143). ↗
  • extra.configCommand: pip config: "Manage local and global configuration"; "set: Set the command.option=value", "unset: Unset the value associated with command.option", "edit: Edit the configuration file in an editor". Without --user, --global or --site it changes the configuration file of the active virtual environment when that file exists, otherwise the user file. So a CI step or RUN with pip config set can give the later pip installs a release-age delay that no environment variable shows (decision D-115). ↗
  • extra.configSections: "Each subcommand can be configured optionally in its own section. This overrides the global setting with the same name", and "A command specific section in the config file `[<command>] host = bar` overrides the option with same name in the `[global]` config file section" (Precedence / Override order). pip reads only [global], the section of the running command and :env: (override_order = ["global", self.name, ":env:"] in cli/parser.py), so a managed key in [install] wins over [global] for pip install; depcurfew comments such keys out in every section other than [global]. ↗
  • extra.pylockCreatedBy: pip lock writes created-by = "pip". ↗
  • extra.requirementsOptions: SUPPORTED_OPTIONS in pip 26.2.2 (--pypi-url is a second name of --index-url in cmdoptions.py); per requirement also --hash and -C/--config-settings (extra.requirementsParser). Any other option, --uploaded-prior-to included, makes the file fail to parse. ↗
  • extra.requirementsParser: build_parser reads each line with optparse.OptionParser(add_help_option=False) holding SUPPORTED_OPTIONS and SUPPORTED_OPTIONS_REQ (--hash, -C/--config-settings), with the names from cmdoptions.py in pip 26.2.2. optparse takes a long option shortened to a prefix that names exactly one of them (_match_abbrev; an exact name wins), so --no-bin :all: is --no-binary :all:, and an ambiguous prefix such as --no is an error. --hash and --config-settings belong to the requirement on their line; on a line of their own they are accepted and ignored. ↗
  • extra.configFileNames: CONFIG_BASENAME is pip.ini on Windows and pip.conf elsewhere; pip looks for it only in the global, user and site locations, never in the project. ↗
  • extra.configFileVariable: Names a configuration file pip loads last; set to os.devnull it turns all configuration files off. ↗
  • extra.environmentVariable: Every long option has a PIP_<UPPER_LONG_NAME> variable with dashes replaced by underscores. Tested on 2026-10-30: pip 25.3 ignored PIP_UPLOADED_PRIOR_TO=P100000D without a word, 26.0 rejected the duration (dates only), 26.1 and 26.2.2 found no version. ↗
  • extra.durationStrings: Only whole days, written PnD, are accepted. ↗
  • extra.missingUploadTime: Upload times exist only in the JSON form of the simple repository API (PEP 700); indexes that serve only HTML have none. ↗
  • extra.lockfileFormat: Each [[packages]] entry has exactly one of vcs (always built), directory (always built), archive (a source tree or wheel at a URL or path) or sdist and wheels from an index. A package with an sdist and no wheels is built when installed. A relative directory path is relative to the lock file. The required top-level created-by records the name of the tool that wrote the file, preferably its normalized Python package name. ↗
  • extra.requirementsFormat: VCS requirements start with git+, hg+, svn+ or bzr+, alone or after "name @"; a direct reference is "name @ URL" (PEP 508); -e installs a project path or VCS URL in editable mode. The legacy #egg= fragment names the project of a VCS URL. Lines ending with a backslash continue on the next line, and # starts a comment (requirements-file-format.md). ↗
  • extra.requirementsIncludes: Option names from cli/cmdoptions.py. A relative path is relative to the directory of the file that includes it, and a file given as an http, https or file URL is downloaded (req_file.py, _parse_and_recurse); a file that includes itself is an error. ↗
  • extra.requirementsPaths: A requirement that contains a path separator (/, and \ on Windows) or starts with . looks like a path (_looks_like_path): a directory there is a project built from source. A name with an archive extension (utils/filetypes.py) is a local archive, even when the file does not exist. http, https, ftp and file URLs are links (utils/urls.py, is_url). ↗
  • extra.lockfilePattern: A named lock file, next to or instead of pylock.toml; pip lock -o writes any name. ↗
  • extra.commandLine: pip and pip3 are the console scripts of the package (pyproject.toml). The options of pip install (install.py) and the general options of every command (cmdoptions.py, general_group), which may also come before install. pip reads them with optparse: --opt value and --opt=value, -rFILE and -r FILE, grouped short flags, and a long option shortened to any prefix that names one option (cli/parser.py keeps optparse's matching), so --extra means --extra-index-url. -e takes a local project path or a VCS URL to install in editable mode. -r, -c, --requirements-from-script and --group read requirements from files of the project. ↗
  • extra.registryOverrides: index_group: --index-url (alias -i, --pypi-url) is the base URL of the package index, --extra-index-url adds indexes, --find-links (-f) adds an HTML page or a directory of archives. Every long option can be set as PIP_<UPPER_LONG_NAME>, dashes replaced by underscores (docs/html/topics/configuration.md); PIP_CONFIG_FILE names a configuration file loaded last, which may set any index. Requirements files may set --index-url, --extra-index-url and --find-links too (req/req_file.py). ↗
  • extra.selection: --pre includes pre-release and development versions (pip only finds stable versions by default) and stands for --all-releases :all:; --all-releases and --only-final take :all:, :none: or package names separated by commas and allow or forbid pre-releases of those packages (models/release_control.py, allows_prereleases: a named package first, then :all:). --no-binary and --only-binary take the same lists: --no-binary keeps pip from using wheels, so the package is built from source, --only-binary from using source distributions (models/format_control.py, handle_mutual_excludes and get_allowed_formats). Each long option can also be set as PIP_<NAME> (docs/html/topics/configuration.md), which the command line overrides. ↗
  • extra.pipxSelection: pipx forwards the standard PIP_* variables to pip (except PIP_USER, PIP_DISABLE_PIP_VERSION_CHECK, PIP_TARGET and PIP_KEYRING_PROVIDER); the uv backend ignores them (docs/how-to/use-private-index.rst). pipx has no option of its own for pre-releases or source builds; --pip-args may carry them. ↗
  • extra.pipxCommandLine: pipx installs applications from PyPI with pip (or uv) in environments of their own. pipx install takes one or more package specs, a VCS URL, a local path or archive, or a script (--preinstall adds packages to the environment; -f is --force, not find-links). pipx run takes the app first (argparse REMAINDER, so its options come before it), --spec names the package to install and run, --with adds packages; a first argument ending in .py is a local script, or a script to download when it is a URL (docs/how-to/run-scripts.rst). argparse accepts abbreviated long options. ↗
  • extra.pipxRegistryOverrides: --index-url is the base URL of the index; --pip-args is split and handed to pip, so it may carry --extra-index-url, --find-links or --no-index. With the pip backend pipx passes the PIP_* variables on to pip; with the uv backend it ignores them and uv reads its own (docs/how-to/use-uv-backend.rst); both kinds are registry variables of pip and uv. ↗
  • extra.latestVersion: Released on 2026-10-20. ↗
  • extra.configCommands: pip config list, edit, get, set, unset and debug: set and unset change a value and save the file, edit opens it in an editor, list, get and debug only read. Without --user, --global or --site the site file is used if one exists, else the user file. ↗
  • extra.installOverrides: --uploaded-prior-to (metavar datetime_or_duration): "Only consider packages uploaded prior to the given value", an ISO 8601 datetime or a duration of whole days P<n>D. PIP_UPLOADED_PRIOR_TO is its environment variable (environmentVariable). A datetime is not compared with the policy, so it is asked about. ↗

Poetry

  • cooldown.setting: A version is ignored while any of its files was uploaded less than the given number of days ago. Applies when dependencies are resolved (poetry lock, add, update); poetry install installs the locked versions without checking. ↗
  • cooldown.configFiles: The local configuration next to pyproject.toml (poetry config --local), not pyproject.toml itself. Environment variables (POETRY_SOLVER_MIN_RELEASE_AGE) win over poetry.toml, which wins over the user config.toml. ↗
  • cooldown.unit: An integer; 0 (the default) turns it off. ↗
  • cooldown.availableSince: "Introduced in 2.4.0"; announced as dependency cooldowns. Tested on 2026-10-30: Poetry 2.3.4 locked with min-release-age = 100000 in poetry.toml without a word, while 2.4.0 and 2.5.1 found no version. ↗
  • cooldown.default: Default 0: all versions are considered. ↗
  • installScripts.defaultPolicy: Without installer.only-binary, packages are built from source distributions when no wheel fits, which runs their build backend. Git and directory dependencies are always built. Installing a wheel runs no package code. ↗
  • installScripts.allowList.setting: With installer.only-binary = [":all:"], the packages named in installer.no-binary are the only ones built from source; explicit names take precedence over :all: since 2.2.0. Their wheels are rejected, so they are always built. ↗
  • installScripts.allowList.file: The docs recommend configuring it with --local for a project. ↗
  • installScripts.allowList.availableSince: "explicit package names will take precedence over :all:" (#10278). Before 2.2.0 a package listed in both settings has no file left to install. ↗
  • installScripts.allowList.format: poetry config stores the value as a list; written by hand, a boolean is not normalized. ↗
  • installScripts.disableAll: Since 2.0.0; the value [":all:"] forbids source distributions for every package. Applied only when installing: resolving dependencies may still build source distributions without static metadata, and git, path and url dependencies are built regardless. ↗
  • project.lockfiles: Next to pyproject.toml. ↗
  • user.files: "Linux: $XDG_CONFIG_HOME/pypoetry or ~/.config/pypoetry - Windows: %APPDATA%\pypoetry - macOS: ~/Library/Application Support/pypoetry". The code agrees on Linux and Windows: CONFIG_DIR = POETRY_CONFIG_DIR or user_config_path("pypoetry", appauthor=False, roaming=True) from platformdirs, without an override (src/poetry/locations.py; on Windows platformdirs asks for the Roaming AppData known folder, which APPDATA normally names). On macOS the directory depends on the installed platformdirs (libraryDirectories); the docs' directory is used when its version cannot be read. config.toml holds the settings as nested tables ([solver] min-release-age = 7); auth.toml next to it holds credentials. POETRY_CONFIG_DIR replaces the directory. Checked at 2.4.0 and 2.5.1; 2.0.0 removed the special handling of the platformdirs 2 macOS directory (#8916, CHANGELOG.md), and older versions are not tracked. ↗
  • user.libraryDirectories: Poetry 2.5.1 allows platformdirs >=3.0.0,<5 (pyproject.toml; its own lock has 4.11.8), and the official installer runs pip install without constraints in Poetry's virtual environment (python-poetry/install.python-poetry.org, install-poetry.py), so a new install gets the latest 4.x. The macOS user_config_dir by platformdirs version, read from the code at the tags: before 4.6.0 always ~/Library/Application Support/<app> (4.5.1 macos.py has no XDG support); 4.6.0 "Honor XDG environment variables on macOS" (#375): a non-empty XDG_CONFIG_HOME wins, a relative one too (os.environ.get("XDG_CONFIG_HOME", "").strip() in _xdg.py), and otherwise the config directory is user_data_dir, so a non-empty XDG_DATA_HOME gives $XDG_DATA_HOME/<app>; 4.9.6 "Fix macOS XDG variables leaking across user_config_dir, user_data_dir, and user_state_dir" (#473; 4.9.4 still returns user_data_dir); 4.11.8 "Ignore relative paths in XDG Base Directory environment variables and use the existing platform fallback" (#540, _xdg_dir with posixpath.isabs); the same in 4.14.2. A relative value is used as it is, so the tool reads it from the directory each command runs in. ↗
  • user.settings: Every setting of Config.default_config is read from the user config.toml ("As with all configurations described here, this is a user specific configuration", docs/configuration.md); dotted names are nested tables. A project poetry.toml replaces a user value, lists included (merge_dicts in src/poetry/utils/helpers.py), and POETRY_* variables beat both. Names in installer.no-binary win over installer.only-binary = :all: only since 2.2.0. solver.min-release-age-exclude is written as a TOML array (see extra.excludeFormat). ↗
  • user.weakening: Precedence: environment variables, then the local poetry.toml, then the global config.toml, then the default; a poetry.toml key replaces the user value, lists included. solver.min-release-age-exclude-source (2.4.0) takes source names from pyproject.toml or URLs. A source that gives no upload times is not filtered at all. ↗
  • user.variables: Any setting can be set as POETRY_ plus its name in capitals with dots and dashes replaced by underscores, and environment variables come first in the precedence ("Configuration sources"). POETRY_CONFIG_DIR replaces the platform directory (src/poetry/locations.py). ↗
  • extra.environmentNames: Config.get builds the name "POETRY_" + the keys of the setting in upper case with _ for - and reads it with os.getenv(env), and _get_environment_repositories matches POETRY_REPOSITORIES_(?P<name>[A-Z_]+)_URL, so only the names in upper case count (decision D-143). ↗
  • extra.installedPackage: The installation page installs a given version with "pipx install poetry==1.8.4", in CI with "$POETRY_HOME/bin/pip install poetry==2.0.0", and manually with pip in a virtual environment ("$VENV_PATH/bin/pip install poetry"). So poetry==<version> in such a command of a CI job or a Dockerfile is the Poetry the later commands run (decision D-115). ↗
  • extra.pylockCreatedBy: Poetry exports pylock.toml with its export plugin (poetry export --format pylock.toml), which writes created-by = "poetry-plugin-export". ↗
  • extra.configTable: poetry config writes dotted settings as nested tables, e.g. [solver] min-release-age = 7. ↗
  • extra.pyprojectTable: A [tool.poetry] table marks a Poetry project; Poetry also accepts a [project] table with a static name and version, which other tools use as well. ↗
  • extra.buildSwitch: installer.only-binary was added in 2.0.0; [":all:"] forbids source distributions of index packages when installing. Git and directory dependencies, and source archives from a URL or path, are built regardless (src/poetry/installation/executor.py at 2.5.1). ↗
  • extra.excludeWildcards: Package names only. ↗
  • extra.requiredVersion: A version constraint in pyproject.toml; a Poetry version outside it raises an error. Poetry 1.x does not know the key. ↗
  • extra.commandLine: poetry add takes package specs: a name, name@constraint, a PEP 508 requirement, a git URL, a path or an archive URL. Options with a value: --group (-G), --extras (-E), --optional, --python, --platform, --markers and --source of add, and the global --directory (-C) and --project (-P); -e/--editable, -D/--dev, --allow-prereleases, --dry-run and --lock are flags (src/poetry/console/commands/add.py). cleo reads -Gdocs and -G docs; long options cannot be shortened. poetry install takes no package specs. ↗
  • extra.registryOverrides: --source names a package source of [[tool.poetry.source]] in pyproject.toml (or pypi) to take the package from. The POETRY_REPOSITORIES_<NAME>_URL variables are for publishing only; no variable sets a package source. ↗
  • extra.versionConstraints: poetry add name@constraint takes any constraint valid in pyproject.toml, and name@latest the newest release; extras go before the @ (name[extra]@^4.0.0). ^ keeps the left-most non-zero part of major.minor.patch: ^1.2.3 is >=1.2.3 <2.0.0, ^1.2 is >=1.2.0 <2.0.0, ^1 is >=1.0.0 <2.0.0, ^0.2.3 is >=0.2.3 <0.3.0, ^0.0.3 is >=0.0.3 <0.0.4, ^0.0 is >=0.0.0 <0.1.0, ^0 is >=0.0.0 <1.0.0. ~ allows patch changes, or minor changes when only a major version is given: ~1.2.3 is >=1.2.3 <1.3.0, ~1.2 is >=1.2.0 <1.3.0, ~1 is >=1.0.0 <2.0.0. * is any version, 1.* is >=1.0.0 <2.0.0, 1.2.* is >=1.2.0 <1.3.0. ~=, inequalities and == as in PEP 440, several separated by commas; a bare version (1.2.3) is that version only. Poetry prefers stable releases and takes a pre-release only when no stable release satisfies the constraint. ↗
  • extra.selection: installer.no-binary (POETRY_INSTALLER_NO_BINARY) disallows wheels for :all: or true, none for :none: or false, or the named packages separated by commas; installer.only-binary (POETRY_INSTALLER_ONLY_BINARY, since 2.0.0) takes the same values; explicit package names win over :all:. poetry add --allow-prereleases accepts pre-releases (src/poetry/console/commands/add.py). ↗
  • extra.latestVersion: Released on 2026-09-20. ↗
  • extra.directoryOptions: Global options: --directory=DIRECTORY (-C) "The working directory for the Poetry command (defaults to the current working directory). All command-line arguments will be resolved relative to the given directory."; --project=PROJECT (-P) "Specify another path as the project root. All command-line arguments will be resolved relative to the current working directory or directory specified using --directory option if used." The page names no environment variable for either. ↗
  • extra.registrySettings: [[tool.poetry.source]] has name, url and priority. "If priority is undefined, the source is considered a primary source"; "All primary package sources are searched for each dependency without a source constraint" and "If you configure at least one primary source, the implicit PyPI source is disabled", so a primary source replaces PyPI. Supplemental sources "are only searched if no other (higher-priority) source yields a compatible package distribution": depcurfew does not know whether PyPI has a version the constraint takes, so such a source counts as one that adds. Explicit sources "are only searched when a package configuration explicitly indicates" them: a dependency with source = "name" in [tool.poetry.dependencies] or [tool.poetry.group.<group>.dependencies], also in a list of constraint tables (docs/dependency-specification.md, docs/managing-dependencies.md). create_pool in src/poetry/factory.py reads Priority[source.get("priority", "primary").upper()], so the value is compared without regard to case; the schema (src/poetry/json/schemas/poetry.json) allows primary, supplemental and explicit, and another value (default or secondary of Poetry 1.x) fails in 2.5.1 and counts as primary here. A source whose name is pypi in any case is PyPI itself (PyPiRepository), which "cannot be configured with a custom url" (create_package_source). ↗
  • extra.configCommands: poetry config [options] [setting-key] [setting-value1] ... [setting-valueN] sets a key to a value (--local in poetry.toml of the project); --unset removes the key, --migrate migrates outdated settings and --list only shows them. "The source namespace groups subcommands to manage repository sources for a Poetry project": source add adds a source to pyproject.toml (also the priority of PyPI, with --priority), source remove removes one from it, and source show only shows them (docs/cli.md; src/poetry/console/commands/source/add.py and remove.py write pyproject.poetry_config["source"], and src/poetry/console/application.py lists source add, source remove and source show). The sources of pyproject.toml are where poetry add and poetry install take packages from (registrySettings). ↗
  • extra.installOverrides: Settings can be set with environment variables prefixed by POETRY_, the upper-case setting name with dots and dashes replaced by underscores; solver.min-release-age (int, days) is POETRY_SOLVER_MIN_RELEASE_AGE. poetry add has no option for it. ↗

PDM

  • cooldown.setting: In the [tool.pdm.resolution] table of pyproject.toml: distributions uploaded after the cutoff are left out when dependencies are resolved (pdm lock, add, update). The --exclude-newer option of pdm lock wins over it, and it wins over strategy.exclude-newer in the PDM configuration. ↗
  • cooldown.configFiles: The [tool.pdm.resolution] table. ↗
  • cooldown.cliFlag: pdm lock --exclude-newer, since 2.13.0. ↗
  • cooldown.unit: An RFC 3339 timestamp, a UTC date or a relative duration N{d|h|w} such as 7d, 12h or 3w, counted from the current UTC time. ↗
  • cooldown.availableSince: "Support exclude-newer in pyproject.toml in the [tool.pdm.resolution] table" (#3776); the pdm lock option exists since 2.13.0. ↗
  • cooldown.default: No default: without a value every upload time is accepted. ↗
  • cooldown.exclude.setting: A table [tool.pdm.resolution.exclude-newer-override] of package = false (no cutoff) or package = another date or duration; package-specific values win over the global cutoff. ↗
  • cooldown.exclude.availableSince: "Allow package-specific overrides for exclude-newer resolution limits" (#3809). ↗
  • installScripts.defaultPolicy: Without only-binary, PDM locks and installs source distributions when they fit, which builds them and runs their build backend. Installing a wheel runs no package code. ↗
  • installScripts.allowList.setting: The packages in no-binary are locked and installed from source distributions only. A name in no-binary wins over only-binary = ":all:" (FormatControl of unearth, which PDM uses), so with both the named packages are the only ones built, and always from source. ↗
  • installScripts.allowList.file: The [tool.pdm.resolution] table. ↗
  • installScripts.allowList.availableSince: no-binary, only-binary and prefer-binary keys in [tool.pdm.resolution] (#2656). ↗
  • installScripts.disableAll: only-binary = ":all:" locks and installs only wheels. The variables PDM_ONLY_BINARY and PDM_NO_BINARY win over pyproject.toml. ↗
  • project.lockfiles: pdm.lock next to pyproject.toml; pdm lock --lockfile writes another name. ↗
  • user.files: <CONFIG_ROOT> is "$XDG_CONFIG_HOME/pdm (~/.config/pdm in most cases) on Linux", "~/Library/Application Support/pdm on macOS" and "%USERPROFILE%\AppData\Local\pdm\pdm on Windows". The code agrees on Linux and Windows: global_config = platformdirs.user_config_path("pdm") / "config.toml", without an override (src/pdm/project/core.py; on Windows the default appauthor repeats the name and roaming is off, so platformdirs asks for the Local AppData known folder). On macOS the directory depends on the installed platformdirs (libraryDirectories); the docs' directory is used when its version cannot be read. The home configuration is TOML whose nested tables are read as dotted keys ([strategy] exclude-newer is strategy.exclude-newer, load_config in src/pdm/project/config.py). -c/--config and PDM_CONFIG_FILE replace it; the site configuration is merged below it. Checked at 2.29.5; earlier versions are not tracked. ↗
  • user.libraryDirectories: PDM 2.29.5 does not pin platformdirs (pyproject.toml; its own lock has 4.9.6). The macOS user_config_dir by platformdirs version, read from the code at the tags: before 4.6.0 always ~/Library/Application Support/<app> (4.5.1 macos.py has no XDG support); 4.6.0 "Honor XDG environment variables on macOS" (#375): a non-empty XDG_CONFIG_HOME wins, a relative one too (os.environ.get("XDG_CONFIG_HOME", "").strip() in _xdg.py), and otherwise the config directory is user_data_dir, so a non-empty XDG_DATA_HOME gives $XDG_DATA_HOME/<app>; 4.9.6 "Fix macOS XDG variables leaking across user_config_dir, user_data_dir, and user_state_dir" (#473; 4.9.4 still returns user_data_dir); 4.11.8 "Ignore relative paths in XDG Base Directory environment variables and use the existing platform fallback" (#540, _xdg_dir with posixpath.isabs); the same in 4.14.2. A relative value is used as it is, so the tool reads it from the directory each command runs in. ↗
  • user.settings: "Allow configuring the default lock --exclude-newer value with strategy.exclude-newer" (2.27.0, #3795): a TOML string such as "7d", a date or an RFC 3339 time. It applies where neither [tool.pdm.resolution] exclude-newer in pyproject.toml nor a project pdm.toml sets it (docs/usage/lockfile.md), and with it in effect pdm lock resolves every package again (src/pdm/cli/commands/lock.py). only-binary, no-binary and exclude-newer-override cannot be set in any PDM configuration file: PDM reads them from [tool.pdm.resolution] in pyproject.toml, only-binary and no-binary also from PDM_ONLY_BINARY and PDM_NO_BINARY (environments/base.py, Project.env_or_setting), so at user level they can be set only through those variables. ↗
  • user.weakening: use_uv (experimental since 2.19.0, PDM_USE_UV) can be set in config.toml and in a project pdm.toml, which wins. PDM passes the cutoff and the build settings to uv lock but not to uv sync --frozen (src/pdm/installers/uv.py), and passes no --no-config, so uv also reads the user uv.toml. A home strategy.exclude-newer cannot weaken a project that sets [tool.pdm.resolution] exclude-newer. use_uv is a switch that turns a protection off and is read with ensure_boolean (src/pdm/project/config.py at 2.29.5): a TOML boolean or number is kept, and a string is false only when empty or false, no or 0 in any case; depcurfew counts every other value as on (other spellings of false too, which errs towards a warning). ↗
  • user.variables: env_or_setting returns os.getenv(var) or the pyproject.toml setting, so a non-empty PDM_ONLY_BINARY or PDM_NO_BINARY wins (environments/base.py). -c/--config and PDM_CONFIG_FILE name the home config file (src/pdm/core.py). PDM_USE_UV is the variable of use_uv, and variables beat pdm.toml and config.toml (src/pdm/project/config.py). ↗
  • extra.environmentNames: A configuration item takes its value from its env_var (PDM_PYPI_URL and the others) with os.environ[item.env_var], and the options read PDM_PROJECT and the other variables with os.getenv("PDM_PROJECT") (src/pdm/cli/options.py), so only those spellings count (decision D-143). ↗
  • extra.pylockCreatedBy: PDM's pylock.toml export writes created-by = "pdm". ↗
  • extra.configTables: exclude-newer, its overrides, only-binary and no-binary share the table. ↗
  • extra.pyprojectTable: PDM keeps its settings in [tool.pdm] of pyproject.toml. ↗
  • extra.buildSwitch: only-binary in [tool.pdm.resolution] since 2.15.0 (#2656). It covers packages from an index: git, URL and path requirements already name their source and are built regardless (candidates.py). ↗
  • extra.durationStrings: "pdm lock --exclude-newer now accepts relative durations in the format N{d|h|w}" (#3760). ↗
  • extra.durationUnits: Written as Nh, Nd and Nw. ↗
  • extra.excludeWildcards: Override keys are package names. ↗
  • extra.excludeValue: package = false disables the cutoff for that package. ↗
  • extra.missingUploadTime: The index must give upload-time (PEP 700); an override of false lifts it for the package. ↗
  • extra.lockedSettings: pdm.lock keeps a content_hash of the whole [tool.pdm.resolution] table (PyProject.content_hash), or with canonical lock inputs (lock_inputs = true, since 2.28.1) the table itself (src/pdm/project/lockfile/freshness.py), so a change to any key in it, exclude-newer and only-binary included, makes the lockfile out of date. pdm lock --check and pdm install --check then exit with 1 ("Lockfile doesn't satisfy the project requirements"), pdm install without --check locks again first and pdm sync only warns (check_lockfile in src/pdm/cli/actions.py) until pdm lock runs again; with exclude-newer set, pdm lock resolves every package again (src/pdm/cli/commands/lock.py). ↗
  • extra.lockHash: PyProject.content_hash: json.dumps(dump_data, sort_keys=True) of sources (tool.pdm.source, default []), dependencies, dev-dependencies, optional-dependencies (default {}), requires-python (default "") and resolution (tool.pdm.resolution, default {}), encoded as UTF-8 and hashed with hashlib (sha256). dev-dependencies are the [dependency-groups] tables, each name normalized (normalize_name in src/pdm/utils.py: re.sub(r"[^A-Za-z0-9]+", "-", name).lower(); a name twice is an error), then the lists of tool.pdm.dev-dependencies appended under their normalized names. pdm.lock keeps it as [metadata] content_hash = "sha256:<hex>" (src/pdm/project/lockfile/pdmlock.py). Project.is_lockfile_fresh (src/pdm/project/core.py) compares it only while pdm.lock has no metadata.lock_inputs and resolution.lock_inputs is not true; a workspace root (tool.pdm.workspace set, WorkspaceManager.is_root in src/pdm/project/workspace.py) hashes the members too. PDM reads pyproject.toml with tomllib (src/pdm/project/toml_file.py), and without a [project] table it converts a Poetry or Flit project first (_convert_pyproject). ↗
  • extra.directoryOptions: project_option: "-p", "--project", dest="project_path", help "Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]", default=os.getenv("PDM_PROJECT"). ↗
  • extra.commandLine: pdm add takes requirements as arguments and editable ones with -e; its options come from cli/options.py and the global ones (-c/--config, --pep582, -I, -n, --no-cache) from core.py. --venv and --pep582 take an optional value, so argparse takes the next word for it. PDM parses with argparse, which accepts abbreviated long options. ↗
  • extra.registrySettings: [[tool.pdm.source]] has name, url, verify_ssl, type ("index or find_links, default to index") and include_packages and exclude_packages. "If you want to omit the default PyPI index, just set the source name to pypi and that source will replace it"; the source list is pypi.url (when no source is named pypi), then the sources of pyproject.toml, then pypi.<name>.url of the configuration, and by default "all sources are treated as equal" and the best matching version across them is taken, so any other source adds an index. Project.get_sources (src/pdm/project/core.py) keys the sources by name and fills a source named pypi from pypi.url, so one without a URL is PyPI (or the pypi.url of the user's configuration, which depcurfew does not read); PDM compares the name pypi exactly, depcurfew without regard to case, which only compares more URLs. Variables in url (${PROJECT_ROOT}) are expanded by PDM, so depcurfew cannot read such a URL. include_packages and exclude_packages are not read: a source counts for every package. ↗
  • extra.registryOverrides: pypi.url, the index PDM uses when pyproject.toml names no source called pypi, can be set with PDM_PYPI_URL (docs/usage/config.md); -c/--config and PDM_CONFIG_FILE name another configuration file, which may set any index. ↗
  • extra.configCommands: pdm config [-l|--local] [-d|--delete] [-e|--edit] [key] [value]: with a key and a value it sets the key (_set_config, in the home config.toml, with -l in the pdm.toml of the project), with -d it deletes the key, with -e it opens the file in an editor; a key alone shows its value, and without a key it lists the configuration. docs/usage/config.md sets the index this way: pdm config pypi.url "https://test.pypi.org/simple", pdm config --local pypi.url …, pdm config pypi.extra.url … for an extra index. PDM parses with argparse, which takes abbreviated long options and grouped short ones (commandLine). ↗
  • extra.selection: pdm add --pre/--prerelease allows pre-releases of the added packages to be pinned and --stable only stable versions (prerelease_option; commands/add.py sets req.prerelease). PDM_NO_BINARY and PDM_ONLY_BINARY are lists of packages separated by commas, :all: for every package, of which no wheel, or only wheels, are locked and installed (docs/usage/lockfile.md; environments/base.py, _setting_list). ↗
  • extra.latestVersion: Released on 2026-10-30. ↗

Pipenv

  • cooldown.setting: In the [pipenv] section of the Pipfile: the resolver considers only versions uploaded at least that many days ago. Pipenv computes a cutoff (now minus N days, UTC) and hands it to pip as uploaded-prior-to. ↗
  • cooldown.configFiles: The [pipenv] section. ↗
  • cooldown.unit: A string in <int>d format, e.g. "30d"; any other form is rejected (pipenv/vendor/plette/models/sections.py). ↗
  • cooldown.availableSince: "Added support for cool-down-period in the [pipenv] section of the Pipfile" under 2026.6.2 (repeated under 2026.7.0 and 2026.7.1). Checked against the wheels on 2026-10-30: missing in 2026.6.1, present in 2026.6.2. ↗
  • cooldown.default: Off unless set. ↗
  • installScripts.defaultPolicy: Pipenv installs with pip, which builds source distributions when no wheel fits. Pipenv honors pip configuration and PIP_* variables, which may forbid building (PIP_ONLY_BINARY=:all:), but the Pipfile has no setting for it. ↗
  • project.lockfiles: JSON, generated next to the Pipfile. ↗
  • project.manifests: TOML. ↗
  • user.files: Pipenv has no user configuration file of its own: it reads environment variables (set in a shell profile), the project .env file and pip configuration; pipenv/environments.py looks up no file. Since 2026.3.0 the pip install step runs with PIP_CONFIG_FILE=/dev/null (pipenv/utils/pip.py; CHANGELOG.md, #6066), so a user pip.conf no longer protects pipenv install and sync. The lock resolver still reads pip.conf, but only [global], because its pip command is named InstallCommand (pipenv/utils/resolver.py), and a Pipfile cool-down-period replaces its uploaded-prior-to. ↗
  • user.settings: No user file to write to; at user level only PIP_* variables reach the pip install step (see variables). ↗
  • user.unknownKeys: No user file. ↗
  • user.invalidValueFails: No user file. ↗
  • user.weakening: No user file; see variables. ↗
  • extra.environmentNames: get_from_env looks up f"{prefix}_{arg}" with the prefix PIPENV (PIPENV_PYPI_MIRROR, PIPENV_PIPFILE, PIPENV_DOTENV_LOCATION) through "positive_lookup in os.environ", that spelling only. PIP_NO_BINARY and PIP_ONLY_BINARY reach the pip Pipenv runs, which reads PIP_ variables with the prefix in upper case and the rest in any case (pip extra.environmentNames). Decision D-143. ↗
  • extra.pylockCreatedBy: Pipenv writes created-by = "pipenv" in the pylock.toml it generates (docs/pylock.md). pipenv install -e . writes the project itself as { path = ".", editable = true } (docs/pipfile.md), and Pipfile.lock keeps it as "path": ".". ↗
  • extra.configTables: Directives such as cool-down-period and allow_prereleases live in [pipenv]. ↗
  • extra.durationStrings: Only whole days (<int>d) are accepted. ↗
  • extra.durationUnits: Whole days only. ↗
  • extra.missingUploadTime: "When the index does not provide upload-time metadata (e.g. most private mirrors) the setting is accepted but has no filtering effect." ↗
  • extra.lockfileFormat: Every key but _meta is a category (default, develop and custom ones) mapping names to entries: index packages have version, hashes and index; git entries git and ref; remote archives file; local projects path, and editable = true for editable installs (Pipfile "Packages Section"). The version is written as a specifier ("version": "==1.2.3"). The hashes of wheels and source distributions are listed together, so the lockfile does not show which packages are built. ↗
  • extra.commandLine: pipenv install takes packages as arguments (without any it installs the Pipfile) and editable ones with -e; -r imports a requirements file. The options of install and the global flags of pipenv, read with argparse, which accepts abbreviated long options. ↗
  • extra.registryOverrides: --index names a package index by URL or by a source name of the Pipfile; --pypi-mirror and PIPENV_PYPI_MIRROR replace PyPI. --extra-pip-args hands arguments to pip, which may name another index, and Pipenv loads PIP_* variables from the .env file that PIPENV_DOTENV_LOCATION names (options.py). ↗
  • extra.directoryOptions: Pipfile.location returns project.s.PIPENV_PIPFILE when it is set, and only otherwise searches the working directory and its parents (find_pipfile, PIPENV_MAX_DEPTH); project_directory is str(Path(self.location).parent.absolute()), and Project.__init__ (pipenv/project.py) changes to it for every command but run. pipenv/environments.py: "If set, this specifies a custom Pipfile location. When running pipenv from a location other than the same directory where the Pipfile is located, instruct pipenv to find the Pipfile in the location specified by this environment variable"; the path is taken relative to the working directory and made absolute. pipenv/cli/options.py has no option that moves the project (--where only prints it). ↗
  • extra.registrySettings: Each [[source]] has name, url and verify_ssl. "all packages are mapped to a single package index for security reasons"; "To install a package from a specific index, you must match the name of the index" (torch = {version = "*", index = "pytorch"} in [packages]); to use another index as the default, "simply omit PyPI from your sources". A package without index comes from the default index, the first source: Resolver.create in pipenv/utils/resolver.py takes project.sources.get_default_index()["name"], which is pipfile_sources()[0] (pipenv/utils/sources.py), and without [[source]] the default is https://pypi.org/simple (pipenv/project.py). With install_search_all_sources = true in [pipenv], "pipenv install and pipenv sync will search all configured sources for packages, but only during installation", so every source adds. Names are compared exactly (get_index_by_name), depcurfew without regard to case; package categories are any top-level table ([packages], [dev-packages] and custom ones). Variables in url are expanded by Pipenv (expand_url_credentials), so depcurfew cannot read such a URL. ↗
  • extra.selection: pipenv install --pre allows pre-releases (and records allow_prereleases in the Pipfile, routines/install.py). Pipenv installs with pip, which reads PIP_NO_BINARY and PIP_ONLY_BINARY like --no-binary and --only-binary (see buildSwitch). ↗
  • extra.latestVersion: Released on 2026-10-28. ↗

Composer

  • cooldown.setting: Withholds versions published within the period when composer update or require resolves dependencies (also init and create-project when they pick a constraint). Measured from the publication time the repository reports (published-time, which Packagist.org provides and package authors cannot influence); a Composer repository that lacks it makes the command fail unless require-published-time is false on it, and packages from VCS, path or artifact repositories use the author-set time of their composer.json. Never withheld: dev versions, locked packages a partial update keeps, platform packages and versions without any date. ↗
  • cooldown.configFiles: config is root-only: "It is only used for projects." COMPOSER_HOME/config.json is merged under it (only its config and repositories keys), and "the local configuration in the project's composer.json always wins" (03-cli.md#composer-home-config-json). ↗
  • cooldown.unit: "A duration string in the form "<number> <unit>" where the unit is one of second, minute, hour, day or week (lowercase, singular or plural - e.g. "7 days", "24 hours", "30 minutes", "1 week"), an integer number of seconds, or null to disable." ↗
  • cooldown.availableSince: "Added a cooldown policy to withhold newly released package versions for a configurable period" under 2.11.0-RC1 (2026-10-22); 2.11.0 was released on 2026-10-29. ↗
  • cooldown.default: "Defaults to null (no cooldown period). The policy only takes effect once a period is set." ↗
  • cooldown.exclude.setting: "Packages listed under ignore bypass the cooldown policy." The ignore format of the other policies: a list of names, or an object of names to a reason, to { constraint, reason, on-block, on-audit } or to a list of such rules. ↗
  • cooldown.exclude.availableSince: Part of the cooldown policy added in 2.11.0-RC1. ↗
  • cooldown.exclude.patternSyntax: "package names support wildcards (e.g. vendor/*)". ↗
  • installScripts.defaultPolicy: Only the root package's scripts run (articles/scripts.md: "If a dependency of the root package specifies its own scripts, Composer does not execute those additional scripts"); dependency code runs during Composer commands through plugins, packages of type composer-plugin. allow-plugins (2.2.0) "Defaults to {} which does not allow any plugins to be loaded": a plugin it does not list makes Composer ask in an interactive run and fail in a non-interactive one, or skips it when the plugin declares plugin-optional (PluginManager::isPluginAllowed, articles/plugins.md). ↗
  • installScripts.allowList.setting: "Use this setting to allow only packages you trust to execute code." ↗
  • installScripts.allowList.file: Root-only, like every config option. ↗
  • installScripts.allowList.availableSince: "As of Composer 2.2.0, the allow-plugins option adds a layer of security". ↗
  • installScripts.allowList.format: parseAllowedPlugins turns each key into a pattern; isPluginAllowed returns the value of the first pattern that matches, in the order written. Config::merge puts the keys of COMPOSER_HOME/config.json after the project's, the project's values winning. ↗
  • installScripts.disableAll: "You can also set the config option itself to false to disallow all plugins"; --no-plugins does the same for one command (03-cli.md#global-options). ↗
  • project.lockfiles: JSON next to composer.json. With COMPOSER=<name>.json Composer reads another manifest and writes <name>.lock (03-cli.md#composer); depcurfew reads composer.json and composer.lock only. ↗
  • project.manifests: The root package; repositories, config and scripts are read only from it. ↗
  • extra.environmentNames: Platform::getEnv looks the name up with array_key_exists($name, $_SERVER), then in $_ENV, then with getenv($name), so outside Windows only that spelling counts: COMPOSER and COMPOSER_HOME, not Composer or composer (decision D-143). ↗
  • extra.latestVersion: Released on 2026-10-30. ↗
  • extra.durationStrings: parseDuration: an integer, or a string of digits (/^\d+$/D), is a number of seconds; otherwise only /^(\d+)\s*(second|minute|hour|day|week)s?$/D is accepted (lowercase, one unit). The string is matched as it is, so a space before or after the value (" 14 days") is not accepted. null, "", 0 and "0" mean no cooldown; any other value makes the command fail with "Invalid policy.cooldown.period format", and so does such a COMPOSER_POLICY_COOLDOWN_PERIOD. ↗
  • extra.durationUnits: The documented examples are "7 days", "24 hours", "30 minutes" and "1 week"; depcurfew writes whole days, rounded up. ↗
  • extra.excludeWildcards: "package names support wildcards (e.g. vendor/*)" in ignore. ↗
  • extra.denyList: "The values are true to allow and false to disallow while suppressing further warnings and prompts." ↗
  • extra.cooldownTime: getEffectiveDate returns the published date, else the release date (time). A Composer repository must give published-time while a cooldown is configured, unless require-published-time is false on it (05-repositories.md#require-published-time: "That field is set by the package author, so the protection is weaker"); ArtifactRepository drops a published-time from the archive's composer.json. ↗
  • extra.lockedVersions: "The cooldown policy applies when resolving dependencies during composer update/require"; "Locked packages that are not being updated" are never withheld. ↗
  • extra.contentHash: getContentHash hashes name, version, require, require-dev, conflict, replace, provide, minimum-stability, prefer-stable, repositories, extra, config.platform and config.policy ("policy changes which versions an update may pick, so changing it should flag the lock as outdated"; CHANGELOG 2.11.0-RC1, #13149). With another hash composer install warns that "The lock file is not up to date with the latest changes in composer.json" (Installer.php) and composer validate fails (03-cli.md#validate); composer update --lock "Overwrites the lock file hash to suppress warning about the lock file being out of date without updating package versions" (03-cli.md#update-u-upgrade). allow-plugins is not hashed. Locker::getContentHash at 2.10.3 hashes config.platform but not config.policy, so a hash written by Composer 2.10 or older differs from what 2.11 computes for a composer.json with config.policy (https://github.com/composer/composer/blob/2.10.3/src/Composer/Package/Locker.php). ↗
  • extra.pluginApiVersion: Locker writes PluginInterface::PLUGIN_API_VERSION of the Composer that writes composer.lock into plugin-api-version (Locker.php; CHANGELOG 1.10.0: "so third-party tools can know which Composer version was used to generate a lock file"). It is 2.11.0 at 2.11.1 ("Bumped composer-plugin-api to 2.11.0" under 2.11.0-RC1) and 2.9.0 at 2.10.3, so a lower value was written by a Composer older than 2.11.0. It names the Composer that last wrote the lock, not every Composer that installs it. ↗
  • extra.lockfileFormat: Each entry of packages and packages-dev has name, version, type and the source { type, url, reference } and dist { type, url, reference, shasum } it installs from, time and, from a repository that gives it, published-time. A package of a path repository has dist type path with the path as url (PathRepository.php); one of an artifact repository has the archive type and its file path as url (ArtifactRepository.php). Composer reads name and type in lower case (BasePackage::__construct and ArrayLoader::configureObject: strtolower), so "Composer-Plugin" is a plugin too. Plugins are packages of type composer-plugin (04-schema.md#type), and Composer also loads the legacy type composer-installer as a plugin, under the same allow-plugins check (PluginInstaller::supports, PluginManager::registerPackage). A plugin whose extra.plugin-optional is true is skipped without a question when Composer runs without a terminal and it is not allowed (PluginManager::isPluginAllowed: elseif ($optional) return false). ↗
  • extra.legacyLockPlugins: parseAllowedPlugins returns no rules when allow-plugins is empty ({} or missing) and composer.lock has a plugin-api-version below 2.2.0, or none (Locker::getPluginApi returns 1.1.0 then). In that mode Composer 2.2 to 2.9 load every plugin without asking when run without a terminal ("if no config is defined we allow all plugins for BC", PluginManager.php at 2.9.8); since 2.10.0-RC1 Composer stops with an error there instead ("Enforce allow-plugins even in non-interactive mode for very old pre-2.2 lock files", #12764 in CHANGELOG.md) and asks in a terminal. ↗
  • extra.manifestSyntax: JsonFile::parseJson at 2.11.1 reads composer.json with PHP's json_decode($json, true) and, when it fails, reports the error with JsonFile::validateSyntax (seld/jsonlint), so a comment or a trailing comma in composer.json stops every Composer command; json_decode takes strict JSON (RFC 8259), which has neither. ↗
  • extra.sourceInstall: getAvailableSources offers source when the package has a source type and dist when it has a dist type; a locked package without a dist is installed from its source, a checkout of the VCS repository the entry names, whatever repository composer.json declares. ↗
  • extra.registryDistHosts: The archives Composer's VCS drivers give a package of the hosts Composer knows by default (github-domains github.com, gitlab-domains gitlab.com, forgejo-domains codeberg.org in Config.php, and Bitbucket): GitHubDriver::getDist https://api.github.com/repos/<owner>/<repo>/zipball/<ref>, GitLabDriver::getDist <scheme>://gitlab.com/api/v4/projects/<id>/repository/archive.zip, GitBitbucketDriver::getDist https://bitbucket.org/<owner>/<repo>/get/<ref>.zip, ForgejoDriver::getDist <host>/api/v1/repos/<owner>/<repo>/archive/<ref>.zip; GitDriver::getDist gives none. ↗
  • extra.repositoryArchiveHosts: The hosts the archives of a Composer repository other than Packagist.org come from, by the host of the repository URL. WPackagist (the Composer repository https://wpackagist.org that its README tells composer.json to declare) gives each plugin version the dist https://downloads.wordpress.org/plugin/<name>.<version>.zip (Plugin::getDownloadUrl) and each theme version https://downloads.wordpress.org/theme/<name>.<version>.zip (Theme::getDownloadUrl in src/Entity/Theme.php), with a dist of type zip and a source of type svn on plugins.svn.wordpress.org or themes.svn.wordpress.org (Package::getPackageVersion in src/Entity/Package.php), all at commit 9b5db4a of the develop branch (the repository has no tags). The archive host of packages.drupal.org could not be read at its source (drupal.org is not reachable from where this was checked), so it is not listed. ↗
  • extra.branchVersions: A locked version names a branch, not a release, when it starts with dev- or ends with -dev: "Composer automatically adds a -dev suffix to all numeric branches and prefixes all other branches imported from a VCS repository with dev-" (versions.md, Stabilities); a tag gives its own version (v7.3.4 or 3.9.0, as the tag is written). ↗
  • extra.repositoryTypes: The repository classes of createRepositoryManager; 05-repositories.md describes composer, vcs (with the drivers bitbucket, github, gitlab, perforce, fossil, git, svn and hg; git-bitbucket is deprecated), path, package and artifact, and { "packagist.org": false } to disable Packagist.org. repositories is root-only. ↗
  • extra.weakeningSettings: "Set to false to disable all dependency policy enforcement"; malware "block: Defaults to true", "block-scope: Defaults to all", update blocks "only during update/require/remove"; cooldown block "Set to false to skip blocking for a cooldown period entirely". policy, cooldown and malware are compared with false exactly; block is read with PHP's (bool) cast after ?? true, so false, 0, "", "0" and [] turn blocking off, while a missing or null block keeps the default and "false" is true (Config.php, MalwarePolicyConfig.php, CooldownPolicyConfig.php). ↗
  • extra.transportSettings: secure-http "Defaults to true. If set to true only HTTPS URLs are allowed to be downloaded via Composer"; disable-tls "Defaults to false. If set to true all HTTPS URLs will be tried with HTTP instead" and "will implicitly disable the secure-http option". Config::get reads both as $value !== "false" && (bool) $value (Config.php), so "false", false, 0, "", "0" and null are false. ↗
  • extra.allowAllPlugins: "or true to allow all plugins to run (NOT recommended)". BasePackage::packageNameToRegexp turns a key into {^...$}i with * as .*, so keys match without regard to case and * matches / too: a key made only of * with at most one / between them ("*", "*/*") with true allows every vendor/name plugin that no earlier key names. ↗
  • extra.repositoryWeakening: require-published-time "Defaults to true"; false falls "back to the time field of each package's composer.json. That field is set by the package author, so the protection is weaker." Only false counts (ComposerRepository.php). "Set filter: false to opt out of every list this repository advertises", or an object that sets a list name to false to skip that list (#filter); Packagist.org advertises the list malware (repo.packagist.org/packages.json). ↗
  • extra.environmentOverrides: COMPOSER_POLICY: "Set to 0 to disable all dependency policy enforcement" (read with Platform::getBoolEnv: 0, false and off are false). COMPOSER_NO_BLOCKING and COMPOSER_NO_SECURITY_BLOCKING: BaseCommand::createPolicyConfig reads both with Platform::getBoolEnv(..., false), which takes only 0, 1, false, true, off and on and makes update, require, install, remove and create-project stop with "Invalid value for COMPOSER_NO_BLOCKING" for any other value but ""; 1, true and on turn blocking off there (PolicyConfig::withBlockingDisabled: advisories, malware, abandoned packages, the cooldown and custom lists). BaseCommand::initialize also sets --no-blocking and --no-security-blocking when (bool) getenv() is true, so false and off turn blocking off as well for the commands that have the option (update, require, install, remove, create-project). COMPOSER_POLICY_COOLDOWN_PERIOD "overrides the configured period", 0 disabling it; COMPOSER_POLICY_COOLDOWN_BLOCK and COMPOSER_POLICY_MALWARE_BLOCK set 0 to disable blocking (PolicyConfig.php). ↗
  • extra.packagistApi: "Using the Composer v2 metadata": GET https://repo.packagist.org/p2/[vendor]/[package].json gives {"packages": {"[vendor]/[package]": [versions]}, "minified": "composer/2.0"}, each version with version, "time": [release datetime, as set by the package author] and "published-time": [datetime the version was published on packagist.org, not influenced by the package author]; the list "requires you to use Composer\MetadataMinifier\MetadataMinifier::expand"; "The p2/$vendor/$package.json file contains only tagged releases", branches are in p2/$vendor/$package~dev.json; package pages are https://packagist.org/packages/[vendor]/[package]. https://repo.packagist.org is the url of the packagist.org repository Composer adds by default (Config::$defaultRepositories at 2.11.1). Composer reads a 404 as a package the repository does not have (ComposerRepository.php), expands a list marked composer/2.0 and loads each version with ArrayLoader.php: version_normalized (else the version normalized), type (lowercased, library when missing), time, published-time (an integer or a non-empty string) and abandoned (true or the name of a replacement). ↗
  • extra.metadataMinifier: MetadataMinifier::expand: the first entry is a whole version; each later entry holds only the keys that changed since the previous version, a key with the value "__unset" being removed; while the version built so far is empty (PHP: !$expandedVersion), the next entry is taken whole again. Composer 2.11.1 locks composer/metadata-minifier 1.0.1. ↗
  • extra.versionConstraints: Exact version (1.0.2); ranges with >, >=, <, <=, != separated by a space or comma (logical AND) or || (logical OR, and | for backwards compatibility), AND binding tighter; the hyphenated range 1.0 - 2.0 (>=1.0.0 <2.1, a partial right end completed with a wildcard); wildcard 1.0.* (>=1.0 <1.1); ~1.2 (>=1.2 <2.0.0), ~1.2.3 (>=1.2.3 <1.3.0), ~1 like ~1.0; ^1.2.3 (>=1.2.3 <2.0.0), ^0.3 (>=0.3.0 <0.4.0), ^0.0.3 (>=0.0.3 <0.0.4); stability flags @<stability>; a branch as dev-<branch>, or <version>.x-dev for a branch named like a version (versions.md). composer/semver 3.6.0 (src/VersionParser.php, which Composer 2.11.1 locks, https://github.com/composer/semver/blob/3.6.0/src/VersionParser.php) also reads = and == as exact, <> as !=, x, X and * as wildcards, "<version> as <alias>", #<commit> after a branch, and appends -dev to the bound of < and >= without an explicit stability, so that pre-releases of the bound are below it. ↗
  • extra.stabilities: minimum-stability "defaults to stable"; the options in order of stability are dev, alpha, beta, RC and stable, and stability flags allow another stability per package. BasePackage::STABILITIES at 2.11.1 gives the priorities (stable 0 to dev 20); StabilityFilter::isPackageAcceptable accepts a version whose stability priority is at most the flag of its package, else at most the minimum stability. RootPackageLoader::extractStabilityFlags takes the least stable @<stability> of a requirement as its flag, else the stability of an explicit unstable version in it (2.0.0-beta1) when that is less stable than the minimum stability. VersionParser::parseStability (composer/semver 3.6.0): a version starting with dev- or ending with -dev is dev; a modifier beta or b is beta, alpha or a is alpha, RC is RC (in any case), anything else (patch, pl, p, none) is stable. Versions without a stability suffix are stable (articles/versions.md#stabilities). ↗
  • extra.versionComparison: Composer orders normalized versions with PHP's version_compare (VersionSelector.php at 2.11.1; Constraint::versionCompare in composer/semver 3.6.0, where a dev- branch only equals itself). php_canonicalize_version replaces -, _ and + with a dot and puts a dot between a digit and a non-digit; the parts are compared one by one, numbers as numbers, words by the first special form they start with (dev < alpha = a < beta = b < RC = rc < # < pl = p; a word that starts with none is lowest), a number against a word as the form # (#N#); when one version has parts left, a number makes it the greater and a word is compared with #N#. ↗
  • extra.commandLine: composer require (alias r) takes packages as "vendor/package:2.*" or vendor/package2:dev-master, and picks a constraint itself for a package without one; composer global <command> runs the command "as if you were running them from the COMPOSER_HOME directory"; composer create-project <package> [<directory>] [<version>]; composer update (u, upgrade) takes packages, wildcards and constraints vendor/package:2.0.1, and --with foo/bar:1.0.0. "As Composer uses symfony/console you can call commands by short name if it's not ambiguous" (commandNames). The options with a value of require, update, create-project, install, config and repository (InputOption VALUE_REQUIRED or VALUE_OPTIONAL in src/Composer/Command/*Command.php at 2.11.1) and the global --working-dir (-d) of src/Composer/Console/Application.php; symfony/console v5.4.55 (Input/ArgvInput.php) groups short options (-nd dir), takes a value attached (-ddir, --working-dir=dir) or the next word when it does not start with -, accepts options before and after the command, reads every word after -- as an argument and does not shorten long options. ↗
  • extra.commandNames: Application::find: an exact command name or alias; otherwise every name and alias that starts with the word (for each part between colons, a name with more parts too), first with case and then without (ASCII letters only, PCRE without u), of which one must match the word whole; an alias is left out when the name of its command is in the list, a hidden command (_complete) when others remain; one name is run, more are ambiguous (an error) and none is not defined. The names and aliases are those of Composer's getDefaultCommands (src/Composer/Console/Application.php at 2.11.1, setName and setAliases in each src/Composer/Command/*Command.php) and of symfony/console (help, list, completion and the hidden _complete). Scripts of composer.json (extra.scriptCommands) and commands of plugins are added as commands too, unless a command of that name exists. ↗
  • extra.commandArguments: parseNameVersionPairs: an argument is split at the first =, : or space after the name; an argument without one takes the next argument as its constraint when that has no /, no * next to a letter, digit, _, / or - and is no platform package. require and create-project read their packages so (RequireCommand via PackageDiscoveryTrait, CreateProjectCommand::installRootPackage); update moves an argument with a constraint (\S+[ =:]\S+) to the temporary constraints of --with and takes lock, nothing and mirrors as --lock (UpdateCommand.php). create-project takes its stability from --stability (-s), else from the @<stability> of its version, else from the version itself. Platform packages are PlatformRepository::PLATFORM_PACKAGE_REGEX (case-insensitive). The name pattern is the one 04-schema.md#name gives (ValidatingArrayLoader::hasPackageNamingError checks the same with possessive quantifiers); Composer lowercases the names it looks up. Both are written here as patterns of the same names whose repeated group starts with its separator (X+(?:[sep]X+)*, decision D-136), so that a long name that fails at its end is read in linear time: X(?:[sep]?X+)* can split a run of letters in exponentially many ways. ↗
  • extra.registryOverrides: create-project --repository "Provide a custom repository to search for the package, which will be used instead of packagist" (and --repository-url, CreateProjectCommand.php at 2.11.1). COMPOSER sets the file name of composer.json, whose repositories then apply (#composer). COMPOSER_HOME sets the home directory (Factory::getHomeDir: "if ($home = Platform::getEnv('COMPOSER_HOME')) return $home"), whose config.json Factory::createConfig merges under the configuration of every project, its repositories included (03-cli.md#composer-home-config-json), and in which composer global runs, with the composer.json there (GlobalCommand::prepareSubcommandInput changes to the home directory of the configuration). Other commands take their repositories from composer.json only. ↗
  • extra.installOverrides: createPolicyConfig: --no-blocking, --no-security-blocking (deprecated), COMPOSER_NO_BLOCKING and COMPOSER_NO_SECURITY_BLOCKING "disable ALL blocking (advisories + malware + abandoned + cooldown + custom)" (PolicyConfig::withBlockingDisabled); --no-cooldown disables only the cooldown blocking. initialize sets --no-blocking and --no-security-blocking on each command that has them when (bool) getenv() is true, so for every value but "" and "0" ("false" and "off" too); createPolicyConfig also reads both with Platform::getBoolEnv, which makes the command fail for a value other than 0, 1, false, true, off and on (src/Composer/Util/Platform.php), so such a value installs nothing. COMPOSER_POLICY (Config::get), COMPOSER_POLICY_COOLDOWN_BLOCK and COMPOSER_POLICY_MALWARE_BLOCK (PolicyConfig::fromConfig) are read with getBoolEnv: 0, false and off turn them off. COMPOSER_POLICY_COOLDOWN_PERIOD replaces the period (CooldownPolicyConfig::getEnvPeriod, in the syntax of durationStrings). create-project --no-secure-http "Disable the secure-http config option temporarily while installing the root package" (03-cli.md#create-project): CreateProjectCommand::installRootPackage merges secure-http false into the configuration it installs the project package with, and secure-http "Defaults to true. If set to true only HTTPS URLs are allowed to be downloaded via Composer" (06-config.md#secure-http). The options are on require, update, install, create-project and remove (03-cli.md). ↗
  • extra.configCommands: composer config [options] [setting-key] [setting-value1] ... changes a setting of composer.json (with --global, -g, of COMPOSER_HOME/config.json; with --file, -f, of that file), --unset removes one and --editor (-e) opens the file; with a key alone it shows the value (src/Composer/Command/ConfigCommand.php at 2.11.1). composer repository (repo) add, remove (rm, delete), set-url (seturl), enable and disable change the repositories, list (ls, show) and get-url (geturl) only read them (RepositoryCommand.php). composer policy add-source changes config.policy (PolicyCommand.php). config, repository and policy all take --global (-g, "Apply command to the global config file") and --file (-f, "If you want to choose a different composer.json or config.json"). The same commands after composer global change the files of COMPOSER_HOME: GlobalCommand runs them in the home directory, where composer.json is the one of composer global and config.json the configuration that Factory::createConfig merges under that of every project. depcurfew reads neither file (decision D-133), so a change there counts also without an install next to it (unread). ↗
  • extra.applicationOptions: Composer finds the command name before it knows the command (getCommandNameBeforeBinding: "This ensures we can find the correct command name even if a global input option is present before it"): it binds the words to the input definition of the application, ignoring the error that stops the binding (an option it does not define, a missing value, a second argument), and takes $input->getFirstArgument(). The definition is that of symfony/console (Application::getDefaultInputDefinition at v5.4.55: the command argument, --help -h, --quiet -q, --verbose -v|vv|vvv, --version -V, --ansi|--no-ansi, --no-interaction -n) with the --profile, --no-plugins, --no-scripts, --working-dir -d (with a value) and --no-cache of Composer. ArgvInput::getFirstArgument (v5.4.55) passes over each word that starts with -, and also over the next word when the option is one the binding set (a long name, or the last letter of a short one) and that word equals its bound value; the first other word is the command. So only -d and --working-dir take the word after them before the command, an option of a command (--ignore-platform-req) does not, and that command later binds the word after it as its value (Input/ArgvInput.php: parse, addLongOption, parseShortOptionSet). ↗
  • extra.scriptCommands: doRunComposer registers the scripts of the composer.json it runs with (Factory::getComposerFile, after -d) as commands when the command word is not the exact name of a command Composer found before (mayNeedScriptCommand: "$rawCommandName !== $commandName", so also for an alias, an abbreviation, another case or a word that names no command) or the command is run-script. Each key of scripts that is no event (the constants of src/Composer/Script/ScriptEvents.php, compared in upper case with - as _) and not already a command or alias ($this->has($script): "A script named ... would override a Composer command and has been skipped") becomes a ScriptAliasCommand with the aliases that scripts-aliases gives it. Application::add of symfony/console (v5.4.55) maps the name and each alias to it, over an alias or name of another command; Command::setName and setAliases reject a name that is not parts without a colon separated by single colons (validateName), and ScriptAliasCommand an alias that is not a string, which stops Composer. find() then resolves the word among all of them: the exact name or alias, else the names that start with it. ScriptAliasCommand runs the script as composer run-script does (src/Composer/Command/ScriptAliasCommand.php). ↗
  • extra.scriptAliases: 2.7.0: "Added `scripts-aliases` top level key in composer.json to define aliases for custom scripts you defined" (#11666). Application::doRunComposer at 2.6.6 and 2.2.25 (src/Composer/Console/Application.php) registers each script of composer.json as a ScriptAliasCommand without aliases ($this->add(new Command\ScriptAliasCommand($script, $description))), and from 2.7.0 with $composer['scripts-aliases'][$script]. So on Composer 2.2 LTS to 2.6 a word that scripts-aliases gives a script is still the Composer command or alias of that name (r is require). ↗
  • extra.rootStability: RootPackageLoader reads minimum-stability of the root composer.json through VersionParser::normalizeStability (composer/semver 3.6.0: lower case, one of stable, RC, beta, alpha and dev, else an exception) and prefer-stable as (bool) $config['prefer-stable']. composer require without a constraint takes the minimum stability of composer.json (PackageDiscoveryTrait::getMinimumStability) for the versions it considers and asks VersionSelector::findBestCandidate for a version with the preferred stability "stable" under prefer-stable, else the minimum stability (RequireCommand.php): versions at least that stable come first, the highest of them, else the most stable of the others. The solver orders the versions a constraint allows with DefaultPolicy::versionCompare: with prefer-stable the more stable one first, else the higher version, which a branch (dev-main aliased 3.x-dev) is. All at 2.11.1 (src/Composer/Package/Version/VersionSelector.php, src/Composer/DependencyResolver/DefaultPolicy.php, src/Composer/Command/PackageDiscoveryTrait.php). ↗
  • extra.installPreference: DownloadManager::getAvailableSources offers source before dist (each only with a type) and reverses them "in case dist is the preferred source for this package": unless preferSource, when preferDist or resolvePackageInstallPreference says dist. BaseCommand::getPreferredInstallOptions sets preferSource for config.preferred-install "source" and preferDist for "dist" (Config::$defaultConfig has "dist"), and neither for "auto", another string or an object; Factory::createDownloadManager hands an object to setPreferences. resolvePackageInstallPreference takes the first key that matches the package name ({^pattern$}i with * as .*): "dist", or "auto" for a version that is not dev, gives dist, any other value source; with no match, source for a dev version (a branch) and dist for others. Config::merge turns the default "dist" into {"*": "dist"} under an object of composer.json and moves the "*" key to the end. --prefer-source, --prefer-dist and --prefer-install override it for one command. All at 2.11.1 (src/Composer/Command/BaseCommand.php, src/Composer/Factory.php, src/Composer/Config.php). ↗
  • extra.sourceFallback: 2.10.0: "Disabled automatic fallback to source checkout if dist/zip install fails, we have introduced a new source-fallback config option as a temporary way to restore the old behavior" (#12885); 2.11.0-RC1: "Removed the source-fallback config option which was added in 2.10 as a temporary measure, dist installs no longer fall back to source" (#13050). DownloadManager::download at 2.11.1 only falls back from source to dist ("Only fallback from dist to source is risky as it can silently switch to less-trusted code"). Composer before 2.10.0 installs a package from its source when the download of its archive fails. ↗
  • extra.registrySourceHosts: The host of the source that the VCS driver gives a package whose archive comes from a host of registryDistHosts: GitHubDriver::getSource https://github.com/<owner>/<repo>.git (git@github.com:<owner>/<repo>.git for a private repository) beside its archive on api.github.com; GitLabDriver::getSource the http_url_to_repo or ssh_url_to_repo of the project on gitlab.com; GitBitbucketDriver::getSource the URL of the repository on bitbucket.org; ForgejoDriver::getSource its clone URL on codeberg.org (src/Composer/Repository/Vcs/*Driver.php at 2.11.1). ↗
  • extra.sourceHostAliases: GitHubDriver::initialize at 2.11.1 reads the host of the repository URL in lower case and takes www.github.com for github.com ("if ($this->originUrl === 'www.github.com') { $this->originUrl = 'github.com'; }"), and GitHubDriver::supports compares the host without www. with github-domains. GitLabDriver::determineOrigin compares the host (with its port) with gitlab-domains as written, GitBitbucketDriver::supports takes only https://bitbucket.org/…, and ForgejoDriver compares the host with forgejo-domains as written (src/Composer/Repository/Vcs/*Driver.php at 2.11.1), so only GitHub has such a host. ↗
  • extra.directoryOptions: "--working-dir (-d): If specified, use the given directory as working directory." Application::doRunComposer changes to it before it reads composer.json (src/Composer/Console/Application.php at 2.11.1). Without it and without composer.json in the current directory (and for a command other than list, init, about, help, diagnose, self-update, global, create-project and outdated), Composer looks for the nearest parent with one, stopping before the home directory and the root of the file system: an interactive run asks whether to use it, use-parent-dir true uses it without asking, and a run without a terminal (stdin not a TTY, or COMPOSER_NO_INTERACTION) with the default use-parent-dir "prompt" (Config::$defaultConfig in src/Composer/Config.php) stays in the current directory and only says so; with --working-dir it never looks at a parent. It then registers the scripts (Application.php) and reads minimum-stability (PackageDiscoveryTrait::getMinimumStability) of Factory::getComposerFile() in the directory it is in. getNewWorkingDir reads the directory with $input->getParameterOption(['--working-dir', '-d'], null, true), which in symfony/console v5.4.55 (Input/ArgvInput.php) takes the first word, up to --, that is --working-dir or -d (then the next word) or starts with --working-dir= or -d (then the rest of the word); a grouped -nd dir does not start with -d, so Composer stays where it is, although the command later binds -n and -d dir as options. ↗

Renovate

  • cooldown.setting: Formerly stabilityDays; old configs are migrated to "N days". Can be scoped with packageRules, vulnerabilityAlerts and update types. ↗
  • cooldown.configFiles: Searched in this order. The "renovate" key in package.json still works but is deprecated. Shared presets (extends) can also set it. ↗
  • cooldown.cliFlag: Self-hosted CLI only; environment variable RENOVATE_MINIMUM_RELEASE_AGE. ↗
  • cooldown.unit: For example "3 days" or "14 days". Since 42.19.5 "0 days" is treated like null. ↗
  • cooldown.availableSince: Earlier versions had the same feature as stabilityDays (first version not tracked). ↗
  • cooldown.default: Off unless configured; the docs table shows no default. config:best-practices adds "3 days" for npm (see presets). Since 44.96.0 minimumReleaseAgeBuffer adds 30 minutes once a delay is set. ↗
  • cooldown.exclude.setting: No dedicated exclusion list. ↗
  • cooldown.exclude.patternSyntax: Glob and regex patterns since 38.0.0. ↗
  • cooldown.securityUpdates: The vulnerabilityAlerts defaults set minimumReleaseAge to null; a delay can still be set inside vulnerabilityAlerts. ↗
  • installScripts.defaultPolicy: Renovate disables package manager scripts when it updates lockfiles; the Mend-hosted app never runs them. ↗
  • installScripts.disableAll: The default; the self-hosted global allowScripts also defaults to false. ↗
  • extra.configLocation: detectConfigFile looks for each name in configFiles (lib/config/app-strings.ts) in the file list of the repository, whose paths start at the repository root, so a renovate.json in a subdirectory is never read. The configuration options page (docs/usage/configuration-options.md at 44.198.2): "Any config you define applies to the whole repository (e.g. if you have a monorepo)" and "Renovate always uses the config from the repository's default branch". ↗
  • extra.durationStrings: Values such as "3 days" or "1 hour", parsed by toMs (lib/util/pretty-time.ts). ↗
  • extra.minimumReleaseAgePresets: config:best-practices extends security:minimumReleaseAgeNpm, which sets minimumReleaseAge "3 days" for the npm datasource (see presets). ↗
  • extra.excludeRule: The documented opt-out: a packageRules entry with matchPackageNames and minimumReleaseAge: null. ↗
  • extra.securityUpdatesSetting: The vulnerabilityAlerts default sets minimumReleaseAge to null, so security updates skip the delay unless a value is set there. ↗
  • extra.excludeWildcards: matchPackageNames accepts globs (and regex) since 38.0.0. ↗
  • extra.ruleDescription: A human-readable description allowed inside any configuration object; depcurfew uses it to recognize the packageRules entry it manages. ↗
  • extra.packageJsonConfig: Deprecated: the configuration options page warns that support may be removed, and Renovate logs that using package.json is deprecated. ↗
  • extra.durationUnits: Units shown in the docs: minimumReleaseAge=1 hour on this page and "3 days" in the configuration options. The value is parsed by toMs (lib/util/pretty-time.ts), whose tests also accept 1 day, 1 week and combined values. ↗
  • extra.datasources: Datasource ids for matchDatasources: npm packages come from the npm datasource and Python packages from pypi, whose release timestamp is the earliest upload_time of the version's files. Composer packages come from packagist, the datasource of the composer manager (static readonly id = 'packagist' in lib/modules/datasource/packagist/index.ts and supportedDatasources in lib/modules/manager/composer/index.ts at 44.199.2, read 2026-11-02). ↗
  • extra.packagistReleaseTime: The release timestamp of a Composer version is composerRelease['published-time'] ?? composerRelease.time: Packagist's publication date, the author-set time only when it is missing. The releaseTimestampNote of lib/modules/datasource/packagist/index.ts at the same tag still says "determined from the time field". ↗
  • extra.negativeMatch: Patterns starting with ! are negative matches, and none of them may match; matchDatasources is matched this way (matchRegexOrGlobList in lib/util/package-rules/datasources.ts at 44.198.0), so ["!pypi"] covers every datasource but PyPI. ↗
  • extra.packageRuleMatching: A packageRules entry applies to a dependency when all of its matchers match. Within one matcher, at least one positive pattern must match when there are any, and no negative pattern (starting with !) may match, so a list of only negative patterns matches every name it does not exclude (docs/usage/string-pattern-matching.md and matchRegexOrGlobList in lib/util/string-match.ts). matchPackageNames, matchDepNames, matchDatasources and matchUpdateTypes all match this way; "*" alone matches everything. ↗
  • extra.packageRulesOrder: All packageRules are evaluated and later rules override options set by earlier ones; a matching rule overrides the top-level configuration ("Package rule config overrides any existing config", lib/util/package-rules/index.ts). Presets in extends are merged before the repository configuration, and packageRules is mergeable, so the rules of presets come first and the repository's rules after them, while a top-level option of the repository replaces the same option of a preset (resolveConfigPresets in lib/config/presets/index.ts and mergeChildConfig in lib/config/utils.ts). ↗
  • extra.delayedUpdateTypes: The update types that take minimumReleaseAge into account; digest and pinDigest only for some datasources, and pin, lockFileMaintenance, lockfileUpdate, rollback, bump and replacement not at all. ↗
  • extra.internalPresets: The built-in preset groups; a default preset is written :name or default:name. Other presets (github>, gitlab>, local>, npm packages and so on) are fetched from elsewhere. Among the built-in presets only the security:minimumReleaseAge* presets set minimumReleaseAge, each in a packageRules entry with matchDatasources for its datasource, and config:best-practices extends security:minimumReleaseAgeNpm (security.preset.ts and config.preset.ts in the same directory). ↗
  • extra.pypiPresets: Added in 44.8.0; config:best-practices does not include it (it includes only security:minimumReleaseAgeNpm). ↗
  • extra.pythonManagers: pep621 updates pyproject.toml with uv.lock (there is no uv manager) or pdm.lock; poetry updates pyproject.toml with poetry.lock; pipenv updates the Pipfile with Pipfile.lock; pip_requirements updates requirements files. pip-compile is off by default (lib/modules/manager/pep621/readme.md and pipenv/index.ts at 44.198.1). ↗
  • extra.managers: The Renovate manager that updates the packages of each tool, by its id in api.ts; github-actions updates the actions the workflows run. The npm manager reads package.json with package-lock.json, pnpm-lock.yaml or yarn.lock (lockFileNames in npm/index.ts). bun and deno have managers of their own that take a package.json over from npm (supersedesManagers in bun/index.ts and deno/index.ts, applied by lib/workers/repository/extract/supersedes.ts), and poetry takes pyproject.toml over from pep621, which updates it for uv and PDM. composer updates composer.json (composer/index.ts). ↗
  • extra.managerCategories: getManagerConfig gives each dependency the categories its manager exports (categories in lib/modules/manager/<id>/index.ts; the list of categories is lib/constants/category.ts), and matchCategories matches them. ↗
  • extra.managerMatching: matchManagers matches the manager id of a dependency like matchRegexOrGlobList (case-insensitive globs, /regex/ and ! for "not"), a custom manager as custom.<name>; matchCategories matches when any category of the dependency matches (anyMatchRegexOrGlobList in lib/util/package-rules/categories.ts). The configuration options page says matchCategories uses "any" logic and is applied after extraction (docs/usage/configuration-options.md). These two, matchPackageNames, matchDepNames, matchDatasources and matchUpdateTypes all have allowString in lib/config/options/index.ts, and massageConfig (lib/config/massage.ts) turns such a string into a list of one. ↗
  • extra.githubActions: An action pinned to a ref that looks like a version (v4, v4.2.0, also as a comment after a commit SHA) is looked up in the github-tags datasource, which gives major, minor and patch updates; another ref (main, a feature tag) goes to github-digest, which gives digest updates only (readme.md in the same directory). getManagerConfig (lib/config/index.ts) starts every manager from the whole configuration, so the top-level minimumReleaseAge applies to github-actions as to the other managers; no built-in preset sets a delay for it (lib/config/presets/internal/security.preset.ts). ↗
  • extra.actionsMatching: matchFileNames matches the packageFile of a dependency, the path of the file from the repository root (and its lockFiles, which the github-actions manager does not set: "Deliberately no lockFiles" in lib/modules/manager/github-actions/extract.ts), like matchRegexOrGlobList; a glob goes to minimatch with { dot: true, nocase: true } (getRegexOrGlobPredicate in lib/util/string-match.ts), so * stays within one directory and ** spans directories. matchFileNames takes no string for a list (no allowString in lib/config/options/index.ts); matchDepTypes does (allowString) and matches the depType like matchRegexOrGlobList (lib/util/package-rules/dep-types.ts). The github-actions manager gives the depType action to a repository action in a uses: field (actions/checkout@v4), and workflow, docker, container, service, github-runner and uses-with to the other things it updates (lib/modules/manager/github-actions/dep-types.ts, extract.ts). ↗
  • extra.actionsTimestamps: github-tags reads committedDate of the commit a lightweight tag points to, or tagger.date of an annotated tag, and takes the publishedAt of a GitHub release of the same version when it is newer (lib/modules/datasource/github-tags/index.ts); github-digest takes the commit date (lib/modules/datasource/github-digest/index.ts). Both are dates from git that the person who makes the commit or the tag sets: the minimum release age page (docs/usage/key-concepts/minimum-release-age.md) says github-tags "uses the committedDate, which is separate from when it was pushed", and that a digest update of a tag moved to new commits ages against the original release date, so it may pass at once. Since 42.0.0 an update without a timestamp waits (missingTimestamp). ↗
  • extra.passesDelayToManager: Since 44.34.0 Renovate passes POETRY_SOLVER_MIN_RELEASE_AGE (rounded up to whole days) to Poetry 2.4.0 and later. It does not pass the delay to uv or read exclude-newer. ↗
  • extra.missingTimestamp: minimumReleaseAgeBehaviour was added in 41.150.0; timestamp-optional still fails open. ↗
  • extra.independentOfPackageManager: Source code passes --before to npm only; pnpm, Yarn and Bun gates are not read. ↗

Dependabot

  • cooldown.setting: Per updates entry: default-days, semver-major-days, semver-minor-days, semver-patch-days, include, exclude. The semver-* keys apply only to SemVer ecosystems. ↗
  • cooldown.configFiles: On the default branch. ↗
  • cooldown.unit: Integer days; the allowed range is disputed (see dayRange). ↗
  • cooldown.availableSince: GA date on github.com; NuGet and Helm since 2025-07-29. ↗
  • cooldown.default: Version updates wait 3 days even without a cooldown block (GHES from 3.23); default-days is also 3 when cooldown is set without it. ↗
  • cooldown.securityUpdates: Cooldown exists only for version updates. dependabot-core also passes a zero age to npm, pnpm and Yarn for security updates, overriding repository gates. ↗
  • installScripts.allowList.setting: insecure-external-code-execution: allow exists only for bundler, mix and pip; nothing allows npm, pnpm, Yarn or Bun scripts. ↗
  • extra.configLocation: "You must store this file in the .github directory of your repository in the default branch (typically main), at .github/dependabot.yml or .github/dependabot.yaml" (github/docs, content/code-security/concepts/supply-chain-security/about-the-dependabot-yml-file.md, read 2026-11-01), so a .github/dependabot.yml in a subdirectory is not read. ↗
  • extra.directories: Required in each updates entry: directory for one directory of manifests, directories for a list; "Define directories relative to the root of the repository for most package managers"; "The directories key supports globbing and the wildcard character *. These features are not supported by the directory key." How a glob matches is not described further (github/docs, content/code-security/reference/supply-chain-security/dependabot-options-reference.md, read 2026-11-01). ↗
  • extra.cooldownKeys: Keys inside the cooldown block of an updates entry; the semver-* keys override default-days for that kind of update. ↗
  • extra.excludeWildcards: cooldown.exclude accepts * wildcards. ↗
  • extra.excludeMatching: ReleaseCooldownOptions#excluded? at v0.402.0 skips the cooldown for a dependency when any exclude pattern matches its name with File.fnmatch?(pattern, dependency_name), and included? matches include the same way, both without flags. Without File::FNM_PATHNAME a * matches / as well ("File.fnmatch('c*t', 'c/a/b/t') #=> true" in the documentation of File.fnmatch, dir.rb of Ruby 3.4.7, https://github.com/ruby/ruby/blob/v3_4_7/dir.rb), and without File::FNM_CASEFOLD case counts, so "*/*" matches every Composer package (vendor/name) and every scoped npm package. ↗
  • extra.cooldownInclude: An include list in the cooldown block limits the cooldown to the dependencies it names (* wildcards, up to 150 entries): the example applies the cooldown to requests, numpy and names starting with pandas or django, and to cover all dependencies one omits include or uses "*". The other dependencies get no cooldown at all, not even the default 3 days: dependabot-core skips the cooldown for a dependency that the include list does not match (ReleaseCooldownOptions#included? with File.fnmatch? and CooldownCalculation.skip_cooldown? in common/lib/dependabot, commit 03892a3e8ee26d43eb96f31c5136c98a85d63b14). exclude wins over include. ↗
  • extra.ecosystems: The npm ecosystem covers npm, pnpm and Yarn; bun needs Bun 1.1.39 or later and deno needs Deno 2. pip covers pip, pip-compile, pipenv and Poetry (v2); uv has its own ecosystem (the table lists uv v0.11). composer covers Composer v2. Cooldown, including the semver-* keys, is supported for all of them (the cooldown table of the same page lists Composer with default and SemVer-bump days, read 2026-11-02). PDM is not listed: dependabot-core skips the dependencies of pyproject.toml when pdm.lock exists (python/lib/dependabot/python/file_parser/pyproject_files_parser.rb at v0.402.0). ↗
  • extra.yamlAliases: Dependabot::Config::File.parse loads dependabot.yml with YAML.safe_load(config, symbolize_names: true); Psych.safe_load takes aliases: false unless told otherwise and raises Psych::AliasesNotEnabled on an alias (*name), so a file with one is not read. The issue that asks for aliases (https://github.com/dependabot/dependabot-core/issues/1582, "YAML aliases", open and labelled Keep on 2026-11-02) quotes the error users get, "YAML aliases are not supported"; the pull request that would allow them (#9653) is open and not merged. The reference of dependabot.yml (dependabot-options-reference.md in github/docs) does not mention anchors or aliases. An anchor (&name) that no alias refers to changes nothing. ↗
  • extra.yamlScalars: Dependabot::Config::File.parse loads dependabot.yml with YAML.safe_load (dependabot-core v0.402.0, common/lib/dependabot/config/file.rb), which is Psych: Ruby 4.0.5 (.ruby-version) with psych 5.5.0 (Gemfile.lock of dependabot-core at v0.402.0). ScalarScanner#tokenize reads a plain scalar in this order: words, booleans (yes, no, on, off, true, false) and null; times and dates; .inf and .nan; :symbols; base 60 integers [-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}, summed as part * 60 ** (index - 2).abs, so 1:30 is 5400; floats with a dot; then INTEGER_LEGACY, the default without strict_integer: 0b binary, 0 followed by octal digits, decimal without a leading zero, 0x hex, each with _ and , allowed, read with Integer(string.delete(',_')), so 010 is 8, 1_0 and 1,0 are 10; anything else, 0o12 and 08 too, is a string. ↗
  • extra.githubActions: package-ecosystem github-actions updates the actions the workflows run: with directory / Dependabot "will search the /.github/workflows directory, as well as the action.yml/action.yaml file from the root directory". The cooldown table lists GitHub Actions with default-days supported and the semver-major-days, semver-minor-days and semver-patch-days keys not supported, and the default cooldown of 3 days covers version updates without a cooldown block (github/docs, content/code-security/reference/supply-chain-security/dependabot-options-reference.md, main on 2026-11-02). ↗
  • extra.maximumDays: The page says the number of cooldown days must be between 1 and 90; whether 0 is accepted is disputed (see dayRange). ↗
  • extra.composerReleaseTime: For composer, the cooldown compares the release date with released_at, which parse_release takes from the time field of each version in the Packagist metadata: the date the package author sets, not published-time, the date Packagist received the version. Seen on 2026-11-02: intercom/intercom-php 5.0.2 has time 2026-01-30 and published-time 2026-04-30 (repo.packagist.org/p2/intercom/intercom-php.json). The updater runs Composer 2.10.3 (ARG COMPOSER_V2_VERSION in composer/Dockerfile at v0.402.0), which has no cooldown policy of its own. ↗
  • extra.composerContentHash: post_process_lockfile calls replace_content_hash, which writes the hash get_content_hash returns: composer/helpers/v2/src/Hasher.php calls Locker::getContentHash of the composer/composer library the helper installs from its composer.lock (2.10.3 at v0.402.0). That method at 2.10.3 does not hash config.policy (src/Composer/Package/Locker.php at 2.10.3), while Composer 2.11 does, so with config.policy in composer.json every composer.lock Dependabot writes has a content-hash Composer 2.11 reads as out of date: composer install warns and composer validate fails until composer update --lock. ↗

Environment

  • corepack.packageManagerField: Format name@x.y.z, optionally followed by +<hash algorithm>.<hash>; a URL to a .js or .tgz file is also allowed. setup-bun also reads bun@x from this key. ↗
  • corepack.devEnginesSince: Limited support at first; since 0.36.0 Corepack uses the devEngines.packageManager range when packageManager is missing. ↗
  • corepack.envFileSince: Corepack reads COREPACK_* keys from .corepack.env; since 0.36.0 only the closest file. COREPACK_ENV_FILE=0 turns it off. ↗
  • corepack.bundledWithNode: Node.js 25.0.0 stopped distributing Corepack; the Corepack README says it ships with Node.js from 14.19.0 up to (but not including) 25.0.0. ↗
  • corepack.package: Its published bin field (publishConfig.bin) declares yarn (./dist/yarn.js), yarnpkg, pnpm and pnpx next to corepack. corepack enable links them from the folder of the corepack executable (a relative symlink to dist/<name>.js on Linux and macOS, a cmd-shim on Windows; sources/commands/Enable.ts), so the package.json behind a yarn or pnpm shim is Corepack's, which says nothing about the version the shim runs. ↗
  • corepack.toolPackages: The npm packages Corepack installs each package manager from: npm; pnpm; yarn below 2.0.0 (Yarn Classic) and, with COREPACK_NPM_REGISTRY, @yarnpkg/cli-dist for Yarn 2 and later ("npmRegistry": { "package": "@yarnpkg/cli-dist", "bin": "bin/yarn.js" }). npm i -g @yarnpkg/cli-dist installs the same package, whose package.json declares bin yarn and carries the Yarn version (observed for 4.18.1). ↗
  • corepack.enableNpm: corepack enable [... name] creates shims for the package managers it is given, or for all of them without parameters: "Note that the npm shims will not be installed unless explicitly requested, as npm is currently distributed with Node.js through other means". So corepack enable npm makes npm the version Corepack picks (packageManager), while a bare corepack enable leaves the bundled npm. ↗
  • corepack.manualInstall: How to Install: "Corepack is distributed with Node.js from version 14.19.0 up to (but not including) 25.0.0. Run `corepack enable` to install the required Yarn and pnpm binaries on your path." Manual Installs, "Install Corepack using npm": "npm install -g corepack". The Node.js 25.0.0 changelog lists "build: stop distributing Corepack" (#57617) among its semver-major commits (https://github.com/nodejs/node/blob/main/doc/changelogs/CHANGELOG_V25.md), and the node images of 25 and later extract the release tarball unchanged (docker.nodeImage), so they have no Corepack either. ↗
  • installScriptPackages.esbuild: npm/esbuild/package.json at v0.28.2 declares "postinstall": "node install.js" and one optionalDependencies entry per platform (@esbuild/linux-x64 and the others, version 0.28.2). generateBinPath in lib/npm/node-platform.ts, which the JavaScript API and bin/esbuild run, first resolves the binary from that optional package ("First check for the binary package from our optionalDependencies"), so esbuild works without its install script. lib/npm/node-install.ts (the install script) only replaces bin/esbuild with the binary ("This optimization also doesn't apply when npm's --ignore-scripts flag is used since in that case this install script will not be run"; not on Windows, with Yarn or WASM), checks the version of the binary, and downloads the platform package when it is missing ("This can happen if you use the --no-optional flag"). Without both, esbuild fails: "maybe someone installed esbuild with both the --no-optional and the --ignore-scripts flags. The fix for this is to just not do that", with the error "make sure that you don't specify the --no-optional or --omit=optional flags". ↗
  • installScriptPackages.fsevents: The package.json of fsevents 2.3.3 declares no install script and lists "files": ["fsevents.d.ts", "fsevents.js", "fsevents.node"], so the published package contains the built module that fsevents.js loads (require("./fsevents.node")); the published tarball holds exactly LICENSE, README.md, package.json, fsevents.js, fsevents.d.ts and fsevents.node (listed on 2026-11-02, nothing run). The repository has a binding.gyp at that tag, and npm adds an install script to such a package when it is published: "If there is a binding.gyp file in the root of your package and you haven't defined your own install or preinstall scripts, npm will default the install command to compile using node-gyp via node-gyp rebuild" (https://github.com/npm/cli/blob/v12.2.1/docs/lib/content/using-npm/scripts.md). That is the install: node-gyp rebuild of the registry metadata and the hasInstallScript of lockfiles; the tarball has no binding.gyp to build from. ↗
  • installScriptPackages.lefthook: postinstall.js runs the lefthook executable with install in INIT_CWD (the directory the install was started in), and does nothing when CI is set and LEFTHOOK is not ("if (isEnabled(process.env.CI) && !isEnabled(process.env.LEFTHOOK)) return"). get-exe.js resolves the executable from lefthook-<os>-<arch>/bin/lefthook, one of the optionalDependencies of packaging/registries/npm/lefthook/package.json (version 2.2.2), whose only script is "postinstall": "node postinstall.js". docs/usage/commands/install.md: lefthook install "Installs configured hooks to Git hooks"; "NPM package lefthook installs the hooks in a postinstall script automatically. For projects not using NPM package run lefthook install after cloning the repo." and "Reinstall is not required when you modify lefthook.yml, the configuration file is read every time a git hook is run." docs/usage/envs/LEFTHOOK.md: "When using NPM package lefthook in CI, and your CI sets CI=true automatically, use LEFTHOOK=1 or LEFTHOOK=true to install hooks in the postinstall script", so by default no hooks are installed in CI. postinstall.js catches every error and does not look at the exit code of lefthook install, so it never fails the install. The legacy package @evilmartians/lefthook-installer fetches the executable when it is installed (docs/installation/node.md), so its script is needed; it is not this entry. ↗
  • node.bundledNpm: The npm field of every release in index.json (fetched on 2026-11-01, sha256 6b27fe5766e87929d16ccdde05c516cbdd12200eab62b28d4b2f31d34e21481a), as the first release of each line that bundles each npm version; latest is the newest release of the line that day. Lines are the major version from 4 on and the minor version before (0.6 to 0.12, as Node.js numbered them then). The bundled npm never goes down within a line. Releases before 0.6.3 (0.1.14 to 0.5.10 and 0.6.0 to 0.6.2) have no npm field: they came without npm. Every release before 18.0.0 bundles npm 8.19.4 or earlier (16.20.2 has npm 8.19.4), so none of them has min-release-age, allowScripts or strict-allow-scripts. 27.0.0-alpha.0.0.0 (npm 12.1.0) is a prerelease and left out: no release bundles npm 12 yet, Node.js 22 stays on npm 10.9.x, 24 reaches npm 11.10 or later only from 24.14.1 (npm 11.10.x was skipped) and 25 ends at npm 11.12.1. ↗
  • node.releaseSchedule: start, lts and end of each line from 4 on, codenames in lower case as nvm and the node image tags write them. After end a line gets no more releases, security fixes included; the README says "Production applications should only use Active LTS or Maintenance LTS releases". From Node.js 27 every line first goes through an alpha phase (27 has "alpha": "2026-10-28" and no codename yet) and every line becomes LTS. ↗
  • node.nvmrc: The file must contain precisely one version followed by a newline; # starts a comment, and comments, blank lines and leading and trailing white space are ignored. node is the latest version and stable an alias for it; lts/* is the latest LTS and lts/<codename> the LTS releases of that line; the file may hold "any other string that nvm understands". nvm use looks for the file from the current directory upwards. lts/-n is not in the README but in nvm.sh at the same commit (https://github.com/nvm-sh/nvm/blob/5e38bc0caed342356ffd26eb21e0e9b995ac228b/nvm.sh, read 2026-11-01): nvm_normalize_lts, which nvm_alias calls for every alias (so also for the version of .nvmrc), matches "lts/-[123456789] | lts/-[123456789][0123456789]*", takes N from after the -, adds 1 and picks the N-th last entry of the lts alias directory, whose entries are the LTS codenames (alphabetical, which is release order) after *; so lts/-1 is the LTS line before the newest one, as in setup-node. When nothing matches it says "That many LTS releases do not exist yet." ↗
  • node.nodeVersionFile: nodenv uses the version in .node-version of the project directory. fnm reads .node-version and .nvmrc and writes the file with node --version, so a leading v occurs (github.com/Schniz/fnm/blob/07f13237ae208f531f8ea88d4cfde3160c22f99a/README.md); setup-node reads it through node-version-file. ↗
  • node.engines: engines.node is the range of Node.js versions the package works on. Unless engine-strict is set, it is advisory and only produces warnings when the package is installed as a dependency; it does not choose the Node.js that runs. setup-node reads it from package.json through node-version-file when volta.node and devEngines.runtime are missing, and picks the newest version that matches. ↗
  • node.inheritedVersionFiles: nvm: "nvm use et. al. will traverse directory structure upwards from the current directory looking for the .nvmrc file". nodenv: find_local_version_file in libexec/nodenv-version-file checks the directory for .node-version and then each parent up to the root (https://github.com/nodenv/nodenv/blob/5083e9819756c1a127a626a874703349f4ddb2e4/libexec/nodenv-version-file). asdf: the tool versions a .tool-versions file declares "will be used in that directory and any subdirectories" (https://github.com/asdf-vm/asdf/blob/master/docs/manage/configuration.md). Volta is not one of them: for_dir in crates/volta-core/src/project/mod.rs "will search ancestors to find a package.json and use that as the root of the project" and reads a parent package.json only through extends (https://github.com/volta-cli/volta/blob/main/crates/volta-core/src/project/mod.rs), so the volta key of the root package.json does not reach a project with a package.json of its own. ↗
  • docker.imageReference: splitDockerDomain canonicalizes ubuntu and docker.io/ubuntu as docker.io/library/ubuntu, and the legacy domain index.docker.io as docker.io. A reference without a tag means latest (docs/reference/commandline/image_tag.md in github.com/docker/cli at 8c8a77521af82b08bf3499cafb4c0e2e7b024936: "If the namespace is omitted, Docker defaults to library, the namespace reserved for Docker Official Images"). registry-1.docker.io is Docker Hub's registry itself: "DefaultRegistryHost is the hostname for the default (Docker Hub) registry used for pushing and pulling images", DefaultRegistryHost = "registry-1.docker.io" (https://github.com/moby/moby/blob/9aa9edfa787e08bb2da31694cd8a402876f32232/daemon/pkg/registry/config.go), so registry-1.docker.io/library/node is the same official image. ↗
  • docker.syntax: Instructions are not case-sensitive. A line that begins with # is a comment unless it is a parser directive; comment lines are removed also inside a continued instruction. Parser directives (syntax, escape, check; keys not case-sensitive) must come first: after a comment, an empty line or an instruction none is read. The escape character (\ by default, or `) at the end of a line continues the instruction; escaping is not performed in RUN except at the end of a line. ARG is the only instruction allowed before FROM, and FROM reads ARGs declared before the first FROM ($VAR, ${VAR}, ${VAR:-word}, ${VAR-word}, ${VAR:+word}, ${VAR+word}); --build-arg can change them. FROM [--platform=<platform>] <image>[:<tag>][@<digest>] [AS <name>]; a later FROM <name> starts from that stage. A here-document (RUN <<EOF) makes the following lines part of the instruction, up to the line with only the delimiter. Only RUN, COPY and ADD in shell form take here-documents, and only a whole word starts one: the parser splits the line into words with quotes kept (shlex.RawQuotes) and matches each word against ^(\d*)<<(-?)\s*([^<]*)$, so a quoted "a <<b" starts none (heredocsFromLine and reHeredoc in frontend/dockerfile/parser/parser.go at the same commit). ↗
  • docker.copySources: COPY and ADD without --from: "When copying source files from the build context, paths are interpreted as relative to the root of the context. Specifying a source path with a leading slash or one that navigates outside the build context, such as COPY ../something /something, automatically removes any parent directory navigation (../). Trailing slashes in the source path are also disregarded, making COPY something/ /something equivalent to COPY something /something." The ADD section says the same about ADD ../something. So /frontend/x, ../frontend/x and frontend/x are the same file, and frontend/.. is the root of the context. ↗
  • docker.environment: ENV <key>=<value> [<key>=<value>...]: "This value will be in the environment for all subsequent instructions in the build stage", and "A stage inherits any environment variables that were set using ENV by its parent stage or any ancestor". "Like command line parsing, quotes and backslashes can be used to include spaces within values". The alternative "ENV <key> <value>, omitting the =" sets one variable, and is discouraged. RUN commands see these variables, and ENV wins over an ARG of the same name. ↗
  • docker.dockerfileNames: "The default filename to use for a Dockerfile is Dockerfile, without a file extension." "A common convention is to name these <something>.Dockerfile", passed with --file. ↗
  • docker.containerfile: "A Containerfile uses the same syntax as a Dockerfile internally"; Buildah and Podman read Containerfile or Dockerfile. Docker does not read Containerfile by default. ↗
  • docker.nodeImage: The image downloads the official tarball of the release and extracts it unchanged; its only npm command is npm --version, and docs/BestPractices.md tells users to add RUN npm install --global npm@<version> to change npm. So node:<version> has exactly the npm that release bundles. The Alpine images extract the -musl tarball or build from source. Tags (stackbrew.js): X.Y.Z, X.Y, X and <codename>, each also with -<variant>, and -alpine and -slim for the default variants; the variants are those of versions.json, plus alpine and slim. Yarn 1 is in the images up to Node.js 25. ↗
  • docker.pythonImage: "our policy is now to use the pip version that is installed during the Python build (which is the version bundled in ensurepip), and to not support overriding it": Dockerfile-linux.template configures CPython --with-ensurepip and installs no other pip (only setuptools and wheel for 3.11). So python:<version> has the pip that CPython release bundles. Images built before 2024-09-07 installed pip with get-pip.py, at the version ensurepip had. Tags (generate-stackbrew-library.sh): X.Y.Z and X.Y, each with -<variant>; -slim and -alpine mean the default suite. ↗
  • devEngines: Each entry is an object or a list of objects with name (required), version and onFail (warn, error by default, or ignore). Corepack and the setup actions read it too. ↗
  • devEnginesSince: npm version that introduced devEngines. ↗
  • volta.manifest: Also extends: a path to another JSON file with a volta key. pnpm support is experimental and needs VOLTA_FEATURE_PNPM=1. ↗
  • volta.maintained: The README says Volta is unmaintained and recommends migrating to mise. ↗
  • asdf.toolVersionsFile: One tool per line followed by one or more versions separated by spaces (fallbacks); # starts a comment. ↗
  • asdf.plugins: Short names in the asdf plugin index; there is no plugin named node. python, uv and poetry checked on 2026-10-30 (danhper/asdf-python, asdf-community/asdf-uv, asdf-community/asdf-poetry). ↗
  • githubActions.jobId: Read from the page source in github/docs (data/reusables/actions/jobs/section-using-jobs-in-a-workflow-id.md, main on 2026-11-02): "You must replace <job_id> with a string that is unique to the jobs object. The <job_id> must start with a letter or _ and contain only alphanumeric characters, -, or _." The runner checks names the same way with ASCII letters and digits (NameValidation.IsValid in src/Sdk/DTPipelines/Pipelines/Validation/NameValidation.cs of actions/runner, main on 2026-11-02: a-z, A-Z, _ anywhere, digits and, with hyphens allowed, - after the first character). ↗
  • githubActions.setupNode: Current major v7. node-version-file reads package.json, .nvmrc, .node-version, .tool-versions or mise.toml; node-version wins when both are set. ↗
  • githubActions.setupNodeVersions: Tag v7.1.0. node-version takes semver (22, 24.8.0, >=10.15.0, 12.x), the NVM LTS syntax (lts/jod, lts/*, lts/-n) and latest, current, node or * for the latest release. A matching version in the runner's tool cache is used first, so a major version such as 24 may give an older release of the line unless check-latest is set. ↗
  • githubActions.setupNodeVersionFile: node-version-file accepts .nvmrc, .node-version, .tool-versions, mise.toml or package.json, relative to GITHUB_WORKSPACE. In package.json it checks volta.node, then the devEngines.runtime entry named node, then engines.node, then volta.extends. getNodeVersionFromFile in src/util.ts tries JSON, then TOML tools.node, then the first line that matches the pattern, then the whole text trimmed. ↗
  • githubActions.jobContainer: Read from the page source in github/docs (data/reusables/actions/jobs/section-running-jobs-in-a-container.md and section-running-jobs-in-a-container-image.md, main on 2026-11-01): "Use jobs.<job_id>.container to create a container to run any steps in a job that don't already specify a container"; "If you do not set a container, all steps will run directly on the host specified by runs-on"; "When you only specify a container image, you can omit the image keyword" (container: node:18); jobs.<job_id>.container.image is "the Docker image to use as the container to run the action", and container.env sets variables in the container. So the run steps of such a job use the Node.js and npm of that image, until a setup step installs another. ↗
  • githubActions.environmentKeys: Read from the page source in github/docs (content/actions/reference/workflows-and-actions/workflow-syntax.md and data/reusables/repositories/actions-env-var-note.md, main on 2026-11-01): env is "A map of variables that are available to the steps of all jobs in the workflow", jobs.<job_id>.env "A map of variables that are available to all steps in the job", and jobs.<job_id>.steps[*].env "Sets variables for steps to use in the runner environment"; for the same name GitHub "uses the most specific variable": the step's over the job's over the workflow's. ↗
  • githubActions.yamlAliases: Read from the page source in github/docs (content/actions/reference/workflows-and-actions/reusing-workflow-configurations.md, commit 23809bf of main on 2026-11-02), for GitHub.com and GitHub Enterprise Cloud: "You can use YAML anchors and aliases to reduce repetition in your workflows. An anchor (marked with &) identifies a piece of content that you want to reuse, while an alias (marked with *) repeats that content in another location." Its examples reuse the env map of a job (env: *env_vars) and a whole job (alt-test: *base_job), and say that this "is equivalent to writing the following YAML without anchors and aliases". The page does not mention merge keys (<<), so depcurfew does not apply them in workflows. ↗
  • githubActions.pnpmActionSetup: Current major v6. Without version the action reads devEngines.packageManager or packageManager from package.json (package_json_file). ↗
  • githubActions.pnpmSetup: For pnpm 11 and later. Without version it reads devEngines.packageManager or packageManager; runtime takes <name>@<version> for node, bun or deno. ↗
  • githubActions.setupBun: Current major v2. Without bun-version it reads packageManager (bun@x), then engines.bun, then installs latest. ↗
  • githubActions.setupDeno: Current major v2. deno-version defaults to 2.x; deno-version-file reads .dvmrc or .tool-versions. ↗
  • githubActions.setupPython: Current version v7.1.0. Without python-version it reads .python-version; python-version wins over python-version-file. pip-version (major[.minor][.patch], CPython only) since v6.0.0. Python comes with pip, but the step alone does not show that pip installs the project. ↗
  • githubActions.setupUv: Current version v10.3.3, with no moving v10 tag. Without version or version-file it reads required-version from uv.toml, then pyproject.toml, in the working directory, and installs the latest uv when neither has one. ↗
  • githubActions.installPoetry: A third-party action (current v1.4.2); version defaults to latest, so without it the Poetry version is not pinned. ↗
  • githubActions.actionsPoetry: A third-party action (current v4.0.0); poetry-version defaults to latest. ↗
  • githubActions.codeScanningUpload: The example workflow on this page needs security-events: write in every repository and actions: read with contents: read only in private ones. The inputs come from upload-sarif/action.yml in github/codeql-action (current major v4, v4.39.1 checked); category tells analyses of the same tool and commit apart. ↗
  • githubActions.stopCommands: Lines between the two are logged without being processed as workflow commands. The token must be randomly generated and unique for each run. Read from the page source in github/docs. ↗
  • githubActions.annotations: escapeData and escapeProperty in @actions/core: the message and property values replace %, CR and LF; property values also replace : and , because properties are separated by commas. The commands and their file, line and title parameters are on https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands (line counts from 1). ↗
  • githubActions.annotationLimits: 10 error, 10 warning and 10 notice annotations per step; 50 annotations per job, summed over all steps. Annotations over the limit are not shown. ↗
  • githubActions.checkRuns: Read from the sources of this page (#create-a-check-run, #update-a-check-run, #list-check-runs-for-a-git-reference), the REST description github/rest-api-description (descriptions/api.github.com/api.github.com.json, commit f9ed74230d54847b5ca00a1343e8e349e858b8fb) and github/docs (commit 33b1f4a6fec2d9b6fd3d374afa56bcd9f0875b57); content/rest/checks/runs.md is generated from the REST description. POST /repos/{owner}/{repo}/check-runs ("Create a check run") needs name and head_sha and takes external_id, "A reference for the run on the integrator's system"; PATCH /repos/{owner}/{repo}/check-runs/{check_run_id} ("Update a check run") takes the same fields but head_sha, with only summary required in output, and "OAuth apps and personal access tokens (classic) cannot use this endpoint"; GET /repos/{owner}/{repo}/commits/{ref}/check-runs ("List check runs for a Git reference", ref a SHA, heads/BRANCH or tags/TAG) takes check_name ("Returns check runs with the specified name"), filter (latest, the default, or all: "latest returns the most recent check runs"), per_page (at most 100) and app_id, and answers {total_count, check_runs}, each with id, name, external_id (nullable), app (with slug, not required) and output.annotations_count. Fine-grained permissions (src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json in github/docs): the list needs Checks read, update and create need Checks write; "write includes read" (github-token-scope-descriptions.md). output.annotations: "maxItems": 50 per request, "To create more than 50 annotations, you have to make multiple requests to the Update a check run endpoint. Each time you update the check run, annotations are appended"; each annotation requires path, start_line, end_line (lines start at 1), annotation_level (notice, warning or failure) and message ("The maximum size is 64 KB"), with an optional title ("The maximum size is 255 characters"). No total per check run is documented; the same description says "GitHub Actions are limited to 10 warning annotations and 10 error annotations per step" without saying whether that binds check runs created through the API (uncertain). Not documented either: whether only the app that created a run may update it, and the app slug of runs created with the workflow token. A check suite holds the runs of one GitHub App for one commit (using-the-rest-api-to-interact-with-checks.md), and GitHub keeps at most 1000 runs of the same name per suite. status completed needs a conclusion (success, neutral, failure and others); output.title and output.summary (Markdown, maxLength 65535) show in the Checks tab; only GitHub Apps can create check runs, which the workflow token is. checks: write "permits an action to create a check run" (data/reusables/actions/github-token-scope-descriptions.md in github/docs, which links the permissions with apiVersion=2022-11-28); a pull request from a fork gets a read-only token unless the repository sends write tokens to such workflows (workflow-syntax.md, How permissions are calculated). For pull_request, GITHUB_SHA is the "Last merge commit on the GITHUB_REF branch" (events-that-trigger-workflows.md), so the check goes on pull_request.head.sha from the payload file GITHUB_EVENT_PATH names (webhook-pull-request-opened schema; variables.md for GITHUB_API_URL, GITHUB_REPOSITORY and GITHUB_EVENT_PATH). ↗
  • githubActions.stepSummary: GitHub flavored Markdown appended to the file named by the variable; at most 1 MiB per step (over that the upload fails with an error annotation), and at most 20 step summaries are shown per job. ↗
  • npmRegistry.api: GET /{package} returns the full document by default: dist-tags maps tags to versions (every package has latest), versions maps versions to version objects, time maps every version to its publish time, and a version object carries scripts (from its package.json) and deprecated. The abbreviated document (Accept: application/vnd.npm.install-v1+json) has no time field and adds hasInstallScript. Scoped names are escaped with %2f (escapedName in github.com/npm/npm-package-arg); the registry answered the same document for @types/node and @types%2fnode on 2026-10-29. Install scripts: preinstall, install and postinstall run for a dependency, and npm runs node-gyp rebuild as install when the package has binding.gyp and no install or preinstall script (github.com/npm/cli/blob/v12.2.1/docs/lib/content/using-npm/scripts.md); binding.gyp is not visible in the document. ↗
  • pypiIndex.api: GET /simple/<project>/ with Accept: application/vnd.pypi.simple.v1+json returns name, files, meta, versions and project-status; the project is matched case-insensitively with _, - and . considered equal (index-api.md in pypi/warehouse, the source of docs.pypi.org/api/index-api/, which recommends the JSON form for new integrations; the JSON API of /pypi/<project>/json marks its releases key deprecated). A file has filename, url, hashes, size, an optional upload-time (yyyy-mm-ddThh:mm:ss.ffffffZ, UTC) and an optional yanked (true or a reason string). Every file belongs to a version listed in versions, but the response does not say which: the version is part of the file name. On 2026-10-30 pypi.org answered api-version 1.4 for requests and 404 for a name it does not know. ↗
  • pypiIndex.projectStatus: A project has exactly one status, active when none is given. quarantined: considered generally unsafe (for example malware), and the index must not offer any of its files. archived: no new uploads, existing files stay; installers may warn. deprecated: obsolete, perhaps superseded by another project; installers may warn. ↗
  • claudeCode.hooks: A PreToolUse command hook gets the event as JSON on stdin and decides by printing one JSON object and exiting 0: deny prevents the call and shows the reason to Claude, ask prompts the user (also in auto mode), deny wins over ask. The PowerShell tool passes its command in tool_input.command with the same fields as the Bash tool. A matcher of names separated by | matches each of them exactly. With args set, command runs as an executable without a shell; on Windows it must resolve to a real executable such as a .exe, not a .cmd or .bat shim from node_modules/.bin. Without onFailure, a hook that fails to start, crashes or times out lets the call through. The if filter is best-effort; the docs recommend the permission system for hard allow or deny rules. ↗
  • claudeCode.sessionStart: SessionStart runs when a session starts or resumes; its matcher startup fires for a new session (also resume, clear, compact and fork). Hooks run in the background, but "Claude's first response still waits for the hooks to finish", and a prompt sent meanwhile does not reach Claude until they finish. A command hook may be shell form (command with $CLAUDE_PROJECT_DIR, the repository root). With onFailure set to "block" (#block-the-action-when-a-hook-fails), a PreToolUse hook whose script is missing blocks the call ("failed; blocking because onFailure is "block"" followed by node's error output, in the example "PreToolUse:Bash hook error: [node ${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.js]: failed; blocking because onFailure is "block"" and "Error: Cannot find module '/path/to/project/.claude/hooks/check-command.js'", re-read 2026-11-01): node starts, cannot load the script and exits with 1, which counts as a failure; without it, the same missing script is a non-blocking error and the command runs. In cloud sessions (https://code.claude.com/docs/en/cloud-environments#setup-scripts) a setup script is a Bash script that runs as root before Claude Code launches and is skipped when a cached environment exists; SessionStart hooks of the repository's .claude/settings.json run in local and cloud sessions (in a session with one repository, outside a project thread), user-level ~/.claude/settings.json hooks do not reach the cloud. The docs recommend a SessionStart hook for project setup such as npm install. ↗
  • claudeCode.shellTools: Tool names are the exact strings of hook matchers. Bash executes shell commands. PowerShell executes PowerShell commands natively; hooks get its command in tool_input.command with the same fields as Bash, and the docs say to match Bash|PowerShell in hooks that inspect shell commands: on Windows, wherever the PowerShell tool is enabled, Claude treats PowerShell as the primary shell, and without Git Bash it is enabled automatically and the Bash tool is not registered at all (also https://code.claude.com/docs/en/hooks#powershell). On Windows with Git Bash it is on by default for claude.ai and Console accounts, CLAUDE_CODE_USE_POWERSHELL_TOOL=0 turns it off, and Claude Code runs pwsh.exe or else powershell.exe 5.1. Monitor runs a command in the background and feeds its output lines back to Claude, with the same permission rules as Bash; on Windows it is available only with Git Bash; a WebSocket watch takes a ws input in place of command. ↗
  • claudeCode.commandlessInputs: "A WebSocket watch takes a `ws` input in place of `command`, and a single Monitor call can't combine the two"; ws has url (a ws:// or wss:// URL) and optional protocols. Opening a WebSocket has its own approval prompt. ↗
  • mcp.revisions: Modern: revisions that carry version, identity and capabilities on every request (2026-07-28 and later); legacy: revisions that open a session with the initialize handshake (2025-11-25 and earlier). A dual-era server may serve both on one stdio process: a request with the modern per-request _meta is served statelessly, an initialize request selects legacy semantics for the process. docs/docs.json lists 2026-07-28 (latest), 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05; schema/2026-07-28/schema.ts and schema/draft/schema.ts both say LATEST_PROTOCOL_VERSION = "2026-07-28". ↗
  • mcp.lifecycle: If the server supports the requested protocolVersion it must answer with the same one, otherwise with another version it supports, which should be its latest; a client that cannot use it disconnects (the same wording in 2024-11-05). After the result the client sends notifications/initialized. The initialize request must not be cancelled and, in 2025-03-26, must not be part of a batch. ping (basic/utilities/ping.mdx) is answered promptly with an empty result and may be sent before initialization. 2026-07-28 removes initialize, notifications/initialized and ping (docs/specification/2026-07-28/changelog.mdx). ↗
  • mcp.stateless: Every 2026-07-28 request carries params._meta with io.modelcontextprotocol/protocolVersion and io.modelcontextprotocol/clientCapabilities (required; a request missing either is rejected with -32602) and optionally io.modelcontextprotocol/clientInfo; servers should put io.modelcontextprotocol/serverInfo in the _meta of every result, and every result must carry resultType ("complete" for a finished one; clients read an absent one as complete). Servers must implement server/discover (server/discover.mdx: supportedVersions, capabilities, instructions, serverInfo in _meta). server/utilities/caching.mdx: results of server/discover and tools/list must carry ttlMs (>= 0) and cacheScope ("public" suits lists of tools that are the same for all users). An unsupported version gets -32022 with data { supported, requested } (basic/versioning.mdx). Self-reported identity must not change behavior. ↗
  • mcp.tools: A server with tools declares the tools capability and answers tools/list (tools in a deterministic order that does not vary per connection) and tools/call ({ name, arguments }; result content, optional structuredContent and isError). Errors of the tool itself, including input values the model can correct, belong in the result with isError: true; an unknown tool or a request that does not fit the schema is a protocol error (-32602). A tool that returns structuredContent should also return the same JSON in a text block. Tool names should be 1 to 128 characters of letters, digits, _, - and . . Annotations (readOnlyHint, openWorldHint and others) are hints that clients must treat as untrusted. Annotations arrived in 2025-03-26 (changelog.mdx), title and structured output in 2025-06-18 (changelog.mdx); in 2025-11-25 and earlier structuredContent is an object. ↗
  • mcp.cancellation: The client cancels an in-flight request with the notification notifications/cancelled and params { requestId, reason? }; the server should stop the work as soon as practical and must not send any further message for that request, and may ignore an unknown or finished request (also basic/transports/stdio.mdx). The same notification exists in the legacy revisions (2025-11-25/basic/utilities/cancellation.mdx). ↗
  • mcp.errorCodes: PARSE_ERROR, INVALID_REQUEST, METHOD_NOT_FOUND, INVALID_PARAMS, INTERNAL_ERROR and UNSUPPORTED_PROTOCOL_VERSION. -32601 is for a method the server does not implement. basic/index.mdx: request ids are strings or integers and never null; notifications have no id and get no response; an error response has the id of its request except when it could not be read, and the 2025-11-25 and 2026-07-28 schemas make id optional in an error response; codes from -32000 to -32019 are legacy and other codes from -32020 to -32099 that the specification does not define must not be used. ↗
  • mcp.errorId: JSONRPCErrorResponse has id?: RequestId in the 2025-11-25 schema (also in schema/2026-07-28/schema.ts); the schemas of 2025-06-18 and 2024-11-05 have JSONRPCError with a required id: RequestId (string | number), and basic/index.mdx of 2025-06-18 says responses must include the same id as their request and request ids must not be null. Neither says what an error response for a request whose id cannot be read carries; JSON-RPC 2.0 uses null there (jsonrpc.org was not reachable to verify it). ↗
  • mcp.stdio: The server reads JSON-RPC messages from stdin and writes them to stdout, delimited by newlines and without embedded newlines; it must not write anything to stdout that is not a valid MCP message, may log UTF-8 to stderr and should exit promptly when stdin is closed. Batches: 2025-03-26 (basic/index.mdx) says implementations must support receiving JSON-RPC batches; 2025-06-18 removed batching (changelog.mdx), and later revisions have no batch message. ↗
  • mcp.clients.claudeCode: claude mcp add [options] <name> -- <command> [args...]: everything after -- goes to the server untouched. Scopes: local (the default, ~/.claude.json), project (.mcp.json in the project root, shared through the repository; Claude Code asks before using its servers) and user. .mcp.json has a top-level mcpServers object of entries with command, args and env; an entry without type is a stdio server. Claude Code sets CLAUDE_PROJECT_DIR to the project root in the environment of the server, not in its own, so ${VAR} expansion in command or args of .mcp.json needs a default such as ${CLAUDE_PROJECT_DIR:-.}. To stop a stdio server it sends SIGINT, then SIGTERM after 100 ms and SIGKILL after a further 400 ms (macOS, Linux); on Windows it closes stdin and ends the process tree after 300 ms. ↗
  • mcp.clients.claudeDesktop: The page "Connect to local MCP servers" of modelcontextprotocol.io: Claude Desktop reads mcpServers (entries with command, args and env) from claude_desktop_config.json. It documents no working directory and no variables, and its troubleshooting asks for absolute paths. The stderr of a server goes to mcp-server-<name>.log in ~/Library/Logs/Claude (macOS) or %APPDATA%\Claude\logs (Windows). ↗
  • mcp.clients.vscode: The source of code.visualstudio.com/docs/agents/reference/mcp-configuration. .vscode/mcp.json (in the workspace or the user profile) has a top-level servers object; a stdio server needs type "stdio" and command, and takes args, cwd (defaults to the workspace folder when run in a workspace), env and envFile; predefined variables such as ${workspaceFolder} work in the configuration. VS Code also reads the portable .mcp.json with mcpServers at the workspace root, without cwd. code --add-mcp with a JSON object of a name and the server configuration adds the server to the user profile. ↗
  • git.ignore: git status and git add skip untracked files that match a pattern from a .gitignore in the same directory or a parent (deeper files override higher ones, and within one file the last matching pattern decides), then from $GIT_COMMON_DIR/info/exclude (.git/info/exclude outside linked worktrees), then from core.excludesFile. Files already tracked are not affected. Patterns: # comments, ! negation, a leading or middle / anchors the pattern to the directory of its .gitignore, a trailing / matches directories only, * and ? do not match /, **/, /** and /**/ match any number of directories; a file below an ignored directory cannot be re-included. The tracked files are the entries of $GIT_DIR/index (Documentation/gitformat-index.adoc at v2.56.0: versions 2, 3 and 4). ↗
  • git.ignoreCase: core.ignoreCase turns on workarounds for file systems that are not case sensitive (APFS, HFS+, FAT, NTFS); it defaults to false, but git clone and git init probe the file system and set it to true when appropriate, so a repository cloned on Windows or macOS has it. With it, git matches .gitignore patterns and looks up the index without regard to case: match_basename and match_pathname in dir.c compare with fspathncmp and fnmatch_icase_mem, which fold case (strncasecmp, WM_CASEFOLD) when repo_ignore_case is set, and environment.c reads core.ignorecase (both at v2.56.0). Section and variable names are case-insensitive, true is yes, on, true or 1 in any case, and a variable without = <value> is true (Documentation/config.adoc at v2.56.0). ↗
  • git.repositoryEntry: "A submodule is a repository embedded inside another repository", with its own history; "the repository it is embedded in is called a superproject". Its git directory is "located under the $GIT_DIR/modules/ directory of its superproject", with "a .git file at the root of the submodule's working directory pointing to" it, and the superproject tracks it only "via a gitlink entry in the tree" with the commit it expects. So a directory with a .git entry of its own (a directory, or the file of a submodule) holds the files of another repository. ↗
  • windows.commandShims: cmd-shim is "the cmd-shim used in npm to create executable scripts on Windows" (README): for each program of a package it writes <name>.cmd, which runs the program with %* (so cmd.exe reads the arguments again), <name>.ps1 for PowerShell and a sh script. npm ships the same files for itself: bin/npm.cmd, bin/npm.ps1, bin/npx.cmd and bin/npx.ps1 in github.com/npm/cli at v12.2.1, the .cmd files ending in "%NODE_EXE%" "%NPM_CLI_JS%" %*. ↗
  • windows.batchArguments: about_Parsing (the source of https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_parsing): on Windows, arguments for batch files are passed as raw command-line strings to cmd.exe, and untrusted input should be passed another way. In the Windows mode of $PSNativeCommandArgumentPassing, the default on Windows since PowerShell 7.3, files ending in .bat or .cmd (also cmd.exe, cscript.exe, wscript.exe, .js, .vbs and .wsf) keep the legacy argument passing of Windows PowerShell 5.1. ↗
  • osv.api: POST /v1/querybatch takes {"queries": [...]}, each query as for POST /v1/query: a package by name and ecosystem with a top-level version, or by purl (a version in both places is a 400). It "Returns vulnerability ids and modified field only. The response ordering will be guaranteed to match the input": {"results": [{"vulns": [{"id", "modified"}], "next_page_token"?}]}. A result with more pages has next_page_token; the next request sends page_token only for those queries, and rarely a result holds only a token, so the caller keeps asking until no token comes back. The response is the JSON of v1BatchVulnerabilityList (docs/osv_service_v1.swagger.json), where an empty list is left out. "MaxQueriesPerQueryBatchRequest is a limit set in osv.dev's API, so is not configurable" = 1000 (bindings/go/osvdev/osvdev.go, with DefaultBaseURL https://api.osv.dev). A record's page is https://osv.dev/vulnerability/<ID> (docs/faq.md); GET /v1/vulns/{id} returns the record (docs/api/get-v1-vulns.md). Requests are case-sensitive ("use 'PyPI' instead of 'pypi'"), and PyPI names are matched after PEP 503 normalization (docs/api/post-v1-query.md). api.osv.dev could not be reached from the machine that read these sources. ↗
  • osv.paging: Pagination happens when "An individual query within the queryset returns more than 1,000 vulnerabilities" or "The entire queryset returns more than 3,000 vulnerabilities total"; "These numbers can vary slightly because of threading and the page size may change in the future." ↗
  • osv.ids: Version 1.9.2 (October 13, 2026) of the OSV schema: an id is "<DB>-<ENTRYID>", and it "must strictly use ASCII characters matching the regular expression ^[a-zA-Z0-9:_.-]+$"; "Characters outside this set (such as spaces, slashes /, backslashes \, parentheses, or exclamation marks) are not allowed." The JSON schema of the same release (validation/schema.json) checks only the prefix (MAL- among the home databases). The schema sets no length for an id. ↗
  • osv.service: "Is the API rate limited? No. Currently there is not a limit on the API." The response size limit is 32 MiB over HTTP/1.1 and none over HTTP/2. Data freshness objective: "Data sources no more than 15 minutes stale, 99.5% of the time". Availability objective 99.9% over 7 days; POST /v1/querybatch latency P50 500 ms, P90 4 s, P95 6 s. ↗
  • osv.withdrawn: Records with the withdrawn field (an RFC 3339 time, ossf/osv-schema docs/schema.md) "will be excluded from: the responses to POST API queries"; they stay in the database, are "returned by the /vulns/<ID> GET API" and shown at https://osv.dev/vulnerability/<ID> marked as withdrawn. ↗
  • osv.malicious: The prefix table of the OSV schema lists MAL for the "Malicious Packages Repository" (github.com/ossf/malicious-packages/tree/main/osv/); OSV.dev imports it under Apache 2.0 (google/osv.dev docs/data.md). Its README (github.com/ossf/malicious-packages/blob/main/README.md) says false positives "may be present in our dataset from time-to-time": a report that is wholly a false positive is moved to osv/withdrawn/ with a withdrawn time, and for false-positive versions of a report those versions move into a database_specific array; reports are not removed. Its CONTRIBUTING.md says ids are assigned automatically and the summary is replaced by a standard one ("Malicious code in <name> (<ecosystem>)" in the records). ↗
  • osv.ecosystems: Keys are the ecosystems of depcurfew (npm, pypi and packagist; in package names of the policy no prefix, pypi: and composer:), values the ecosystem names of the OSV schema: "npm" (an NPM package name), "PyPI" (a normalized PyPI package name), "Packagist" (a PHP package name; without a :<REMOTE-REPO-URL> suffix it means https://packagist.org). OSV.dev covers all three (google/osv.dev docs/data.md, Covered Ecosystems). How it compares Packagist versions: versionMatching. ↗
  • osv.versionMatching: The API (go/cmd/api, with the Datastore store of go/internal/database/datastore) answers a query with a version by buildVersionMatcher: for an ecosystem it knows, it parses the version with the ecosystem helper and keeps the AffectedVersions whose coarse range holds Coarse(version), then matches each listed version of a record by parsing it too and comparing the two (versionIsMatchEcosystemVersionsList, cmp == 0), and the events of its ranges the same way. The Packagist helper (go/osv/ecosystem/packagist.go) parses with semantic.ParsePackagistVersion of google/osv-scalibr v0.5.3 (go/go.mod), whose canonicalizePackagistVersion removes one leading v or V before it compares as PHP's version_compare does (semantic/version-packagist.go at v0.5.3), and its Coarse removes them too, so v8.1.9 and 8.1.9 are the same version both in a query and in a record (also the coarse range the importer stores, go/internal/database/datastore/affected_versions.go). The Python helper of the workers (osv/ecosystems/packagist.py, PackagistVersion.php_canonicalize_version) removes a leading v as well. All at google/osv.dev b7449847246af793439d06284d340af40cdae854 (master on 2026-11-02). A version of composer.lock is therefore sent as Composer wrote it. ↗
  • python.nameNormalization: Names are lowercased and every run of ., - or _ becomes a single -, before lookups and comparisons (PEP 503): Friendly.Bard and friendly_bard are the same package. Read from the page source in pypa/packaging.python.org. ↗
  • python.namePattern: The specification gives ^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])\Z run with re.IGNORECASE (PEP 508). ↗
  • python.projectFile: The configuration file of a Python project, in the project root; tools keep their own settings in its [tool.<name>] tables. ↗
  • python.wheelExtension: A wheel is a ZIP archive with the .whl extension; installing it unpacks files and runs no build code. Read from the page source in pypa/packaging.python.org. ↗
  • python.sourceDistributionExtensions: ARCHIVE_EXTENSIONS of pip without .whl: the archives pip accepts from an index besides wheels (index/package_finder.py rejects any other extension), all of them built when installed. A standard sdist is named {name}-{version}.tar.gz with the name normalized (PEP 625, source-distribution-format.rst); older uploads use the other extensions and names that are not normalized. ↗
  • python.bundledPip: _PIP_VERSION in Lib/ensurepip/__init__.py at every final tag from v3.9.0 to v3.15.2 (github.com/python/cpython/blob/v<X.Y.Z>/...; the latest tags are v3.9.25 0bbaf5de, v3.10.22 acb4dc12, v3.11.18 26badd80, v3.12.16 2c2462af, v3.13.18 0d4bd512, v3.14.10 b703b2c5 and v3.15.2 5e58eaad), as the first release of each line that bundles each pip version. Two-part values such as 24.0 are written 24.0.0. 3.12 and older never bundle pip 26; pip 26.1 or later comes with 3.13.14, 3.14.5 and 3.15.0. ↗
  • python.hatch: Hatch reads its project configuration from [tool.hatch] of pyproject.toml or from hatch.toml. It has no setting of its own for a release-age delay, building from source or dependency sources; its environments install with uv (installer = "uv", the default of its internal environments) or pip (docs/how-to/environment/select-installer.md), and uv reads [tool.uv] of the project under Hatch too (tested on 2026-10-30 with Hatch 1.18.2 and uv 0.13.6). ↗
  • python.virtualEnvironment: Creating virtual environments: venv "places a pyvenv.cfg file in it with a home key" (in the target directory) and "also creates a bin (or Scripts on Windows) subdirectory". How venvs work: "A virtual environment may be "activated" using a script in its binary directory (bin on POSIX; Scripts on Windows)"; the table of activation commands: POSIX bash/zsh source <venv>/bin/activate, fish source <venv>/bin/activate.fish, csh/tcsh source <venv>/bin/activate.csh, pwsh <venv>/bin/Activate.ps1; Windows cmd.exe <venv>\Scripts\activate.bat, PowerShell <venv>\Scripts\Activate.ps1. Activation prepends the binary directory to PATH and sets VIRTUAL_ENV. Lib/venv/__init__.py at v3.14.0 writes pyvenv.cfg as os.path.join(context.env_dir, "pyvenv.cfg") and installs the scripts of the common directory and of os.name. ↗
  • python.interpreter: python [-bBdEhiIOPqRsSuvVWx?] [-c command | -m module-name | script | - ] [args]: -m and -c end the interpreter options, and what follows goes to the module or the command; -W arg, -X option and --check-hash-based-pycs mode take a value, the other options are flags. One-letter options may be grouped after one dash: _PyOS_GetOpt in Python/getopt.c (v3.14.0, SHORT_OPTS "bBc:dEhiIm:OPqRsStuvVW:xX:?") reads them one by one, and c, m, W and X take the rest of the word or the next word, so python3 -Im pip runs pip. pip documents running itself as python -m pip, and as py -m pip with the Windows launcher (github.com/pypa/pip/blob/26.2.2/docs/html/cli/pip_install.rst). ↗

To review

Uncertain facts rest on incomplete official sources; disputed facts have official sources that disagree.

npm · installScripts.allowList.format ❓ uncertain

The exact entry grammar (no semver ranges) is stated in accepted RFC 0054; the shipped docs describe entries only in prose.

  • Object keyed by name, name@version or name@v1 || v2 with true (allow) or false (deny); npm install-scripts approve writes pinned name@version entries · source, verified 2026-10-28.

npm · sources.git.availableSince ⚠️ disputed

The release notes add --allow-git in 11.9.0; the GitHub changelog says it was introduced in 11.10.0.

  • Variant 1: 11.9.0 · source, verified 2026-10-28.
  • Variant 2: 11.10.0 · source, verified 2026-10-28.

npm · sources.remoteTarball.availableSince ⚠️ disputed

The 11.14.0 release notes add the flag; the GitHub changelog dates it to 11.15.0, which also moved enforcement into the resolver. Treat 11.15.0 as the safe minimum.

  • Variant 1: 11.14.0 · source, verified 2026-10-28.
  • Variant 2: 11.15.0 · source, verified 2026-10-28.

npm · sources.file.availableSince ⚠️ disputed

The 11.14.0 release notes add the flag; the GitHub changelog dates it to 11.15.0, which also moved enforcement into the resolver. Treat 11.15.0 as the safe minimum.

  • Variant 1: 11.14.0 · source, verified 2026-10-28.
  • Variant 2: 11.15.0 · source, verified 2026-10-28.

npm · sources.directory.availableSince ⚠️ disputed

The 11.14.0 release notes add the flag; the GitHub changelog dates it to 11.15.0, which also moved enforcement into the resolver. Treat 11.15.0 as the safe minimum.

  • Variant 1: 11.14.0 · source, verified 2026-10-28.
  • Variant 2: 11.15.0 · source, verified 2026-10-28.

npm · project.workspacesObjectKey ❓ uncertain

Not documented; npm's map-workspaces also accepts { "packages": [...] } and negated patterns.

  • packages · source, verified 2026-10-28.

npm · extra.lockfileInstalls ❓ uncertain

Inferred: npm ci does not list min-release-age or before among its options, and a user report (npm/cli#9277) describes it installing a version younger than the window.

  • npm ci installs versions pinned in package-lock.json without applying min-release-age · source, verified 2026-10-28.

pnpm · cooldown.cliFlag ❓ uncertain

No dedicated flag is documented for install or add; release notes mention "a CLI flag" without syntax. Environment variable: PNPM_CONFIG_MINIMUM_RELEASE_AGE (pnpm 11+), npm_config_minimum_release_age (pnpm 10).

  • null · source, verified 2026-10-28.

pnpm · sources.file.setting ❓ uncertain

No setting restricts file: or link: dependencies (concluded from the full settings list); blockExoticSubdeps treats local paths and workspace links as trusted.

  • null · source, verified 2026-10-28.

pnpm · sources.directory.setting ❓ uncertain

No setting restricts file: or link: dependencies (concluded from the full settings list); blockExoticSubdeps treats local paths and workspace links as trusted.

  • null · source, verified 2026-10-28.

pnpm · project.workspacesObjectKey ❓ uncertain

The docs show packages only as a list; concluded from the absence of an object form.

  • null · source, verified 2026-10-28.

pnpm · user.unknownKeys ❓ uncertain

pnpm 11 drops config.yaml keys it does not accept (unknown, project-only or not camelCase) and prints a warning that names them; pnpm 12 warns about keys its port of isConfigFileKey rejects, but drops blockExoticSubdeps without a word. What pnpm 10 does with an unknown key in rc was not checked.

  • warn · source, verified 2026-10-31.

pnpm · user.invalidValueFails ❓ uncertain

Read from code: pnpm 11.28.10 stops when the global config.yaml cannot be read (readGlobalYamlConfig) or applied (applyGlobalYamlConfig), except in commands that skip unreadable settings. Which values fail, and what pnpm 10 (rc) and pnpm 12 do, was not checked; true is the safe assumption.

  • true · source, verified 2026-10-31.

pnpm · extra.perProjectNpmrc ❓ uncertain

Without a shared lockfile, pnpm 10 installs every workspace project with its own .npmrc layered over the workspace settings, without filtering keys, so a package .npmrc can change minimum-release-age for that project. Read from code; no documentation or test covers it. No official source says this combination turns minimumReleaseAge off.

  • {"sharedWorkspaceLockfile":false,"until":"11.0.0"} · source, verified 2026-10-29.

pnpm · extra.lockfileRecheck ❓ uncertain

Structured form of lockfileVerification: whether a frozen-lockfile install re-checks the age of versions already in the lockfile. trustLockfile: true (11.3.0) turns the check off.

  • 10.16.0+: false
    11.1.3+: true · source, verified 2026-10-28.

pnpm · extra.lockfileVerification ❓ uncertain

The 11.1.3 release notes confirm re-validation (ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION). The pnpm 10 behavior rests on maintainer comments in pnpm/pnpm#12450 (a Dependabot lockfile passed --frozen-lockfile on 10.34.5), not on docs.

  • 10.16.0+: frozen-lockfile installs do not re-check versions already in the lockfile
    11.1.3+: lockfile entries are re-checked; trustLockfile: true (11.3.0) turns this off · source, verified 2026-10-28.

Yarn (Berry) · cooldown.cliFlag ❓ uncertain

No flag sets the gate. --no-time-gate on yarn add and yarn up (4.15.0+) disables it for one command; yarn install has no such flag.

  • null · source, verified 2026-10-28.

Yarn (Berry) · cooldown.default ⚠️ disputed

The code is unambiguous: off until 4.14.x, 1d from 4.15.0. The published settings schema claimed 3d for 4.11.0-4.14.x and 0m in 4.16.0; the live yarnrc page shows "1w", which is an example value. Upgraded projects with an old lockfile get npmMinimalAgeGate: 0 written to .yarnrc.yml (see upgradeMigration).

  • Variant 1: 4.10.0+: 0
    4.15.0+: 1d · source, verified 2026-10-28.
  • Variant 2: 4.10.0+: 0
    4.11.0+: 3d
    4.15.0+: 1d · source, verified 2026-10-28.

Yarn (Berry) · cooldown.securityUpdates ❓ uncertain

No automatic bypass is documented and yarn npm audit only reports. Options: --no-time-gate on yarn add/up, a pinned npmPreapprovedPackages entry, or a per-scope gate of 0.

  • applies · source, verified 2026-10-28.

Yarn (Berry) · installScripts.allowList.availableSince ❓ uncertain

dependenciesMeta is documented in the changelog from the 2.x line; the exact first version was not pinned down.

  • 2.0.0 · source, verified 2026-10-28.

Yarn (Berry) · sources.remoteTarball.setting ❓ uncertain

No setting restricts http(s) tarball dependencies (concluded from the full settings list); the closest are enableNetwork, networkSettings.<host>.enableNetwork and unsafeHttpWhitelist for plain http.

  • null · source, verified 2026-10-28.

Yarn (Berry) · sources.file.setting ❓ uncertain

No setting restricts file:, link: or portal: dependencies (concluded from the settings list and plugin sources); only exec: is gated by enableScripts (4.14.0+).

  • null · source, verified 2026-10-28.

Yarn (Berry) · sources.directory.setting ❓ uncertain

No setting restricts local directory dependencies (file:, link:, portal:), as for local tarballs.

  • null · source, verified 2026-10-28.

Yarn (Berry) · project.workspacesObjectKey ❓ uncertain

Not documented; the manifest parser also accepts { "packages": [...] }.

  • packages · source, verified 2026-10-28.

Yarn (Berry) · user.invalidValueFails ❓ uncertain

Read from code at 4.18.1: parseValue errors are rethrown with the file name while the configuration loads, so a value Yarn cannot parse, such as enableScripts: maybe or a malformed duration, stops every command, also from the home file. On 4.10.x a duration string such as 7d silently had no effect instead (durationStrings). Not tested.

  • true · source, verified 2026-10-31.

Yarn (Berry) · user.weakening ❓ uncertain

Read from code (resolveRcFiles, the same since 4.0.0; not on yarnpkg.com, and no test was read): lists from every .yarnrc.yml are joined, so home entries add to a project's list unless the project uses the undocumented { onConflict: reset } form; objects such as npmScopes merge key by key; for single values the file closest to the project wins. Since 4.17.0 a scope listed in the home npmScopes only for its registry gets the default gate of 1d instead of the project's gate (perScopeGate). A .yarnrc.yml in any folder between the root and the project merges the same way. enableScripts is a switch that turns a protection off: Yarn reads every value as text (FAILSAFE_SCHEMA, see extra.yamlMergeKeys) and parseBoolean of miscUtils.ts takes true and 1 as true and false and 0 as false and stops on any other value, after replacing ${VARIABLE} references; depcurfew counts every value but false and 0 as on.

  • {"key":"approvedGitRepositories","values":"any","effect":"approves these git repositories in every project, on top of the project's own list"}, {"key":"npmPreapprovedPackages","values":"any","effect":"exempts these packages from the age gate in every project, on top of the project's own list"}, {"key":"enableScripts","values":{"except":[false,0,"false","0"]},"effect":"runs dependency build scripts in every project whose .yarnrc.yml does not set enableScripts"}, {"key":"npmMinimalAgeGate","values":[0],"effect":"turns the age gate off in every project whose .yarnrc.yml does not set it"}, {"key":"npmScopes.*.npmMinimalAgeGate","values":[0],"effect":"turns the age gate off for that scope in every project"} · source, verified 2026-10-31.

Yarn (Berry) · user.variables ⚠️ disputed

The yarnrc docs say environment variables cannot set lists, but parseValue splits a string on commas for list settings, so by the code YARN_APPROVED_GIT_REPOSITORIES and YARN_NPM_PREAPPROVED_PACKAGES work. The safe choice is to treat both as effective.

  • Variant 1: {"name":"YARN_ENABLE_SCRIPTS","anyCase":true,"values":{"except":["false","0"]},"effect":"runs dependency build scripts, whatever any .yarnrc.yml says"}, {"name":"YARN_NPM_MINIMAL_AGE_GATE","anyCase":true,"values":"any","effect":"replaces npmMinimalAgeGate from every .yarnrc.yml"}, {"name":"YARN_APPROVED_GIT_REPOSITORIES","anyCase":true,"values":"any","effect":"replaces approvedGitRepositories from every .yarnrc.yml (a comma-separated list)"}, {"name":"YARN_NPM_PREAPPROVED_PACKAGES","anyCase":true,"values":"any","effect":"replaces npmPreapprovedPackages from every .yarnrc.yml (a comma-separated list)"} · source, verified 2026-10-31. A variable starting with yarn_ in any case sets the camel-cased setting before the rc files are read, and they cannot change it (Configuration.find and use; YARN_IGNORE_SCRIPTS is ignored); a list setting takes a comma-separated string (parseValue); enableScripts accepts true or 1 (parseBoolean), false or 0 turn it off, and any other value stops Yarn, so every value but false and 0 counts as on.
  • Variant 2: {"name":"YARN_ENABLE_SCRIPTS","anyCase":true,"values":{"except":["false","0"]},"effect":"runs dependency build scripts, whatever any .yarnrc.yml says"}, {"name":"YARN_NPM_MINIMAL_AGE_GATE","anyCase":true,"values":"any","effect":"replaces npmMinimalAgeGate from every .yarnrc.yml"} · source, verified 2026-10-31. Most settings "can also be defined through environment variables (at least for the simpler ones; arrays and objects aren't supported yet)", and such values "will overwrite any that might have been defined in the RC files".

Yarn (Berry) · extra.yarnPath ❓ uncertain

yarn set version saves the release as .yarn/releases/yarn-<version>.cjs and writes a relative yarnPath to it. Yarn 2 and later read yarnPath (an absolute path setting, resolved against the folder of the .yarnrc.yml that sets it) from every .yarnrc.yml, the home file included, before the project is found (Configuration.find, pickPrimaryCoreFields), and run node <yarnPath> instead of themselves (runYarnPath in packages/yarnpkg-cli/sources/lib.ts); a nearer .yarnrc.yml with its own yarnPath, YARN_YARN_PATH or YARN_IGNORE_PATH changes that. The file name is only a hint: a URL or a file given to yarn set version gives other names (yarn-remote.cjs), a hand-written yarnPath may name any file, and the version inside the bundle is minified, so depcurfew uses the name only when it is yarn-<exact version>.cjs and the file exists.

  • {"key":"yarnPath","releaseFile":"yarn-<version>.cjs","variables":["YARN_YARN_PATH","YARN_IGNORE_PATH"]} · source, verified 2026-11-01.

Yarn (Berry) · extra.berryLockfileMarker ❓ uncertain

Read from code: Yarn 2+ writes a __metadata key into yarn.lock and treats a lockfile without it but with "yarn lockfile v1" as Yarn Classic.

  • __metadata · source, verified 2026-10-28.

Yarn (Berry) · extra.unknownSettings ❓ uncertain

Read from the current source code; older releases were not checked.

  • Unknown keys in the project .yarnrc.yml throw (unless enableStrictSettings is false), so settings newer than the pinned Yarn break installs · source, verified 2026-10-28.

Bun · cooldown.default ⚠️ disputed

The bunfig reference says the default is null (off) and an open docs pull request (oven-sh/bun#41545) says the feature is off by default; the install page lists 259200 (3 days) under "These are the default values".

  • Variant 1: 1.3.0+: null · source, verified 2026-10-28.
  • Variant 2: 1.3.0+: 259200 · source, verified 2026-10-28.

Bun · cooldown.securityUpdates ❓ uncertain

No automatic bypass is documented; exempt the fixed release with name@version in minimumReleaseAgeExcludes (1.4.4+). Exact version requests still go through the gate.

  • applies · source, verified 2026-10-28.

Bun · installScripts.allowList.availableSince ❓ uncertain

Upper bound: 1.0.5 already persists trustedDependencies in bun.lockb; the first version was not pinned down. bun pm trust and bun add --trust arrived in 1.0.31.

  • 1.0.5 · source, verified 2026-10-28.

Bun · sources.git.setting ❓ uncertain

Git dependencies are supported with no setting to allow or forbid them (concluded from the full bunfig [install] list); install.blockExoticSubdeps is proposed in oven-sh/bun#30340 but not shipped.

  • null · source, verified 2026-10-28.

Bun · sources.remoteTarball.setting ❓ uncertain

Tarball URL dependencies are supported with no setting to allow or forbid them (concluded from the full bunfig [install] list); install.blockExoticSubdeps is proposed in oven-sh/bun#30340 but not shipped.

  • null · source, verified 2026-10-28.

Bun · sources.file.setting ❓ uncertain

Local tarball dependencies are supported with no setting to allow or forbid them (concluded from the full bunfig [install] list); install.blockExoticSubdeps is proposed in oven-sh/bun#30340 but not shipped.

  • null · source, verified 2026-10-28.

Bun · sources.directory.setting ❓ uncertain

Local directory dependencies are supported with no setting to allow or forbid them (concluded from the full bunfig [install] list); install.blockExoticSubdeps is proposed in oven-sh/bun#30340 but not shipped.

  • null · source, verified 2026-10-28.

Bun · project.lockfiles ❓ uncertain

Bun 1.2 made the text bun.lock the default (verified). That bun.lockb is still read afterwards is inferred from the documented migration command and from saveTextLockfile = false, which writes bun.lockb.

  • earlier: bun.lockb
    1.2.0+: bun.lock, bun.lockb · source, verified 2026-10-28.

Bun · user.variables ❓ uncertain

No environment variable sets minimumReleaseAge or its exclusions: concluded from the install page, which lists registry, token, lockfile and retry variables only. NPM_CONFIG_IGNORE_SCRIPTS only turns scripts off. XDG_CONFIG_HOME moves the user file (user.files).

  • [] · source, verified 2026-10-31.

Deno · cooldown.availableSince ⚠️ disputed

The 2.5.5 release notes ship the flag, the deno.json key and exclude as unstable; the release blog says the feature was introduced in 2.6.

  • Variant 1: 2.5.5 · source, verified 2026-10-28.
  • Variant 2: 2.6.0 · source, verified 2026-10-28.

Deno · cooldown.securityUpdates ❓ uncertain

No security bypass is documented; only per-package exclude or an age of 0.

  • applies · source, verified 2026-10-28.

Deno · installScripts.disableAll ❓ uncertain

Scripts do not run by default. The schema accepts a boolean allowScripts, but no page states that false turns all scripts off. deno x has --ignore-scripts.

  • allowScripts: false · source, verified 2026-10-28.

Deno · user.variables ❓ uncertain

Only these two spellings are read (min_release_age_days_from_env); 0 turns the default 24 hours off. Read from code: every parsed .npmrc starts from the variable and its own key overrides it (test ".npmrc value takes precedence over the environment fallback"), and the project file wins over the home file, so a project .npmrc without the key puts the variable above the home value. The first version is from denoland/deno#35458, which shipped in 2.9.0.

  • {"name":"NPM_CONFIG_MIN_RELEASE_AGE","values":"any","effect":"sets min-release-age where no .npmrc has the key, and hides the home value in projects whose .npmrc lacks it (2.9.0+)"}, {"name":"npm_config_min_release_age","values":"any","effect":"sets min-release-age where no .npmrc has the key, and hides the home value in projects whose .npmrc lacks it (2.9.0+)"} · source, verified 2026-10-31.

Deno · extra.npmrcFormat ⚠️ disputed

The safe choice is an integer number of days, which also matches npm.

  • Variant 1: whole days only, e.g. min-release-age=3 · source, verified 2026-10-28.
  • Variant 2: a duration with a unit, e.g. min-release-age=72h · source, verified 2026-10-28.

Deno · extra.fileLinkSkipped ⚠️ disputed

Official pages disagree on whether the project's own file: and link: dependencies are skipped, or only those in published packages' metadata.

  • Variant 1: file: and link: dependencies in the project package.json are silently skipped · source, verified 2026-10-28.
  • Variant 2: file: and link: specifiers in registry metadata of npm packages are skipped · source, verified 2026-10-28.

uv · cooldown.securityUpdates ❓ uncertain

uv does not know which versions fix vulnerabilities; the delay holds back every new upload unless the package is listed in exclude-newer-package.

  • applies · source, verified 2026-10-30.

uv · sources.git.setting ❓ uncertain

No setting allows or forbids git dependencies (concluded from the list of settings). no-sources only ignores the tool.uv.sources table; a URL dependency introduced by a registry package is rejected during resolution (docs/pip/compatibility.md).

  • null · source, verified 2026-10-30.

uv · sources.remoteTarball.setting ❓ uncertain

No setting allows or forbids URL dependencies (concluded from the list of settings). no-sources only ignores the tool.uv.sources table; a URL dependency introduced by a registry package is rejected during resolution (docs/pip/compatibility.md).

  • null · source, verified 2026-10-30.

uv · sources.file.setting ❓ uncertain

No setting allows or forbids local archive dependencies (concluded from the list of settings). no-sources only ignores the tool.uv.sources table; a URL dependency introduced by a registry package is rejected during resolution (docs/pip/compatibility.md).

  • null · source, verified 2026-10-30.

uv · sources.directory.setting ❓ uncertain

No setting allows or forbids local directory dependencies (concluded from the list of settings). no-sources only ignores the tool.uv.sources table; a URL dependency introduced by a registry package is rejected during resolution (docs/pip/compatibility.md).

  • null · source, verified 2026-10-30.

uv · extra.lockfileFormat ❓ uncertain

uv.lock has no documented format (the docs say only that it is managed by uv). Each [[package]] has source = { registry = URL } for an index, { git = URL?rev#commit }, { url = URL }, { path = archive }, { directory = dir }, { editable = dir } or { virtual = dir } (a directory that is not built). Index packages list sdist and wheels; a package without wheels, or from git, a directory or a source archive, is built when installed.

  • {"sources":{"registry":"registry","git":"git","remoteTarball":"url","file":"path","directory":"directory","editable":"editable","virtual":"virtual"},"sdist":"sdist","wheels":"wheels","packages":"package"} · source, verified 2026-10-30.

pip · cooldown.exclude.setting ❓ uncertain

No per-package exception (concluded from the list of options).

  • null · source, verified 2026-10-30.

pip · cooldown.securityUpdates ❓ uncertain

pip does not know which versions fix vulnerabilities; the cutoff holds back every new upload.

  • applies · source, verified 2026-10-30.

pip · installScripts.allowList.availableSince ❓ uncertain

--no-binary and --only-binary exist since 7.0.0 and are read from pip.conf since 7.1.0; when requirements files started to accept them is not recorded.

  • 7.0.0 · source, verified 2026-10-30.

pip · sources.git.setting ❓ uncertain

No option allows or forbids VCS requirements (concluded from the list of options). Hash-checking mode (--require-hashes, or any --hash) rejects VCS and local directory requirements, unless --no-require-hashes (26.2) turns the automatic mode off.

  • null · source, verified 2026-10-30.

pip · sources.remoteTarball.setting ❓ uncertain

No option allows or forbids direct URL requirements (concluded from the list of options). Hash-checking mode (--require-hashes, or any --hash) rejects VCS and local directory requirements, unless --no-require-hashes (26.2) turns the automatic mode off.

  • null · source, verified 2026-10-30.

pip · sources.file.setting ❓ uncertain

No option allows or forbids local archive requirements (concluded from the list of options). Hash-checking mode (--require-hashes, or any --hash) rejects VCS and local directory requirements, unless --no-require-hashes (26.2) turns the automatic mode off.

  • null · source, verified 2026-10-30.

pip · sources.directory.setting ❓ uncertain

No option allows or forbids local directory requirements (concluded from the list of options). Hash-checking mode (--require-hashes, or any --hash) rejects VCS and local directory requirements, unless --no-require-hashes (26.2) turns the automatic mode off.

  • null · source, verified 2026-10-30.

pip · project.workspaces ❓ uncertain

pip has no workspaces.

  • null · source, verified 2026-10-30.

pip · project.workspacesObjectKey ❓ uncertain

No workspaces.

  • null · source, verified 2026-10-30.

pip · extra.buildSwitch ❓ uncertain

The option exists since 7.0.0; when requirements files started to accept it is not recorded. pip applies it only to packages found on indexes and find-links (format_control is used only by the package finder), so VCS, local directory and direct URL source requirements are still built.

  • {"setting":"--only-binary","value":":all:","since":"7.0.0","covers":["registry"]} · source, verified 2026-10-30.

Poetry · cooldown.cliFlag ❓ uncertain

No command-line option; the environment variable POETRY_SOLVER_MIN_RELEASE_AGE sets it for one command.

  • null · source, verified 2026-10-30.

Poetry · cooldown.securityUpdates ❓ uncertain

Poetry does not know which versions fix vulnerabilities; the delay holds back every new version of a package not listed in solver.min-release-age-exclude.

  • applies · source, verified 2026-10-30.

Poetry · sources.git.setting ❓ uncertain

No setting allows or forbids git dependencies (concluded from the list of settings and Config.default_config); dependencies of dependencies may come from such sources too.

  • null · source, verified 2026-10-30.

Poetry · sources.remoteTarball.setting ❓ uncertain

No setting allows or forbids url dependencies (concluded from the list of settings and Config.default_config); dependencies of dependencies may come from such sources too.

  • null · source, verified 2026-10-30.

Poetry · sources.file.setting ❓ uncertain

No setting allows or forbids local file dependencies (concluded from the list of settings and Config.default_config); dependencies of dependencies may come from such sources too.

  • null · source, verified 2026-10-30.

Poetry · sources.directory.setting ❓ uncertain

No setting allows or forbids local directory dependencies (concluded from the list of settings and Config.default_config); dependencies of dependencies may come from such sources too.

  • null · source, verified 2026-10-30.

Poetry · project.workspaces ❓ uncertain

Poetry has no workspaces: the 2.5.1 docs do not mention them and the request for subprojects is open.

  • null · source, verified 2026-10-30.

Poetry · project.workspacesObjectKey ❓ uncertain

No workspaces.

  • null · source, verified 2026-10-30.

Poetry · user.unknownKeys ❓ uncertain

Config.merge keeps every key of config.toml and only known settings are read, so a version that does not know a key ignores it without a word. Read from the code; tested only with poetry.toml, which goes through the same merge (2.3.4 ignored solver.min-release-age there on 2026-10-30).

  • ignore · source, verified 2026-10-31.

Poetry · user.invalidValueFails ❓ uncertain

A config.toml that is not valid TOML stops every command (TOMLError "Invalid TOML file"). Values are not checked when the file is loaded (only POETRY_* variables go through the normalizers of config.py), and a key an older version does not know is never read, so the keys depcurfew writes need no exact version. Read from the code.

  • false · source, verified 2026-10-31.

Poetry · extra.excludeFormat ⚠️ disputed

The 2.5.1 docs give the type string, a comma-separated list; the docs on main (pull request #11087, not released) give array and say to use a TOML array in poetry.toml. The 2.5.1 code iterates the value as it is, so a string would be read letter by letter. Tested on 2026-10-30: a TOML array exempted the package in Poetry 2.4.0 and 2.5.1.

  • Variant 1: comma-separated string · source, verified 2026-10-30.
  • Variant 2: TOML array · source, verified 2026-10-30.

Poetry · extra.lockedVersionsKept ❓ uncertain

Read from the solver code, which takes the locked package without asking the repository; the docs do not say it.

  • poetry lock and poetry add keep versions already in poetry.lock even when they are newer than the delay allows; poetry update and poetry lock --regenerate resolve them again · source, verified 2026-10-30.

Poetry · extra.lockfileFormat ❓ uncertain

poetry.lock has no documented format. Each [[package]] from PyPI has no [package.source]; others have type git, url, file, directory or legacy (a named index). files lists {file, hash} for every distribution, empty for git and directory packages; a package from an index without a .whl file is built when installed.

  • {"sources":{"git":"git","remoteTarball":"url","file":"file","directory":"directory","registry":"legacy"},"packages":"package","source":"source","files":"files"} · source, verified 2026-10-30.

PDM · cooldown.securityUpdates ❓ uncertain

PDM does not know which versions fix vulnerabilities; the cutoff holds back every newer distribution of a package without an override.

  • applies · source, verified 2026-10-30.

PDM · sources.git.setting ❓ uncertain

No setting allows or forbids git dependencies (concluded from the documented [tool.pdm] settings); only-binary does not stop them from being built.

  • null · source, verified 2026-10-30.

PDM · sources.remoteTarball.setting ❓ uncertain

No setting allows or forbids URL dependencies (concluded from the documented [tool.pdm] settings); only-binary does not stop them from being built.

  • null · source, verified 2026-10-30.

PDM · sources.file.setting ❓ uncertain

No setting allows or forbids local archive dependencies (concluded from the documented [tool.pdm] settings); only-binary does not stop them from being built.

  • null · source, verified 2026-10-30.

PDM · sources.directory.setting ❓ uncertain

No setting allows or forbids local directory dependencies (concluded from the documented [tool.pdm] settings); only-binary does not stop them from being built.

  • null · source, verified 2026-10-30.

PDM · project.workspaces ❓ uncertain

Workspaces ([tool.pdm.workspace] members) are experimental since 2.28.0 and are locked and installed from the root only, so depcurfew configures the root and reads no members.

  • null · source, verified 2026-10-30.

PDM · project.workspacesObjectKey ❓ uncertain

Not read; see workspaces.

  • null · source, verified 2026-10-30.

PDM · user.unknownKeys ❓ uncertain

load_config keeps every key of config.toml without checking it, and only registered config items are ever read, so PDM before 2.27.0 ignores strategy.exclude-newer. Read from the code.

  • ignore · source, verified 2026-10-31.

PDM · user.invalidValueFails ❓ uncertain

A config.toml that is not valid TOML stops every command (load_config catches only FileNotFoundError). Values are coerced when read, and src/pdm/core.py reads strategy.exclude-newer before every command, so a value convert_to_datetime cannot parse (anything but Nd, Nh, Nw, a date or an RFC 3339 time) fails every command. Read from the code.

  • true · source, verified 2026-10-31.

PDM · extra.lockfileFormat ❓ uncertain

pdm.lock (lock_version 4.5) has no documented format beyond the docs examples. Each [[package]] has name, version and files ({file, hash} for every distribution); a VCS package has its repository under the key of its VCS (git = "…") with ref and revision; a local archive or directory has path, a remote archive url, and editable packages editable = true (as_lockfile_entry). A package from an index without a .whl file is built when installed.

  • {"packages":"package","files":"files","file":"file","vcs":["git","hg","svn","bzr"],"url":"url","path":"path","editable":"editable"} · source, verified 2026-10-30.

PDM · extra.uvMode ❓ uncertain

Experimental since 2.19.0: PDM resolves and installs with uv. It passes the cutoff and the build settings to uv lock, but runs uv sync --frozen without the build settings (src/pdm/installers/uv.py), and pdm.lock then lists source distributions even with only-binary.

  • {"file":"pdm.toml","key":"use_uv"} · source, verified 2026-10-30.

Pipenv · cooldown.cliFlag ❓ uncertain

No command-line option.

  • null · source, verified 2026-10-30.

Pipenv · cooldown.exclude.setting ❓ uncertain

No per-package exception: the cutoff applies to every package.

  • null · source, verified 2026-10-30.

Pipenv · cooldown.securityUpdates ❓ uncertain

The cutoff holds back every newer version, security fixes included.

  • applies · source, verified 2026-10-30.

Pipenv · installScripts.allowList.setting ❓ uncertain

No documented setting; a per-package no_binary = true exists in the code (pipenv/routines/install.py) but forces building rather than allowing it.

  • null · source, verified 2026-10-30.

Pipenv · installScripts.disableAll ❓ uncertain

No Pipfile setting. Only pip configuration or PIP_ONLY_BINARY=:all: in the environment (Pipenv loads the project .env for every command) forbids building.

  • null · source, verified 2026-10-30.

Pipenv · sources.git.setting ❓ uncertain

No Pipfile setting allows or forbids git dependencies (concluded from the documented [pipenv] directives).

  • null · source, verified 2026-10-30.

Pipenv · sources.remoteTarball.setting ❓ uncertain

No Pipfile setting allows or forbids URL dependencies (concluded from the documented [pipenv] directives).

  • null · source, verified 2026-10-30.

Pipenv · sources.file.setting ❓ uncertain

No Pipfile setting allows or forbids local archive dependencies (concluded from the documented [pipenv] directives).

  • null · source, verified 2026-10-30.

Pipenv · sources.directory.setting ❓ uncertain

No Pipfile setting allows or forbids local directory dependencies (concluded from the documented [pipenv] directives).

  • null · source, verified 2026-10-30.

Pipenv · project.workspaces ❓ uncertain

Pipenv has no workspaces.

  • null · source, verified 2026-10-30.

Pipenv · project.workspacesObjectKey ❓ uncertain

No workspaces.

  • null · source, verified 2026-10-30.

Pipenv · user.variables ❓ uncertain

PIPENV_RESOLVER is not documented. The code ranks it above the resolver key of the Pipfile ("CLI/caller > env > current project's Pipfile > default"), and the pure-python backend locked the newest versions despite cool-down-period when chosen in the Pipfile (extra.resolverBypass, tested on 2026-10-30); the variable itself was not tested. PIPENV_PYPI_MIRROR: "When the index does not provide upload-time metadata (e.g. most private mirrors) the setting is accepted but has no filtering effect" (docs/pipfile.md). PIP_* variables are merged over the environment of the pip subprocess (pipenv/utils/processes.py), so they still reach it while pip.conf does not; pipenv/routines/install.py also reads PIP_NO_BINARY.

  • {"name":"PIPENV_RESOLVER","values":["pure-python"],"effect":"selects the pure-python resolver, which ignores cool-down-period"}, {"name":"PIPENV_PYPI_MIRROR","values":"any","effect":"replaces PyPI; on a mirror without upload times cool-down-period has no effect"}, {"name":"PIP_ONLY_BINARY","values":"any","effect":"sets only-binary of the pip Pipenv installs with, which no pip.conf reaches since 2026.3.0"}, {"name":"PIP_NO_BINARY","values":"any","effect":"builds these packages from source when installing, and pipenv install records no_binary for a named package in the Pipfile"} · source, verified 2026-10-31.

Pipenv · extra.resolverBypass ❓ uncertain

Not documented. Tested on 2026-10-30 with 2026.10.4: with resolver_backend = "pure-python" in [pipenv], pipenv lock locked the newest versions despite cool-down-period = "100000d"; resolver is the older name of the key.

  • {"table":"pipenv","keys":["resolver_backend","resolver"],"value":"pure-python"} · source, verified 2026-10-30.

Composer · cooldown.cliFlag ❓ uncertain

No option sets the period (concluded from the command options): --no-cooldown and --no-blocking turn the delay off for one command, show --cooldown-period and outdated --cooldown-period only change what is displayed, and COMPOSER_POLICY_COOLDOWN_PERIOD overrides the period.

  • null · source, verified 2026-11-02.

Composer · cooldown.securityUpdates ❓ uncertain

The cooldown section names no exception for security fixes; its example lists symfony/security-bundle under ignore because "Security fixes need to be applied immediately".

  • applies · source, verified 2026-11-02.

Composer · sources.git.setting ❓ uncertain

No setting allows or forbids VCS dependencies (concluded from the config options in 06-config.md). Such packages come only from repositories declared in the root composer.json: "Repositories are not resolved recursively. You can only add them to your main composer.json. Repository declarations of dependencies' composer.jsons are ignored."

  • null · source, verified 2026-11-02.

Composer · sources.remoteTarball.setting ❓ uncertain

No setting allows or forbids package repository dependencies (concluded from the config options in 06-config.md). Such packages come only from repositories declared in the root composer.json: "Repositories are not resolved recursively. You can only add them to your main composer.json. Repository declarations of dependencies' composer.jsons are ignored."

  • null · source, verified 2026-11-02.

Composer · sources.file.setting ❓ uncertain

No setting allows or forbids artifact dependencies (concluded from the config options in 06-config.md). Such packages come only from repositories declared in the root composer.json: "Repositories are not resolved recursively. You can only add them to your main composer.json. Repository declarations of dependencies' composer.jsons are ignored."

  • null · source, verified 2026-11-02.

Composer · sources.directory.setting ❓ uncertain

No setting allows or forbids path repository dependencies (concluded from the config options in 06-config.md). Such packages come only from repositories declared in the root composer.json: "Repositories are not resolved recursively. You can only add them to your main composer.json. Repository declarations of dependencies' composer.jsons are ignored."

  • null · source, verified 2026-11-02.

Composer · project.workspaces ❓ uncertain

Composer has no workspaces; a monorepo links its packages with path repositories.

  • null · source, verified 2026-11-02.

Composer · project.workspacesObjectKey ❓ uncertain

No workspaces.

  • null · source, verified 2026-11-02.

Composer · extra.olderVersions ❓ uncertain

Read from the code at 2.10.3, not tested: fromConfig passes every key of policy but advisories, malware, abandoned and ignore-unreachable to CustomListPolicyConfig::fromRawConfig, which reads only block, audit, ignore and sources, and the schema at 2.10.3 does not reject period there. Config::merge keeps any unknown config key, and the schema of config has no additionalProperties: false.

  • Composer 2.10 reads policy.cooldown as a custom dependency policy without sources, which blocks nothing; older versions ignore config.policy as an unknown config key · source, verified 2026-11-02.

Renovate · cooldown.exclude.availableSince ❓ uncertain

Assumed to work since the option exists with packageRule scope; not stated by a release note.

  • 35.46.0 · source, verified 2026-10-28.

Renovate · installScripts.allowList.setting ❓ uncertain

No per-package allow-list was found: scripts are all or nothing, via allowScripts: true (self-hosted global config) plus ignoreScripts: false.

  • null · source, verified 2026-10-28.

Renovate · extra.pnpmSecurityExclusions ❓ uncertain

updatePnpmWorkspace: when a security update (vulnerability alert) changes a project with a pnpm lockfile whose pnpm-workspace.yaml sets minimumReleaseAge, Renovate adds the entry <name>@<version> to minimumReleaseAgeExclude with the comment "# Renovate security update: <name>@<version>" on the line above it; a later fix of the same package appends " || <version>" to the entry (and to the comment), and an entry for the package that has no comment gets one. The tests next to it (artifacts.spec.ts) show the written file. No other package manager (npm, Yarn, Bun, Deno) has such code at this tag; read from the code.

  • {"managers":["pnpm"],"file":"pnpm-workspace.yaml","setting":"minimumReleaseAgeExclude","comment":"# Renovate security update: ","versionSeparator":" || "} · source, verified 2026-10-30.

Renovate · extra.digestBypassFixed ⚠️ disputed

Digest updates could bypass minimumReleaseAge; the advisory and a maintainer comment give different fixed versions. Rebase requests could bypass strict checks before 44.61.3 (GHSA-2frq-pm48-6j4h).

  • Variant 1: 44.3.1 · source, verified 2026-10-28.
  • Variant 2: 44.10.0 · source, verified 2026-10-28.

Dependabot · cooldown.cliFlag ❓ uncertain

Cooldown is configured only in dependabot.yml; the Dependabot CLI README mentions no such flag.

  • null · source, verified 2026-10-28.

Dependabot · cooldown.exclude.availableSince ❓ uncertain

Presumably shipped with cooldown GA; not confirmed separately.

  • 2025-07-01 · source, verified 2026-10-28.

Dependabot · installScripts.defaultPolicy ❓ uncertain

From dependabot-core source, not the docs: npm, Yarn and Bun lockfile updates run with scripts disabled; for pnpm only --lockfile-only was found. bundler, mix and pip may execute external code.

  • all versions: deny · source, verified 2026-10-28.

Dependabot · installScripts.disableAll ❓ uncertain

Nothing to configure for JavaScript ecosystems: scripts are always disabled (source code). For bundler, mix and pip, external code execution is disabled automatically when registries are configured.

  • null · source, verified 2026-10-28.

Dependabot · extra.yamlMergeKeys ❓ uncertain

Not known. The options reference does not mention YAML anchors or merge keys, GitHub parses dependabot.yml in its own service, and the dependabot-core pull request that would allow aliases ("we can't use the YAML anchor (aliases) feature in dependabot.yml file") is still open and marked stale (read 2026-10-31). depcurfew reads dependabot.yml without merge keys: a cooldown that an entry would get only through <<: *defaults counts as missing, which bot-cooldown reports, and depcurfew apply writes the cooldown into the entry itself, which wins over merged keys where they apply.

  • false · source, verified 2026-10-31.

Dependabot · extra.actionsReleaseDate ❓ uncertain

Read from the code, not the docs. A proposed commit SHA is aged by published_at of the GitHub release of its tag, else the creatordate of the tag (git for-each-ref), else the commit date; version tags by the creatordate of each tag (refs_for_tag_with_detail in common/lib/dependabot/git_metadata_fetcher.rb), which is the tagger date of an annotated tag and the commit date of a lightweight one, both set in git by whoever makes them. Only default-days counts. A missing or unreadable date lets the update through (check_if_version_in_cooldown_period? returns false).

  • the publication date of the GitHub release of the tag, else the date of the tag, else the date of the commit; with no date the update does not wait · source, verified 2026-11-02.

Dependabot · extra.dayRange ⚠️ disputed

Matters for opting out of the default cooldown; cooldown.exclude: ["*"] works under the documented precedence rule either way. The announcement does not state its author's role.

  • Variant 1: 1 to 90 days · source, verified 2026-10-28.
  • Variant 2: 0 removes the cooldown · source, verified 2026-10-28.

Dependabot · extra.transitiveGating ❓ uncertain

Read from dependabot-core source.

  • Regular updates pass the cooldown to npm (11.10+), pnpm (10.16+) and Yarn Berry to hold back transitive dependencies; the Bun updater passes none · source, verified 2026-10-28.

Environment · corepack.defaults ⚠️ disputed

Corepack 0.36.0 runs the version lastKnownGood.json names for a package manager when no package.json above the current folder sets packageManager; without an entry it fetches the latest version of the npm package (yarn: Yarn Classic 1.x, which never reads .yarnrc.yml) and records it there, or with COREPACK_DEFAULT_TO_LATEST=0 uses its built-in default (getDefaultVersion in sources/Engine.ts). The code looks for the home folder in COREPACK_HOME, XDG_CACHE_HOME, LOCALAPPDATA (on every system) and then the home folder, using a variable that is set even when it is empty (??); the README leaves out XDG_CACHE_HOME and LOCALAPPDATA outside Windows. The code is what runs, so depcurfew follows it; the layout is the same since 0.13.0 (sources/folderUtils.ts), before which the folder was ~/.node/corepack. Values carry a hash after + (1.22.22+sha1.ac34...), which is not part of the version.

  • Variant 1: {"since":"0.13.0","locations":[{"platforms":["linux","darwin"],"directories":[{"from":{"env":"COREPACK_HOME","emptyCounts":true},"path":""},{"from":{"env":"XDG_CACHE_HOME","emptyCounts":true},"path":"node/corepack"},{"from":{"env":"LOCALAPPDATA","emptyCounts":true},"path":"node/corepack"},{"from":"home","path":".cache/node/corepack"}],"file":"lastKnownGood.json"},{"platforms":["win32"],"directories":[{"from":{"env":"COREPACK_HOME","emptyCounts":true},"path":""},{"from":{"env":"XDG_CACHE_HOME","emptyCounts":true},"path":"node/corepack"},{"from":{"env":"LOCALAPPDATA","emptyCounts":true},"path":"node/corepack"},{"from":"home","path":"AppData/Local/node/corepack"}],"file":"lastKnownGood.json"}]} · source, verified 2026-11-01. getCorepackHomeFolder: process.env.COREPACK_HOME ?? join(process.env.XDG_CACHE_HOME ?? process.env.LOCALAPPDATA ?? join(homedir(), process.platform === `win32` ? `AppData/Local` : `.cache`), `node/corepack`); sources/Engine.ts reads join(getCorepackHomeFolder(), `lastKnownGood.json`), a JSON object of package manager names and versions.
  • Variant 2: {"since":"0.13.0","locations":[{"platforms":["linux","darwin"],"directories":[{"from":{"env":"COREPACK_HOME"},"path":""},{"from":"home","path":".cache/node/corepack"}],"file":"lastKnownGood.json"},{"platforms":["win32"],"directories":[{"from":{"env":"COREPACK_HOME"},"path":""},{"from":{"env":"LOCALAPPDATA"},"path":"node/corepack"}],"file":"lastKnownGood.json"}]} · source, verified 2026-11-01. "COREPACK_HOME can be set in order to define where Corepack should install the package managers. By default it is set to %LOCALAPPDATA%\node\corepack on Windows, and to $HOME/.cache/node/corepack everywhere else."

Environment · docker.dockerfilePrefix ❓ uncertain

Dockerfile.<name> (Dockerfile.dev) is a common practice, but no Docker documentation that was read mentions it; depcurfew reads such files too, because they are Dockerfiles passed with --file.

  • Dockerfile. · source, verified 2026-11-01.

Environment · docker.nodeImageTags ❓ uncertain

Moving tags on 2026-10-28, when library/node was last generated: lts, lts-<codename>, current, latest and a variant alone (alpine, slim, bookworm) all mean 26.13.0. They move to another line without notice: after 26 became LTS no line is current, and how current and latest resolve once 27 is released is not documented. Tags of lines no longer built (20, iron, 18) are gone from library/node and are not updated any more.

  • {"tags":{"latest":"26","current":"26","lts":"26"}} · source, verified 2026-11-01.

Environment · docker.pythonImageTags ❓ uncertain

On 2026-11-01 latest, 3 and a variant alone (slim, alpine, trixie) mean 3.15.2 (aliases [3.15]='3 latest' in generate-stackbrew-library.sh); they move when a new line is released. X.Y-rc tags are prereleases.

  • {"tags":{"3":"3.15","latest":"3.15"}} · source, verified 2026-11-01.

Environment · npmRegistry.notFoundStatus ❓ uncertain

The API description leaves its Errors section empty; a name that does not exist answered 404 with {"error":"Not found"} on 2026-10-29.

  • 404 · source, verified 2026-10-29.

Environment · npmRegistry.search ❓ uncertain

The description documents text, size (at most 250) and from. Results carried downloads.weekly on 2026-10-29, which the description does not list, and from was ignored, so one query returns at most 250 packages.

  • {"path":"/-/v1/search","maxSize":250,"weeklyDownloadsField":"downloads.weekly"} · source, verified 2026-10-29.

Environment · claudeCode.hookContext ❓ uncertain

The PreToolUse decision control table lists additionalContext in hookSpecificOutput as "String added to Claude's context alongside the tool result. Ignored when permissionDecision is "defer"", next to permissionDecision, permissionDecisionReason and updatedInput, and #add-context-for-claude says Claude Code wraps the string in a system reminder that Claude reads on the next model request, places it next to the tool result for PreToolUse, writes a value over 10,000 characters to a file and passes its path with a preview of 2,000 characters, and recommends factual statements over imperative instructions. Uncertain: the page does not say in so many words that additionalContext works without permissionDecision; the table ties it to no decision but defer, and an output without permissionDecision leaves the call to the normal permission flow.

  • {"field":"additionalContext","withoutDecision":true,"inlineLimit":10000} · source, verified 2026-11-01.