| 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. |
Fix Dependency Vulnerability
Overview
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.
Required Inputs
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, or 2.3.2.
If either value is missing, ask for it and stop until the user answers.
Workflow
- 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.json or npm-shrinkwrap.json: npm.
yarn.lock: Yarn.
packageManager in the nearest package.json can confirm the exact manager/version.
- Search every lockfile for the vulnerable package. Use
rg or grep; 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, or pnpm.overrides entries 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.json files 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, or npm 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.json provides one.
- Report each completed step and provide the complete list of directories where package files or lockfiles were updated.
Remediation Fields
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.
Install Commands
Run installs sequentially in the affected directories:
- pnpm:
pnpm install --dir <affected-directory> or run pnpm install inside that directory if this matches the repo convention.
- npm:
npm install --prefix <affected-directory> or run npm install inside that directory.
- Yarn: run
yarn install inside the affected directory.
Do not run installs in parallel; lockfile updates should be serialized.
Helper Script
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-run prints affected lockfiles, package manifests, package managers, and planned manifest entries without editing files.
--manager pnpm|npm|yarn overrides package-manager detection when a repo has unusual lockfile conventions.
--broad writes one package-name entry instead of exact package@version selectors where exact selectors are otherwise supported.
--all-majors allows 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.
Final Response Checklist
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.