| name | fix-cve-dep |
| description | Upgrade a vulnerable npm dependency end-to-end — version bump, resolutions pin, yarn install, license regeneration, and commit. Invoke for any CVE, security advisory, or dependency vulnerability ticket (Jira CRW-*, GHSA-*, or a user request to "fix the X vulnerability" or "upgrade Y for security"). Handles ClearlyDefined indexing checks, .deps/ file updates, and produces a properly formatted commit automatically. |
| argument-hint | [package-name] [fix-version] [jira-ticket] |
Fix CVE Dependency Upgrade
Required input
- Package name (e.g.
axios, ws, ip-address)
- Minimum fix version from the CVE description
- Jira ticket ID (e.g.
CRW-11204)
If $ARGUMENTS is missing fields, extract them from context (open Jira ticket, branch name, etc.).
Workflow
1. Check current version
grep -A 3 '"<package>@npm' yarn.lock | head -6
If current ≥ fix version, document as already fixed and stop.
2. Find the best upgrade target
Pick the latest indexed version, not just the minimum fix version:
yarn npm info <package> dist-tags 2>/dev/null | grep latest
For each candidate (latest, latest-1, fix-version), check ClearlyDefined score:
curl -s --max-time 10 \
"https://api.clearlydefined.io/definitions/npm/npmjs/-/<package>/<version>" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('scores',{}).get('effective',0), d.get('licensed',{}).get('declared','?'))"
Choose the highest-versioned package with score > 0 and a resolved SPDX license. A newer un-indexed version resolves via semver (^) and breaks yarn license:generate — pin the exact indexed version.
3. Update package.json
Update in ALL locations:
- Root
package.json → resolutions field (exact version, e.g. "<package>": "1.16.1")
- Any workspace
package.json with it as a direct dep (update range, e.g. "<package>": "^1.16.1")
grep -rn '"<package>"' packages/*/package.json package.json
Pinning rules:
- Use exact version (no
^) in resolutions to prevent resolution to newer un-indexed versions
- For packages crossing a major semver boundary (e.g.
^9.x → 10.x), the resolutions override is mandatory
4. Reinstall and verify
yarn install
grep -A 2 '"<package>@npm' yarn.lock | head -4
5. Regenerate license files
yarn license:generate
If UNRESOLVED exits:
Check ClearlyDefined individually:
curl -s --max-time 10 \
"https://api.clearlydefined.io/definitions/npm/npmjs/-/<dep>/<version>" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('scores',{}).get('effective',0), d.get('licensed',{}).get('declared','?'))"
- Score > 0: batch API timed out — retry (usually succeeds on attempt 2–4)
- Score = 0: not yet indexed — add to
.deps/EXCLUDED/prod.md (runtime) or .deps/EXCLUDED/dev.md (dev only):
| `<package>@<version>` | [clearlydefined](https://clearlydefined.io/definitions/npm/npmjs/-/<package>/<version>) |
Then re-run yarn license:generate.
6. Verify
yarn license:check
7. Commit
git add package.json packages/*/package.json yarn.lock \
.deps/dev.md .deps/prod.md .deps/EXCLUDED/dev.md .deps/EXCLUDED/prod.md
Commit message:
fix(deps): upgrade <package> to <version> to fix <vulnerability-type> (<JIRA>)
<Package> versions prior to <fix-version> <vulnerability description>.
Upgrade from <old-version> to <new-version> (pinned in resolutions) and
regenerate license dependency files.
CVE reference: <CVE-ID or GHSA>
Fixed in: <package> <fix-version>
Assisted-by: {AGENT_NAME}
Signed-off-by: {AUTHOR_NAME} <{AUTHOR_EMAIL}>
8. Push
git push -u origin <branch>
Special cases
Package crosses major semver boundary (e.g. 9.x → 10.x)
The fix version exceeds the range declared by transitive dependents ("ip-address": "^9.0.5" won't accept 10.x). Add a hard pin:
"ip-address": "10.2.0"
Multiple CVEs in one PR
Fix all packages in a single commit; list each in the commit body:
1. <package-a> — fixes <type> (CRW-XXXXX)
2. <package-b> — fixes <type> (CRW-XXXXX)
ClearlyDefined batch API failures
The batch API sometimes returns HTTP 502 or times out. Always retry before adding packages to EXCLUDED. Usually succeeds on attempt 2–4.