All jobs

Fix Vulnerable Dependencies in a Node.js App

Yes. An agent clears the npm audit advisories in your Node.js app with the smallest safe upgrades and opens a PR that still passes tests.

Run this on RushIn a Project that has your repository.

What the agent does

The agent clones the app into its own cloud sandbox and reads what it is working with before it changes anything. In an Express app like OWASP/NodeGoat, package.json pins Express 4, the Mongo driver 2, marked 0.3.5 and a Grunt-based toolchain, and ships a v2 package-lock.json, so its lockfile carries known advisories today. The agent installs the dependencies, runs npm audit to get the starting list, and runs the test task once (the test script runs Grunt's mocha suite) so a later failure can be told apart from one that was already there.

Then it works the advisories one at a time, smallest safe upgrade first. For a direct dependency it bumps to the lowest version that clears the advisory without crossing a major boundary it cannot justify; for a transitive one reached only through another package it reaches for an overrides entry rather than forcing an unrelated direct bump. It records for each advisory which package moved, from which version to which, and whether the fix was a direct upgrade or an override.

After each change it reinstalls and runs the suite again. NodeGoat's toolchain is old, so some bumps move a package far enough that the build or a test reacts; the agent keeps a change only when the suite still passes, and backs out an upgrade that breaks it, reporting that one as needing a person rather than leaving it half-applied. Where a direct bump is blocked by a peer range, it notes the chain instead of guessing.

When the advisories are worked through it runs npm audit again to capture the ending state, commits the changed package.json and lockfile, and opens a pull request. The description carries both audit outputs, before and after, and the per-advisory list of what moved, so a reviewer sees what was cleared and what, if anything, could not be without a larger change.

Start it with one API call

POST https://api.prix.dev/o/{org}/sessions with this body:

{
  "agent": "claude",
  "input": "Run npm audit. For each advisory, apply the smallest upgrade that fixes it, preferring a direct bump and using overrides only for a transitive dependency with no direct upgrade. Reinstall and run the test suite after each change; back out any upgrade that breaks the build or the tests and note it as needing a person. Run npm audit again, then open a pull request whose description carries both audit outputs and a list of each package that moved, from which version to which.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
  1. Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
  2. Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
  3. Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

What comes back

What comes back is a pull request against the repository, its diff the changed package.json and the v2 lockfile. The description sets the two npm audit outputs side by side, before and after, with a list of each package that moved, its old and new version, and whether a direct upgrade or an override cleared it. The two audit outputs are what a reviewer reads first to see which advisories actually closed.

The session transcript keeps every command in order: the first install, the opening audit, then the reinstall and mocha run after each bump, and the closing audit. An upgrade backed out because it broke the build or a test appears as a needs-a-person item, with the error and any peer-range chain that blocked it, so a hard case on this old toolchain is named rather than quietly skipped.

Before merging, the reviewer confirms the suite the agent ran reaches the code the bumps touched, that no override is papering over a package that really needs a direct upgrade, and that any advisory still open is one they accept. The sandbox still holds the installed project, so a follow-up to the same session can ask the agent to take on a blocked upgrade together with the code changes it requires.

Run it on every a new advisory published against a pinned package

Run it when a new advisory lands, not only on a calendar. A small job on your server that watches the GitHub Advisory Database or the npm feed for the packages your lockfile pins can send this request the moment one of them gets a report, so the fix is in review the same day the advisory is public rather than at the next weekly sweep.

A weekly schedule works too for a slower cadence: an automation with a Monday schedule trigger sends the same request, each run starting from a fresh clone of the default branch so the audit reflects that week's lockfile. Set a webhook URL on the API key and Rush POSTs run.completed with the session_url and the pull request, so your server routes a real fix to a reviewer and drops a run that found nothing.

The use case this job follows, with its automation and trigger: Upgrade dependencies weekly.

Why run it on Rush?

An Express app with a Grunt toolchain and a years-old lockfile is exactly where a by-hand audit sweep stalls: a bump reinstalls slowly, trips a peer range, and leaves the machine in a state you have to undo. In a Rush sandbox the agent absorbs all of that on its own disk, reinstalling and rerunning the mocha suite as many times as the advisories need, while your checkout and global Node version stay as they were.

The reviewer's decision rests on the two audit outputs and the test runs, all kept in the transcript and the pull request description, so clearing an advisory is a change you can read rather than a claim you accept. An old lockfile often has advisories that no safe bump clears; the run names those as needing a person instead of forcing a break, and several repositories can be swept at once up to the key's concurrent-run limit.

Frequently asked questions

Will it make a major version jump on an old package like Express?

Only when nothing smaller clears the advisory and the suite still passes. It tries the smallest bump first and avoids a major boundary it cannot justify; a major jump that breaks the mocha suite is backed out and the advisory is listed as needing a person, so an old Express or Mongo-driver pin is never forced across a break.

How does it fix a transitive dependency with no direct upgrade?

It adds an overrides entry to package.json scoped to the vulnerable transitive package rather than bumping an unrelated direct dependency, then reinstalls so the lockfile resolves to the fixed version, and the description records it as an override rather than a direct upgrade.

What if a peer range blocks an upgrade?

Old toolchains hit this often. Rather than guess, the agent records the peer-range conflict the install printed and lists that advisory as needing a person, so you decide whether to move the blocking package or accept the advisory for now.

Can it work on a private repository?

Yes. Install the Rush GitHub App on the repository and keep the resource as {"url": "https://github.com/your-org/your-app"}. The agent clones through that installation, reinstalls and runs the suite in its sandbox, and opens the pull request through the same App.