What the agent does
The agent checks out the pull request branch named in resources. On a NestJS API shaped like lujakob/nestjs-realworld-example-app it reads package.json before installing. The name is nestjs-realworld-example-app at version 2.0.0, the test script is jest --config=jest.json, and the runtime packages are @nestjs/core and @nestjs/common at ^7.0.5, @nestjs/typeorm at ^7.0.0, typeorm at ^0.2.24, typescript at ^3.8.3, jest at ^25.5.3 and ts-jest at ^25.4.0. There is no engines field and no .nvmrc. package-lock.json is lockfileVersion 1 and still says version 1.1.4, and a yarn.lock sits beside it, so npm install is what the request asks for and the review says both lockfiles are present.
It then reads the article module the diff sits in. src/article/article.controller.ts is the articles controller: GET /articles, GET /articles/feed, GET /articles/:slug, comments, POST create, PUT update, DELETE, and favorite. src/article/article.module.ts applies AuthMiddleware only to the feed, to POST /articles, and to the mutating :slug routes, so a public GET is outside that list. src/article/article.entity.ts maps the article table with a simple-array tagList, an eager OneToMany of comments, and a favoriteCount column defaulting to 0. src/article/article.service.ts is 204 lines. findAll starts from where 1 = 1, filters tag with LIKE, and for favorited loads a user then adds article.authorId IN the ids of that user's favorites. update assigns the body onto the row and does not rebuild the slug, which the controller marks with a Todo on the PUT handler. create saves the article, then pushes it onto author.articles.
npm test is the proof the review quotes, and the suite is thin. jest.json sets testRegex to /src/.*.(test|spec).(ts|tsx|js)$ and transforms TypeScript with node_modules/ts-jest/preprocessor.js. The only file that matches is src/tag/tag.controller.spec.ts. That spec builds a testing module with TypeOrmModule.forRoot() and no options, spies on TagService.findAll, and expects the controller to return the same array. ApplicationModule also calls TypeOrmModule.forRoot() with no arguments. The repository ships ormconfig.json.example, a MySQL config for localhost port 3306, database nestjsrealworld, entities src//.entity, and synchronize true. There is no ormconfig.json. The agent runs npm test in the sandbox and pastes the Jest output into the review, including a connection failure if the spec boots TypeORM against a missing config.
The review is one GitHub review on the pull request. Each finding names a file and a line, and the body splits blocking issues from suggestions. A change to the favorited andWhere, to slugify, or to a route the middleware does not cover is blocking when the diff touches it. A suggestion is a missing spec under src/article, or the package.json version drifting from the lockfile. The agent does not push commits. The transcript keeps the npm install and npm test tool calls with their output, so the review's test paragraph is the command that ran, not a summary written from the diff alone.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Review this pull request on the NestJS RealWorld API. Check it out, install dependencies with npm, and run npm test, which is jest --config=jest.json. Read the diff with the surrounding code in src/article/article.controller.ts, src/article/article.service.ts, src/article/article.module.ts and src/article/article.entity.ts. The only spec is src/tag/tag.controller.spec.ts, and the database sample is ormconfig.json.example. Post one GitHub review that cites file and line for every finding, separates blocking issues from suggestions, and includes the npm test result. Do not push commits.",
"resources": [
{
"url": "https://github.com/your-org/your-app/pull/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.
- 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
What comes back is a review on the open pull request, not a second branch. The session read names the repository and the pull request. The review body has the npm test result first, then blocking findings and suggestions. On a change to the article module the blocking notes point at the lines the diff edits in article.service.ts and article.controller.ts, and they say whether AuthMiddleware in article.module.ts covers the route. Suggestions name the missing article specs and the two lockfiles. Nothing in the pull request diff is from the agent, because the request says not to push.
A reviewer reads the cited lines against the test paragraph before accepting the review. If npm test failed because TypeOrmModule.forRoot() had no database, that failure is in the review and is not written up as a product bug unless the diff caused it. The transcript on GET /o/{org}/sessions/{id}/messages holds each tool_use and its tool_result, including the Jest output.
Run it on every pull request opened
Subscribe your server to the GitHub pull_request webhook. On pull_request.opened, and again on synchronize if you want the new commits reviewed, POST this body to https://api.prix.dev/o/{org}/sessions with the pull request URL in resources, which checks that branch out. Send an Idempotency-Key of the GitHub delivery id so a retried webhook returns the same session instead of starting a second review. The Rush GitHub App has to be installed on the repository or resources answers 422 RESOURCE_NOT_ACCESSIBLE.
Set a webhook URL on the API key. Rush POSTs run.completed, run.failed or run.cancelled when the turn finishes, and the payload's session_url is where you read the review text. A key allows at most max_concurrent runs at once, 4 by default, and the next start answers 429, so a burst of opened pull requests should wait for a free slot rather than fire in one batch.
The use case this job follows, with its automation and trigger: Review every pull request.
Why run it on Rush?
Reviewing this NestJS tree on a laptop means cloning, choosing npm over the stray yarn.lock, standing up MySQL because ormconfig.json.example expects it, and then running a Jest file that does not import the article module. The sandbox does that install and npm test away from your working copy, and the output stays on the session. A follow-up with POST /o/{org}/sessions/{id}/messages wakes the parked sandbox if you want a second look at one finding.
The review is tied to a command you can replay from the transcript. A diff-only comment cannot show that the single spec never loads ArticleService, or that TypeORM was asked to connect with no ormconfig.json. Each pull request is its own session and its own clone, so several NestJS reviews run at once without sharing a database or a node_modules, and a person still decides what to do with the review.
Frequently asked questions
Will the review push commits or rewrite the article module?
No. The request says not to push, and the agent posts a review on the branch that is already open. The pull request diff stays the author's. If a finding needs a fix, that is a follow-up you send, or a separate session whose request asks for a commit.
npm test does not cover articles. What does the review say?
It says that. jest.json only collects specs under src, and the repository has src/tag/tag.controller.spec.ts and no article spec. The review quotes the Jest summary and lists the article files it read by hand. It does not invent passing article tests to fill the gap.
The repo has both package-lock.json and yarn.lock. Which install does it run?
npm, because that is the request, and package.json has no packageManager field. The review notes yarn.lock and the lockfile version 1.1.4 against package.json 2.0.0 so a reviewer can see the drift. It does not delete either lockfile.
Does the sandbox need MySQL for this review?
The sample config is MySQL, and the tag spec calls TypeOrmModule.forRoot() with no arguments, which reads ormconfig if present. The agent runs npm test as the tree stands. When the connection fails, that output is the test result in the review. It does not start a database the repository does not declare in a committed config.
Can it review a pull request that only touches the user module?
Yes. resources is the pull request URL, so the checkout is that branch whatever files it changes. The request tells it to spend its time on the article module, which is the right scope for an article change.