Terminal.skills
Use Cases/Automate Dependency Updates and Catch Breaking Changes with AI

Automate Dependency Updates and Catch Breaking Changes with AI

Scan your project for outdated dependencies, detect breaking changes before they hit production, and generate safe upgrade plans.

Development#dependencies#npm#security#upgrades#semver
Works with:claude-codeopenai-codexgemini-clicursor
$

The Problem

Priya's Node.js project has 187 dependencies. Dependabot opens 15 PRs a week that nobody reviews — they pile up in the queue like unread emails, each one a small gamble between "safe patch" and "subtle breaking change." Three packages are 2 major versions behind. Last time someone batch-upgraded everything on a Friday afternoon, the app broke in production because a library changed its API in a patch release without documenting it. The rollback took 40 minutes and ruined the weekend.

Now the team is afraid to update anything. Six packages have known CVEs sitting in the backlog under a Jira ticket labeled "tech debt — Q3." The security team flags it every quarter. Engineering says they will get to it next sprint. Nobody does.

The worst part is that nobody knows which updates are safe. A minor version bump in stripe might just add a new method, or it might change how webhook signatures are verified. Without reading every changelog line by line — and cross-referencing each change against the actual codebase — the only way to find out is to upgrade and pray.

The Solution

Using the dependency-updater and code-migration skills, the agent audits the full dependency tree, cross-references changelogs against the actual codebase to identify which breaking changes affect specific files, and generates migration code for API differences. CVE patches ship first because they rarely change APIs. Then major upgrades go one at a time with tested migration code, so any breakage points to exactly one package.

Step-by-Step Walkthrough

Step 1: Audit Dependency Health

Priya starts with a full picture of what she is working with:

Analyze our package.json and package-lock.json. Show me every outdated dependency grouped by risk level: critical (known CVEs), major (breaking version jump), minor (safe to update), and pinned (intentionally locked). Include how far behind each one is.

The audit groups 187 packages into four buckets:

Critical (Known Vulnerabilities) — update immediately:

PackageCurrentLatestCVESeverity
jsonwebtoken8.5.19.0.2CVE-2022-23529HIGH
axios0.21.41.7.2CVE-2023-45857MEDIUM
semver6.3.07.6.0CVE-2022-25883MEDIUM

Major (Breaking Changes) — review required:

PackageCurrentLatestKey Changes
next13.4.1214.2.3App Router changes, Middleware API update
prisma4.16.25.14.0New client API, changed relation loading
stripe12.18.015.8.0Webhook handler signature changed

Minor/Patch (Safe): 34 packages with backward-compatible updates. These can be batch-updated with minimal risk.

Pinned: 3 packages locked with exact versions. sharp@0.32.1 is pinned due to native build issues on ARM — the newer versions break on the team's M1 Macs. The pin has a comment explaining why, and the issue is tracked upstream.

Step 2: Get a Detailed Breaking Change Report

The raw version numbers are useful but not actionable. Priya needs to know exactly what code in her project will break, and where:

For the three MAJOR packages (next, prisma, stripe), show me exactly what APIs changed between our version and the latest. Check our codebase for files that use the affected APIs.

The report cross-references changelogs with actual source files:

next 13.4.12 to 14.2.3:

  • NextResponse.rewrite() signature changed — 2 files affected (src/middleware.ts lines 12 and 34, both using the old single-argument pattern)
  • Image component layout prop removed, replaced by fill8 files affected across the dashboard and marketing pages
  • Minimum React version 18.2.0 — already satisfied, no change needed

prisma 4.16.2 to 5.14.0:

  • findUnique no longer accepts rejectOnNotFound14 files affected
  • JSON protocol is now default — no code change needed
  • Import paths unchanged

stripe 12.18.0 to 15.8.0:

  • Constructor no longer accepts apiVersion in options — 1 file affected (src/lib/stripe.ts)
  • stripe.webhooks.constructEvent() — unchanged, which is a relief since this handles payment processing
  • 12 type names renamed with Stripe. prefix — 6 files affected in type definitions

