What the agent does
The agent reads how the API is already wired before it writes a single spec. In a NestJS app like brocoders/nestjs-boilerplate it opens package.json and finds @nestjs/common at 11.1.18, Jest 30.3.0, TypeScript 5.9.3, and scripts test (jest), test:cov and test:e2e. The Jest block sets rootDir to src, testRegex to .*\.spec\.ts$, ts-jest as the transform, and testEnvironment to node. There is a package-lock.json, so installs use npm, not yarn or pnpm.
It then lists every *.service.ts under src/ and looks for a matching *.service.spec.ts. In this boilerplate the providers are all missing unit specs: src/auth/auth.service.ts (email login, bcrypt compare, session hash, JWT issue), src/users/users.service.ts (create with salted password, pagination), src/session/session.service.ts, src/mail/mail.service.ts, src/mailer/mailer.service.ts, src/home/home.service.ts (reads app.name from ConfigService), the file upload variants under src/files/infrastructure/uploader/, and the social auth services (auth-google, auth-apple, auth-facebook). End-to-end coverage already lives under test/ with Docker Compose files; the gap the agent fills is unit specs next to the providers.
For each chosen service it adds a *.spec.ts that builds the provider with Test.createTestingModule from @nestjs/testing (pinned with the Nest packages at 11.1.18). Collaborators such as UsersService, SessionService, MailService, JwtService and ConfigService are provided as real instances when their dependencies are light, or as typed stubs when they touch TypeORM or Mongoose repositories. Specs exercise behaviour: AuthService.validateLogin rejecting a missing user or wrong provider, HomeService.appInfo returning the configured name, UsersService.create hashing a password before persist. Seed services under src/database/seeds/ stay out of scope unless the prompt names them.
It runs npm test in the sandbox (and npm run test:cov when the prompt asks for coverage) until the new specs pass, then opens a pull request that lists each new file and which branches it covers. Production .service.ts files are not rewritten; only new *.spec.ts files land in the diff.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "claude",
"input": "Write Jest unit tests for the NestJS services in this API that have no spec file, building each with Test.createTestingModule and real collaborators where practical. Run npm test and open a pull request.",
"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
What comes back is a pull request on a new branch. In a repository shaped like brocoders/nestjs-boilerplate it adds *.service.spec.ts files beside providers such as auth.service.ts, users.service.ts and home.service.ts, each importing Test from @nestjs/testing and asserting on public methods. Existing e2e Docker flows under test/ and docker-compose.*.test.yaml are left alone.
The pull request description lists which services had no spec, which collaborators were real versus stubbed, and the npm test result from the sandbox. The session trajectory keeps the Jest output, so a reviewer can see failures the agent fixed before pushing.
Before merging, a reviewer checks that the specs do not reach a live database, that password and JWT paths use test doubles for secrets, and that the new files match the repo's testRegex. Once merged, npm test in CI picks them up with no workflow change.
Run it on every new NestJS service without a spec
Hook your generator or pull-request bot so that when a commit adds a *.service.ts under src/ with no matching *.spec.ts, your server sends this request with the repository in resources. Each gap gets its own sandbox run and a pull request that only adds the missing Jest file.
Point the API key's webhook at your server to receive run.completed or run.failed. Respect max_concurrent (4 by default); a Monday sweep across a large monorepo should queue starts rather than fire them all at once.
The use case this job follows, with its automation and trigger: Write the missing tests.
Why run it on Rush?
NestJS unit specs need a working Test.createTestingModule graph and honest stubs for TypeORM or Mongoose repositories. Doing that on a laptop means installing the boilerplate's lockfile, waiting on Jest, and holding half-written specs in your tree. On Rush the agent builds that graph in its own sandbox, runs npm test there, and only opens the pull request when the suite is green.
You get proof, not a claim: the trajectory shows every Jest run, the pull request names which services were bare, and production providers stay untouched. The same request can fill missing specs across several Nest APIs in parallel, each reviewed before merge.
Frequently asked questions
Will it mock every dependency?
No. The prompt asks for real collaborators where practical. Light services like HomeService keep a real ConfigService with a test config. Repository-backed services get typed stubs for the persistence port so the spec stays a unit test, not a hidden e2e run.
Does it replace my Docker e2e suite?
No. Files under test/ and scripts like test:e2e:relational:docker stay as they are. This job only adds *.spec.ts files under src/ for Jest's testRegex.
What about auth and password hashing?
Specs drive AuthService.validateLogin and UsersService.create with known plaintexts and assert on thrown UnprocessableEntityException codes and on bcrypt hashes differing from the input. They do not print secrets into the pull request or the trajectory fields meant for operators.
npm, yarn or pnpm?
Whatever the lockfile says. The Brocoders boilerplate ships package-lock.json, so the agent runs npm test. If your app has pnpm-lock.yaml or yarn.lock, it uses that package manager instead.