What the agent does
In a NestJS app like lujakob/nestjs-realworld-example-app, the agent starts by listing every place a Node version could be pinned, and in this repository most of them are missing. There is no .nvmrc, no engines field in package.json, no Dockerfile and no workflow under .github. The README still carries a Travis badge that points at a different repository. So the pull request adds pins rather than edits them, and says so: .nvmrc with 24, an engines entry, and a CI workflow that runs on Node 24, each listed as a new file.
Next it reads what will break on a new runtime. package.json pins NestJS ^7.0.5, TypeORM ^0.2.24, TypeScript ^3.8.3, Jest ^25.5.3, ts-jest ^25.4.0 and @types/node ^13.13.4. argon2 ^0.26.2 is a native addon compiled at install time, so it is the first thing likely to fail under Node 24, and the agent reads the install log to see whether a newer argon2 release ships a prebuilt binary for it. The repository also commits both package-lock.json (lockfileVersion 1) and yarn.lock; the agent picks one, regenerates it under Node 24 and states which one it deleted and why.
Then it makes the project run at all before judging the upgrade. src/config.ts is not committed, only src/config.ts.example with a SECRET export, so tsc stops until that file exists; the agent copies it in the sandbox and leaves it out of the commit. npm start runs index.js, which loads ts-node/register, while start:prod compiles with tsc into dist/ and runs node dist/main.js. dist/ is checked in, so the agent rebuilds it or removes it from the repository and explains the choice instead of shipping stale compiled output.
Last come the tests. jest.json transforms TypeScript through node_modules/ts-jest/preprocessor.js, and the only spec, src/tag/tag.controller.spec.ts, calls TypeOrmModule.forRoot(), which reads an ormconfig.json the repository only ships as ormconfig.json.example pointing at MySQL on localhost:3306. The agent starts a MySQL server in the sandbox for that spec, records the result on the old Node version first, then on Node 24, so a failure that existed before the upgrade is reported as a baseline problem and not blamed on the runtime.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Upgrade this NestJS project to Node 24. List every place a Node version is or should be pinned (.nvmrc, package.json engines, CI workflows, Dockerfile) and say which ones you are adding. Keep one lockfile and regenerate it under Node 24. Copy src/config.ts.example to src/config.ts in the sandbox only. Start MySQL from ormconfig.json.example, run npm test on the current Node first and then on Node 24, and also run tsc and node dist/main.js. Fix each break the new runtime causes, such as native modules like argon2 that fail to build, with the smallest version bump that works. Open a pull request that lists each fix with the command output that showed it.",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- 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.
- 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.
- 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
The pull request has a short list of files: .nvmrc, package.json with an engines field and any dependency bumps the install forced, one regenerated lockfile with the other removed, and a new workflow under .github/workflows that installs on Node 24, runs tsc and runs the Jest suite against a MySQL service. If the agent added a Dockerfile, the description says it is new and why; it does not invent one when the app never had a container.
The description pairs each change with the failure that caused it: the argon2 build error and the version that fixed it, the TypeScript or ts-jest bump the compiler or test runner needed, and any spec that already failed before the upgrade. A reviewer checks that the lockfile choice matches how the team installs, that the NestJS major stayed on 7 unless the description explains a forced move, and that the new CI job runs the same commands the agent ran. Each command and its output are in the session transcript, read with GET /o/{org}/sessions/{id}/messages.
Run it on every service still on an old Node
Keep a list of services and the Node version each one runs. When a service falls behind the version you target, your scheduler sends one POST /o/{org}/sessions request with that repository in resources and the prompt above. Store the execution_id beside the service name so the next weekly pass skips repositories that already have an open upgrade.
Set a webhook on the key and your endpoint receives run.completed or run.failed when the turn ends. Read the session for the pull request link, and send a follow-up with POST /o/{org}/sessions/{id}/messages when a reviewer asks for a change, such as keeping yarn.lock instead of package-lock.json.
The use case this job follows, with its automation and trigger: Upgrade dependencies weekly.
Why run it on Rush?
Moving a NestJS 7 app to Node 24 means compiling native addons, installing two-year-old packages and starting a MySQL server, none of which you want on the laptop you use for other projects. In a Rush sandbox the agent can install Node 22 and Node 24 side by side, run the suite on both, and break things freely. Every npm install, tsc and jest command is kept with its output in the run's record, so the pull request is backed by what actually ran.
When you have ten services on old Node versions, each one gets its own sandbox and its own pull request, started in parallel up to the key's concurrency limit. The agent works through argon2 in one repository and a TypeORM driver in another without either run seeing the other's state, and you review the results one by one.
Frequently asked questions
My project has no .nvmrc or Dockerfile. What does the agent change?
It adds the pins that are missing and says in the pull request which files are new. For a repository like this one that means .nvmrc, an engines field and a CI workflow. It does not add a Dockerfile unless you ask, since a container is a deployment decision.
Will it upgrade NestJS 7 to the latest major at the same time?
Not unless Node 24 forces it. The prompt asks for the smallest version bump that fixes each break, so a NestJS major upgrade only happens if the old version cannot install or run, and the description shows the error that required it. A full framework upgrade is better as its own pull request.
What happens with native modules like argon2?
The agent reads the install log under Node 24. If the pinned argon2 has no binary for the new runtime and fails to compile, it moves to the nearest release that builds and runs the tests that hash and verify passwords. The version change and the failing log line go in the description.
My tests need a database. Can they run?
Yes. The sandbox is a full machine, so the agent starts MySQL from the settings in ormconfig.json.example and runs the spec against it. If a spec cannot run for a reason unrelated to Node, the pull request marks it as not verified.