What the agent does
In fastify/demo the agent reads package.json and finds fastify ^5.10.0 with @fastify/autoload, @fastify/env, @fastify/session, @fastify/cookie, @fastify/swagger, @fastify/under-pressure and the rest of the official plugins, knex with mysql2, postgrator for the SQL migrations under migrations, typebox ^1.3.6 with the TypeBox type provider, and on the dev side typescript ~6.0.3, @types/node ^26.1.1, tsx, c8, glob and neostandard for eslint. There is no lockfile: .gitignore lists package-lock.json, pnpm-lock.yaml, yarn.lock and bun.lockb, and .npmrc sets ignore-scripts=true and min-release-age=7. That changes what an upgrade means here: every install already floats to the newest version inside each range, so the job is raising the ranges themselves, and npm will not take a version younger than seven days.
The checks are the ones ci.yml runs on Node 22 and 24 with a mysql:8.4 service: npm i --ignore-scripts, npm run build -- --noEmit, npm run lint, a generated COOKIE_SECRET, an empty .env for the scripts that pass --env-file=.env, then npm run db:migrate and npm run test with MYSQL_HOST, MYSQL_DATABASE test_db, MYSQL_USER test_user, CAN_SEED_DATABASE=1 and RATE_LIMIT_MAX=4 in the environment. The test script seeds the database and runs c8 over glob -c "tsx --test" "./test/**/*.ts", so the suite is node:test rather than a separate runner. test/helper.ts builds the app through fastify-plugin with skipOverride and adds login and injectWithLogin helpers that post to /api/auth/login and read the cookie named by this.config.COOKIE_NAME; the specs cover cors, env, the error and not-found handlers, rate limiting, the scrypt password plugin and the home, auth, users and tasks routes.
The agent starts MySQL 8.4 in the sandbox as docker-compose.yml describes, exports the same variables as CI, runs db:migrate and the full baseline, then runs npm outdated. For each package it raises the range with npm install
A bump that fails goes back to its previous range with the failing test name and error kept for the pull request. Majors in the @fastify family are applied only when the Fastify core version they require is already in place, and the typebox 1.x line is checked against the type provider it pairs with. Because there is no lockfile to commit, the pull request is a package.json diff, and its description states the exact versions the sandbox resolved so a reviewer knows what was tested.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Upgrade the npm dependencies to the latest compatible versions with npm. Read .npmrc and .gitignore first: there is no lockfile and min-release-age is set, so raise the ranges in package.json rather than expecting a lock diff. Start MySQL 8.4 in the sandbox as docker-compose.yml describes, export the same environment ci.yml uses including CAN_SEED_DATABASE=1 and a generated COOKIE_SECRET, create an empty .env, and run npm i --ignore-scripts, npm run build -- --noEmit, npm run lint, npm run db:migrate and npm run test for a baseline. Then run npm outdated and raise each outdated range with npm install <package>@latest, rerunning build, lint and test after each group. Leave out any bump that breaks them and say why with the error. Open a pull request with one line per bump and the resolved version of each package the sandbox tested.",
"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 changes package.json only, since the repository keeps no lockfile. The description has one line per package with the old range, the new range and the version npm resolved in the sandbox, then the bumps left out with the command and error that failed. A package held back by min-release-age is listed with the newer version it will reach once that version is old enough.
A reviewer checks that the CI matrix passes on both Node versions, reads the fastify and @fastify lines first because plugin majors tend to change option names, and checks the typebox line against the type provider. The session record holds the MySQL start, the baseline, every npm install and every test run, so an excluded package can be retried in a follow-up message to the same session.
Run it on every Monday morning
A scheduled workflow sends POST /o/{org}/sessions with this request and your repository in resources, with the org key as the bearer token and an Idempotency-Key built from the repository name and the week, so a re-run of the workflow returns the run already started.
Put a webhook URL on the key. When the turn finishes your endpoint receives run.completed with session_url, reads the pull request link from the session and posts it to the backend channel for the week's review.
The use case this job follows, with its automation and trigger: Upgrade dependencies weekly.
Why run it on Rush?
Testing a Fastify upgrade honestly means a MySQL instance, migrations, seeds and a full node:test pass for every group of bumps, which is slow on a laptop and leaves containers and environment variables behind. In a Rush sandbox the agent runs that loop on its own machine as many times as the upgrade needs, with each command's output kept.
A bot that opens one pull request per package leaves the team to find which of a dozen plugin bumps broke the session cookie test. The agent opens one pull request, already run against the suite, with the failing bumps taken out and named, and the same request can run against every Fastify service you maintain at once, up to the key's concurrency limit.
Frequently asked questions
Why is there no lockfile diff?
The repository ignores every lockfile, so each install resolves fresh within the ranges in package.json. The pull request therefore changes the ranges, and its description records the exact versions the sandbox resolved and tested so you know what passed.
Does it respect min-release-age?
Yes. npm reads the setting from .npmrc and will not resolve a version published less than seven days ago, so the agent cannot install one either. Such a package is listed in the pull request with the version it will reach later.
Does it need MySQL to run the tests?
Yes. The test script seeds the database before running the suite and the route tests log in through the real auth plugin, so the agent starts mysql:8.4 in the sandbox and runs db:migrate first, as ci.yml does with its service container.
Will it move Fastify or a plugin to a new major?
A plugin major is applied only when the Fastify version it requires is already installed and the suite passes; a Fastify core major is listed with its version but left for a planned upgrade, since the plugin set has to move together.