Bump Dependency
SkillSecurityResearch and safely apply npm dependency version bumps across the Plumber monorepo (root, backend, frontend, types). Use when the user asks to bump/update/upgrade a package, asks whether a version bump has breaking changes, or wants a dependency security patch applied.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Bump Dependency skill
What this skill tells your AI
The instructions your AI receives, as published by opengovsg/plumber in .claude/skills/bump-dependency/SKILL.md and read by ahel’s review.
Safely evaluate and apply a dependency version bump. Never skip the research and impact-check steps, even for "just a patch" bumps.
Step 0 — Resolve the package name and target version
The invocation argument (e.g. /bump-dependency <name>) is the literal
package name — take it at face value and confirm it with grep/npm ls
before interpreting it any other way. Don't let recent conversation
context reinterpret it (e.g. a bare word that also reads as an ordinary
English adjective, or resembles a package discussed earlier in the
session) — verify against package.json/package-lock.json first.
Don't ask the user for a target version up front. Resolve it yourself:
- Run
npm audit --jsonat the repo root. If the package shows up with a recommended fix (fixAvailable), that recommended version is the default target — even if it's a major bump, since it's the minimum needed to clear the advisory. - If the package isn't flagged by
npm audit, prefer staying within the current major version line: use the latest minor/patch release on that line (npm view <package>@<current-major> version, or the highest entry for that major fromnpm view <package> versions --json) as the default target, not the absolute latest major. Only reach past the current major if the user explicitly asks for the newest version or there's a concrete reason the current major can't be kept (e.g. it's deprecated/unsupported upstream). - Either way, proceed straight into Step 1–4 research/impact-check using that resolved target — only surface the version as an explicit decision point in Step 4 if it turns out to be a major bump over the current version (major bumps carry real migration risk and are worth a deliberate go/no-go from the user; patch/minor bumps aren't).
Step 1 — Classify the dependency
Check whether the package is direct or transitive:
- Direct: listed in
dependencies/devDependenciesof the root or anypackages/*/package.json, pinned to an exact version (no^/~). - Transitive: only appears in
package-lock.json(confirm withnpm ls <package> --all), not declared in anypackage.json— it may already have an entry in the rootpackage.jsonoverridesblock if a prior bump pinned it there.
Step 2 — Research breaking changes
For the version range being bumped (current → target), find and summarize:
- Official changelog / release notes (GitHub releases,
CHANGELOG.md). - Any security advisories (GHSA/CVE) fixed in the range — note the CVE ID.
- Actual breaking API changes vs. pure internal/security/perf fixes. Read more than just the target version — check every version in between, since intermediate releases can carry the real breaking change.
Use WebFetch/WebSearch for this. Don't rely on memory — package
changelogs are outside training-data-freshness territory.
Step 3 — Check repo impact (always, no exceptions)
Spawn an Explore (or general-purpose) agent to search
packages/*/src (excluding node_modules/dist) for direct
imports/requires and call sites of the package. Ask it to:
- Report whether usage is direct or purely transitive-through-tooling.
- For each call site, check whether the specific behavior changes from Step 2 (not generic "could this break something") actually apply to the input that call site handles.
- Suggest concrete manual/automated tests if there's real exposure.
If the package is confirmed transitive-only (e.g. pulled in by eslint, graphql-codegen, dd-trace, jest), say so plainly — no first-party call sites means the changelog risk doesn't apply to Plumber's own logic, even if the CVE itself sounds scary.
Step 4 — Report and wait
Present to the user: what changed in the version range, whether Plumber
code is exposed, and recommended verification (npm run lint, npm test,
specific manual checks). Do not proceed to Step 5 without the user
asking you to apply/bump/commit it.
Step 5 — Apply the bump (only after the user asks)
Direct dependency:
- Edit the exact
package.json(root or the owning workspace) to the new version. Always pin exact ("1.9.0", never"^1.9.0"or"~1.9.0") — this repo always pins. Usenpm install -Eif installing rather than hand-editing. - Ask explicit confirmation before running
npm install. Never run it unprompted, even after the user approved the bump itself in Step 4 — approving the bump is not the same as approving the command.
Transitive dependency:
- Prefer
npm update <package>first — it stays within whatever range the parent dependency already declares. - If the target patched version is outside that range (common for
security backports), add/update an exact-pinned entry for it under the
root
package.json"overrides"block instead, then apply vianpm install. npm updateandnpm installeach require their own explicit confirmation before running — never run either unprompted, and don't treat approval of one as approval of the other.
Step 6 — Commit (only after explicit confirmation)
- Never commit a dependency bump unprompted, even right after applying it.
- Before committing, run
git status+git diff --statand confirm the diff is scoped to exactly the intendedpackage.json/package-lock.jsonchanges — nothing unrelated got swept in. - Commit message: what was bumped, the CVE/behavior-change summary from
Step 2, one line on why it's safe (from Step 3). End with
Co-Authored-By:using the current session's actual model name — never copy this line from a prior commit in git history.
Quick reference
| Situation | Command |
|---|---|
| Confirm direct vs transitive | npm ls <package> --all |
| Bump transitive within existing range | npm update <package> |
| Force transitive past declared range | pin in root overrides, then npm install |
| Bump direct dependency | edit exact version in package.json, then npm install |
Signals
- GitHub stars
- 27
- Forks
- 15
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
bump-dependency- Source
- github.com/opengovsg/plumber