Index: node_modules/semver/README.md
===================================================================
--- node_modules/semver/README.md	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/README.md	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -57,4 +57,5 @@
 const semverSort = require('semver/functions/sort')
 const semverRsort = require('semver/functions/rsort')
+const semverTruncate = require('semver/functions/truncate')
 
 // low-level comparators between versions
@@ -400,9 +401,16 @@
 caret      ::= '^' partial
 qualifier  ::= ( '-' pre )? ( '+' build )?
-pre        ::= parts
-build      ::= parts
-parts      ::= part ( '.' part ) *
-part       ::= nr | [-0-9A-Za-z]+
-```
+pre        ::= prepart ( '.' prepart ) *
+prepart    ::= nr | alphanumid
+build      ::= buildid ( '.' buildid ) *
+alphanumid ::= ( ['0'-'9'] ) * [-A-Za-z] [-0-9A-Za-z] *
+buildid    ::= [-0-9A-Za-z]+
+```
+
+Note: Prerelease identifiers (`pre`) use `nr` for numeric parts, which
+disallows leading zeros (e.g., `1.2.3-00` is invalid). Build metadata
+identifiers (`build`) allow any alphanumeric string including leading
+zeros (e.g., `1.2.3+00` is valid). This matches the
+[SemVer 2.0.0 specification](https://semver.org/#spec-item-9).
 
 ## Functions
@@ -450,4 +458,10 @@
 * `parse(v)`: Attempt to parse a string as a semantic version, returning either
   a `SemVer` object or `null`.
+* `truncate(v, releaseType)`: Return the version with components _lower_
+  than `releaseType` dropped off, e.g.:
+  * `major` removes build & prerelease info and sets minor & patch to 0.
+  * `minor` removes build & prerelease info, and sets patch to 0
+  * `patch` removes build & prerelease info
+  * All prerelease types remove build info only
 
 ### Comparison
@@ -651,4 +665,5 @@
 * `require('semver/functions/satisfies')`
 * `require('semver/functions/sort')`
+* `require('semver/functions/truncate')`
 * `require('semver/functions/valid')`
 * `require('semver/ranges/gtr')`
Index: node_modules/semver/classes/range.js
===================================================================
--- node_modules/semver/classes/range.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/classes/range.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -99,4 +99,7 @@
 
   parseRange (range) {
+    // strip build metadata so it can't bleed into the version
+    range = range.replace(BUILDSTRIPRE, '')
+
     // memoize range parsing for performance.
     // this is a very hot path, and fully deterministic.
@@ -224,4 +227,5 @@
 const {
   safeRe: re,
+  src,
   t,
   comparatorTrimReplace,
@@ -230,4 +234,7 @@
 } = require('../internal/re')
 const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants')
+
+// unbounded global build-metadata stripper used by parseRange
+const BUILDSTRIPRE = new RegExp(src[t.BUILD], 'g')
 
 const isNullSet = c => c.value === '<0.0.0-0'
@@ -271,4 +278,9 @@
 const isX = id => !id || id.toLowerCase() === 'x' || id === '*'
 
+const invalidXRangeOrder = (M, m, p) => (
+  (isX(M) && !isX(m)) ||
+  (isX(m) && p && !isX(p))
+)
+
 // ~, ~> --> * (any, kinda silly)
 // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0
@@ -288,4 +300,8 @@
 const replaceTilde = (comp, options) => {
   const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
+  // if we're including prereleases in the match, then the lower bound is
+  // -0, the lowest possible prerelease value, just like x-ranges and carets.
+  // this keeps `~1.2` equivalent to the `1.2.x` x-range it's documented as.
+  const z = options.includePrerelease ? '-0' : ''
   return comp.replace(r, (_, M, m, p, pr) => {
     debug('tilde', comp, _, M, m, p, pr)
@@ -295,8 +311,8 @@
       ret = ''
     } else if (isX(m)) {
-      ret = `>=${M}.0.0 <${+M + 1}.0.0-0`
+      ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`
     } else if (isX(p)) {
       // ~1.2 == >=1.2.0 <1.3.0-0
-      ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`
+      ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`
     } else if (pr) {
       debug('replaceTilde pr', pr)
@@ -367,8 +383,8 @@
         if (m === '0') {
           ret = `>=${M}.${m}.${p
-          }${z} <${M}.${m}.${+p + 1}-0`
+          } <${M}.${m}.${+p + 1}-0`
         } else {
           ret = `>=${M}.${m}.${p
-          }${z} <${M}.${+m + 1}.0-0`
+          } <${M}.${+m + 1}.0-0`
         }
       } else {
@@ -396,4 +412,8 @@
   return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
     debug('xRange', comp, ret, gtlt, M, m, p, pr)
+    if (invalidXRangeOrder(M, m, p)) {
+      return comp
+    }
+
     const xM = isX(M)
     const xm = xM || isX(m)
Index: node_modules/semver/classes/semver.js
===================================================================
--- node_modules/semver/classes/semver.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/classes/semver.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -7,4 +7,20 @@
 const parseOptions = require('../internal/parse-options')
 const { compareIdentifiers } = require('../internal/identifiers')
+
+const isPrereleaseIdentifier = (prerelease, identifier) => {
+  const identifiers = identifier.split('.')
+  if (identifiers.length > prerelease.length) {
+    return false
+  }
+
+  for (let i = 0; i < identifiers.length; i++) {
+    if (compareIdentifiers(prerelease[i], identifiers[i]) !== 0) {
+      return false
+    }
+  }
+
+  return true
+}
+
 class SemVer {
   constructor (version, options) {
@@ -310,6 +326,7 @@
             prerelease = [identifier]
           }
-          if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
-            if (isNaN(this.prerelease[1])) {
+          if (isPrereleaseIdentifier(this.prerelease, identifier)) {
+            const prereleaseBase = this.prerelease[identifier.split('.').length]
+            if (isNaN(prereleaseBase)) {
               this.prerelease = prerelease
             }
Index: node_modules/semver/functions/truncate.js
===================================================================
--- node_modules/semver/functions/truncate.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
+++ node_modules/semver/functions/truncate.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -0,0 +1,48 @@
+'use strict'
+
+const parse = require('./parse')
+const constants = require('../internal/constants')
+const SemVer = require('../classes/semver')
+
+const truncate = (version, truncation, options) => {
+  if (!constants.RELEASE_TYPES.includes(truncation)) {
+    return null
+  }
+
+  const clonedVersion = cloneInputVersion(version, options)
+  return clonedVersion && doTruncation(clonedVersion, truncation)
+}
+
+const cloneInputVersion = (version, options) => {
+  const versionStringToParse = (
+    version instanceof SemVer ? version.version : version
+  )
+
+  return parse(versionStringToParse, options)
+}
+
+const doTruncation = (version, truncation) => {
+  if (isPrerelease(truncation)) {
+    return version.version
+  }
+
+  version.prerelease = []
+
+  switch (truncation) {
+    case 'major':
+      version.minor = 0
+      version.patch = 0
+      break
+    case 'minor':
+      version.patch = 0
+      break
+  }
+
+  return version.format()
+}
+
+const isPrerelease = (type) => {
+  return type.startsWith('pre')
+}
+
+module.exports = truncate
Index: node_modules/semver/index.js
===================================================================
--- node_modules/semver/index.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/index.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -29,4 +29,5 @@
 const cmp = require('./functions/cmp')
 const coerce = require('./functions/coerce')
+const truncate = require('./functions/truncate')
 const Comparator = require('./classes/comparator')
 const Range = require('./classes/range')
@@ -67,4 +68,5 @@
   cmp,
   coerce,
+  truncate,
   Comparator,
   Range,
Index: node_modules/semver/internal/re.js
===================================================================
--- node_modules/semver/internal/re.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/internal/re.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -137,5 +137,5 @@
 
 // Something like "2.*" or "1.2.x".
-// Note that "x.x" is a valid xRange identifer, meaning "any version"
+// Note that "x.x" is a valid xRange identifier, meaning "any version"
 // Only the first item is strictly required.
 createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`)
Index: node_modules/semver/package.json
===================================================================
--- node_modules/semver/package.json	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/package.json	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -1,5 +1,5 @@
 {
   "name": "semver",
-  "version": "7.7.4",
+  "version": "7.8.5",
   "description": "The semantic version parser used by npm.",
   "main": "index.js",
@@ -15,6 +15,6 @@
   },
   "devDependencies": {
-    "@npmcli/eslint-config": "^6.0.0",
-    "@npmcli/template-oss": "4.29.0",
+    "@npmcli/eslint-config": "^7.0.0",
+    "@npmcli/template-oss": "5.0.0",
     "benchmark": "^2.1.4",
     "tap": "^16.0.0"
@@ -53,5 +53,5 @@
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.29.0",
+    "version": "5.0.0",
     "engines": ">=10",
     "distPaths": [
Index: node_modules/semver/range.bnf
===================================================================
--- node_modules/semver/range.bnf	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/range.bnf	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -11,6 +11,7 @@
 caret      ::= '^' partial
 qualifier  ::= ( '-' pre )? ( '+' build )?
-pre        ::= parts
-build      ::= parts
-parts      ::= part ( '.' part ) *
-part       ::= nr | [-0-9A-Za-z]+
+pre        ::= prepart ( '.' prepart ) *
+prepart    ::= nr | alphanumid
+build      ::= buildid ( '.' buildid ) *
+alphanumid ::= ( [0-9] ) * [A-Za-z-] [-0-9A-Za-z] *
+buildid    ::= [-0-9A-Za-z]+
Index: node_modules/semver/ranges/subset.js
===================================================================
--- node_modules/semver/ranges/subset.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/semver/ranges/subset.js	(revision 6c7cfa631d14a25615bca6e638d689aaeb21e1a2)
@@ -175,5 +175,5 @@
           return false
         }
-      } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) {
+      } else if (gt.operator === '>=' && !c.test(gt.semver)) {
         return false
       }
@@ -193,5 +193,5 @@
           return false
         }
-      } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) {
+      } else if (lt.operator === '<=' && !c.test(lt.semver)) {
         return false
       }
