| name | fix-dependency-vulnerability |
|---|---|
| description | Resolve dependency vulnerability alerts in package-managed repositories by identifying the vulnerable package and target fixed version, finding every relevant nested lockfile, determining the package manager and matching package.json remediation field, updating overrides or resolutions, regenerating lockfiles one affected directory at a time, and reporting all changed directories. Use when the user mentions a vulnerable npm/package dependency, dependency bump, package-manager override, lockfile update, or security alert remediation. |
Use this skill to remediate a vulnerable package managed by a repository package manager. Detect the package manager from lockfiles and manifests, prefer the highest safe fix in the dependency tree, avoiding major version changes unless explicitly requested, update every affected project, then regenerate lockfiles sequentially.
Before changing files, make sure these are known:
- Vulnerable package name, such as
picomatch. - Target version or range, such as
4.0.4,^4.0.4, or2.3.2.
If either value is missing, ask for it and stop until the user answers.
- Confirm the package and target version in your own words.
- Find all lockfiles first, including nested lockfiles:
rg --files -g 'pnpm-lock.yaml' -g 'package-lock.json' -g 'npm-shrinkwrap.json' -g 'yarn.lock'- Determine the package manager for each lockfile:
pnpm-lock.yaml: pnpm.package-lock.jsonornpm-shrinkwrap.json: npm.yarn.lock: Yarn.packageManagerin the nearestpackage.jsoncan confirm the exact manager/version.
- Search every lockfile for the vulnerable package. Use
rgorgrep; do not inspect only top-level directories. - For each matching lockfile, locate its corresponding
package.json. Prefer the same directory as the lockfile; if missing, walk up to the nearest ancestor package manifest. - Inspect matching lockfile entries to identify concrete resolved versions where possible. When the requested target is a concrete semantic version, only update resolved versions in the same major version unless the user explicitly says to update all majors.
- Walk up the dependency chain before adding overrides. If a direct dependency or a nearer parent dependency has a safe non-major update that removes the vulnerable transitive version, prefer that over adding a new override or resolution.
- Inspect existing
overrides,resolutions, orpnpm.overridesentries before choosing the fix. If the repo already pins the vulnerable package or a relevant parent package, update that existing pin first or in tandem. If a parent dependency bump removes the need for an existing remediation pin, remove the obsolete pin instead of carrying it forward. - Update all affected
package.jsonfiles before running installs. - Preserve existing override or resolution entries while adding or changing the vulnerability entry.
- Run the package-manager install command sequentially, one affected directory at a time, after all manifests have been updated.
- Verify the final resolved version, not just the manifest change. Check the lockfile and use the package-manager graph tool where helpful, such as
yarn why,pnpm why, ornpm ls. When a parent bump replaced an override-based fix, confirm the graph stays clean without the old override or resolution. - Run the appropriate repo test command if
package.jsonprovides one. - Report each completed step and provide the complete list of directories where package files or lockfiles were updated.
Use the package manager's native package manifest field:
- pnpm:
pnpm.overrides. - npm: top-level
overrides. - Yarn: top-level
resolutions.
Prefer fixing the issue higher in the tree when it is safe to do so:
- First choice: bump the direct dependency that brings in the vulnerable package, if a safe compatible release already fixes the transitive.
- Second choice: bump an existing nearer parent dependency that removes the vulnerable transitive version.
- Last choice: add or change an override or resolution for the vulnerable leaf package.
Do not add a new override or resolution until you have checked whether a parent-package update would remove the vulnerable version with fewer long-term pins.
If a direct or parent dependency bump fully removes the vulnerable transitive version, prefer deleting the now-unneeded override or resolution rather than leaving a stale pin behind.
Prefer exact selectors when the lockfile reveals vulnerable resolved versions and the package manager supports them:
{
"pnpm": {
"overrides": {
"picomatch@4.0.3": "4.0.4"
}
}
}For npm, a broad override is often the portable form:
{
"overrides": {
"picomatch": "4.0.4"
}
}Use a broad override or resolution only when exact selectors are unsupported, the user explicitly asks for a broad override, the repo already uses that pattern for the same alert, or the lockfile does not reveal a specific resolved version. Avoid unintentionally forcing unrelated older major versions to a newer major.
If multiple vulnerable versions are present across majors and the target version is not safe for all majors, update only the matching major and tell the user which versions were skipped. Pause and ask for the intended target per skipped major if the alert still requires those versions to be remediated.
Run installs sequentially in the affected directories:
- pnpm:
pnpm install --dir <affected-directory>or runpnpm installinside that directory if this matches the repo convention. - npm:
npm install --prefix <affected-directory>or runnpm installinside that directory. - Yarn: run
yarn installinside the affected directory. Do not run installs in parallel; lockfile updates should be serialized.
Use scripts/update_dependency_remediation.py to perform lockfile discovery and manifest updates consistently:
python3 .codex/skills/fix-dependency-vulnerability/scripts/update_dependency_remediation.py picomatch 4.0.4 --root .Useful options:
--dry-runprints affected lockfiles, package manifests, package managers, and planned manifest entries without editing files.--manager pnpm|npm|yarnoverrides package-manager detection when a repo has unusual lockfile conventions.--broadwrites one package-name entry instead of exactpackage@versionselectors where exact selectors are otherwise supported.--all-majorsallows exact selectors across all discovered versions instead of filtering to the target version's major.
After the script updates manifests, run installs manually and sequentially in the directories it reports.
The helper script updates remediation fields consistently, but it does not decide whether a parent dependency bump is better than a leaf-package override. Make that decision before running installs.
Include:
- Vulnerable package and target version.
- Lockfiles checked and lockfiles containing the package.
- Package manager detected for each affected directory.
- Package manifests updated.
- Install commands run, with success or failure.
- Final resolved version confirmed, with the check used.
- Test command run, with success or failure.
- Complete list of directories where updates were made.