This is where the automation pays for itself. The Prisma change touches 14 files, but scanning the actual code shows that 12 of them are the exact same one-line pattern: findUnique({ where: ..., rejectOnNotFound: true }) becomes findUniqueOrThrow({ where: ... }). A mechanical find-and-replace handles 86% of the affected files.

Step 3: Generate the Upgrade Plan and Migration Code

Create a safe upgrade plan with the exact order to update packages. For each major upgrade, generate the migration code diffs. Start with the CVE fixes since those are low-risk, then handle the major bumps one at a time.

The plan sequences upgrades to minimize risk:

  1. CVE patches firstjsonwebtoken, axios, semver. These rarely change APIs (the CVE in jsonwebtoken is an exception — it requires adding the algorithms option).
  2. Prisma — the most files touched, but the most mechanical migration. One automated script handles 12 of 14 files.
  3. Stripe — mostly type renames, low runtime risk.
  4. Next.js — the most complex upgrade, saved for last when everything else is stable.

Each major upgrade comes with a generated diff showing every file change, so Priya can review the migration before applying it.

Step 4: Apply and Verify

Apply the CVE fixes first — update jsonwebtoken, axios, and semver. Show me the exact npm commands and any code changes needed. Then run the existing test suite to confirm nothing broke.

The jsonwebtoken upgrade from 8.x to 9.x requires one code change: the algorithms option is now required when verifying tokens. This is the security hardening that the CVE was about — without specifying algorithms: ['HS256'], an attacker could force the library to use a weaker algorithm. The fix is one line, but it is the line that makes the CVE meaningful.

The axios and semver upgrades are drop-in replacements — version bumps with no code changes needed. All three CVE fixes are committed, tests pass, and the patch ships to production by lunch.

Step 5: Set Up Continuous Dependency Monitoring

After the one-time cleanup, a weekly automated check prevents the backlog from growing again. The goal is simple: never let CVEs sit for 8 months again.

Create a weekly automated check that scans for new CVEs in our current dependencies and alerts us in Slack if anything critical appears. Also flag any dependency that becomes deprecated or unmaintained. Generate the GitHub Action workflow for this.
yaml
# .github/workflows/dependency-monitor.yml
name: Weekly Dependency Check
on:
  schedule:
    - cron: '0 9 * * 1'  # Every Monday 9 AM UTC
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm audit --json > audit-results.json
      - name: Check for critical vulnerabilities
        run: |
          CRITICAL=$(jq '.vulnerabilities | to_entries[] | select(.value.severity == "critical") | .key' audit-results.json)
          if [ -n "$CRITICAL" ]; then
            curl -X POST $SLACK_WEBHOOK -d "{\"text\":\"Critical CVEs found: $CRITICAL\"}"
          fi

The workflow also checks for deprecated packages and flags any dependency that has not had a commit in over a year. These are the packages that silently become liabilities — no CVEs yet, but no security patches either.

Real-World Example

Priya runs the full workflow on a Tuesday morning. The audit takes 30 seconds and reveals 6 CVEs, 11 major updates pending, and 3 packages that are completely unmaintained — one of them has not had a commit in 2 years and its GitHub repo is archived.

The CVE patches go in first: three version bumps and one one-line code change for the jsonwebtoken algorithms option. Tests pass. She ships it to production by lunch. The security team's quarterly flag is resolved before it even comes up.

The Prisma upgrade is next. The breaking change scan shows 14 affected files, but the migration script handles 12 of them automatically — it is the same rejectOnNotFound to findUniqueOrThrow swap repeated across the codebase. Priya manually adjusts the remaining 2 files where the query pattern is slightly different. The Next.js upgrade needs 2 manual fixes for the middleware rewrite pattern. Stripe takes 20 minutes for the type renames.

Total time: 3 hours instead of the 2 weeks the team had budgeted. Zero production incidents from the upgrade. And the Monday morning Slack alert means the next CVE gets caught within a week instead of sitting in a backlog for 8 months.