Skip to content
Smart subagent on top of Playwright CLI

Prima CLI

Each Playwright needs their Prima

Your agent describes the check. A cheaper model drives playwright-cli and sends back the verdict.

$ npx prima-cli

Works with Playwright CLI

Works with your favorite agent

Claude Code Codex Cursor OpenCode Claude Code Codex Cursor OpenCode
Why Prima

Stop spending Opus on clicks

If your agent checks its work in a real browser, most of its tokens go to reading pages. Prima moves that work to a smaller model and hands back the result.

For agents that verify their work with playwright-cli

01 · The problem

Your agent reads the whole page to press one button.

When Claude Code or Codex checks a change with playwright-cli, it takes a snapshot, reads the ARIA tree, clicks by ref, and snapshots again because the page re-rendered. Each round is a turn on your most expensive model, and every tree stays in context next to your code.

agent session · checking the settings form turn 9 and counting

$ npx playwright-cli snapshot

- navigation [ref=e14] … the whole page tree

$ npx playwright-cli click e87

# page re-rendered, e87 is gone

$ npx playwright-cli snapshot

- navigation [ref=e14] … the whole tree, again

$ npx playwright-cli click e91

…

Every line above goes through your main model and stays in its context for the rest of the session.

02 · The handoff

Say what should happen. Prima does the clicking.

Prima attaches to the browser your agent opened with playwright-cli. Your agent passes one sentence. A small, fast model drives the page, and your agent gets back a short report instead of a browser transcript.

Your agent sends

$ npx prima-cli check "dark theme survives a reload"

Your agent gets back

PASSED · exit 0

used: I.click('Theme'); I.click('Dark'); I.refreshPage()

artifacts: saved to disk

The snapshots, retries and re-renders happened. Your agent just did not have to read them.

03 · Context

Page dumps go to disk. Your agent keeps its context for code.

ARIA trees, HTML, screenshots and network logs are written to files. Your agent opens them only when a check fails and it needs a closer look. The rest of the time it stays focused on the code it is changing, and the session runs longer before it has to compact.

In your agent's context

PASSED · checkout succeeds
used: I.click('Place order')
artifacts: output/prima/

A few lines, then back to the code.

On disk, read only if needed

  • aria-snapshot.txt
  • page.html
  • step-03.png
  • network.har

04 · Cost

Browser work runs at small-model prices.

Finding a button in a page tree does not need Opus. Prima runs that loop on a cheap, fast model such as gpt-oss-120b on Groq or OpenRouter. Your frontier model is billed for deciding what to check and for fixing what broke.

Your agent · frontier model

  • Decides what needs checking
  • Reads the verdict
  • Fixes the code when a check fails

Prima · small model

  • Reads snapshots and picks elements
  • Retries when the page re-renders
  • Confirms the outcome on the page

Fewer turns on the expensive model, and each turn it does take is about your code.

05 · Evidence

A verdict you can check, not a thumbs up.

Each step comes back with the code Prima ran. A step it could not complete is marked FAIL with the reason. If an outcome was never checked, Prima says so instead of guessing. At the end, one command turns the session into an HTML or Markdown report you can attach to a pull request.

$ npx prima-cli do "open the account menu" "choose Settings" "switch theme to Dark"

okopen the account menu · I.click('Account') okchoose Settings · I.click('Settings') FAILswitch theme to Dark · the Theme select has no "Dark" option

Your agent knows which step broke and what the page showed, without opening a single snapshot.

06 · Setup

Your agent already runs playwright-cli. Tell it about Prima.

Nothing changes in how your agent works. It still opens the browser with playwright-cli. You add one line to your agent instructions, or install the prima skill, and it runs npx prima-cli for checks. It learns every command from npx prima-cli --help.

Your agent runs

$ npx playwright-cli open http://localhost:3000

$ npx prima-cli --help

$ npx prima-cli check "a new user can sign up and sees the dashboard"

PASSED · exit 0

You add to AGENTS.md or CLAUDE.md

- Use npx prima-cli for browser checks

Works with Claude Code, Codex, Cursor, OpenCode and any agent that runs shell commands.

1 / 6
Sound familiar?

Five minutes to build.
Ten to check.

Your agent writes the feature in one pass, then spends twice as long clicking through it with playwright-cli. Here is that session to scale.

One feature, start to finish

15 min

Writes the feature

one continuous pass

5 min
then

Checks it with playwright-cli

snapshot, read, click, ×20

10 min

Two thirds of the session is your most expensive model reading page trees and clicking refs. Every one of those tokens stays in its context and is billed at its rate.

The new loop

Your agent asks.
Prima sends back proof

Your agent still runs playwright-cli. Prima sits on top of it as a fast subagent, so the expensive model stops clicking and each model does the work it is priced for.

A cartoon robot builder holding a wrench, leaning on a screen with a light and dark theme toggle, asking: Does our theme setting survive reload?
claude-code · delegating
$ npx prima-cli check "the theme setting survives a reload"

### Result
ok: true                    expectations: PASSED
used: I.click('Theme'); I.selectOption('Dark'); I.reload(); ...

### Steps
1. ok  switch the theme to dark     I.selectOption('Theme', 'Dark')
2. ok  confirm it took effect       I.seeInField('#theme', 'dark')

agent: verdict received in one call. moving on.

Your agent decides what

Claude Code, Codex or Cursor writes the outcome it expects in one sentence. No page trees, no locators, no screenshots.

A small model works out how

Prima runs the look-and-click loop on playwright-cli with a cheap, fast model. It finds elements and retries after re-renders. None of that reaches your agent.

A verdict comes back

PASSED or FAILED, the steps taken and the code that worked. Snapshots and screenshots are saved to disk, not sent to your agent.

The execution model runs on any provider

OpenAI Anthropic Google Groq Mistral OpenRouter SambaNova
Inside Prima

Even faster with Jev

Many browser steps are a multiple-choice question: which link, did it work. Jev answers those in a fraction of a second, for less than the model that drives the browser.

Decisions by Jev

Specialized model by TypeSafe AI

Most models write an answer. Jev makes a decision.

  • Cheaper and faster. A small model that picks an answer instead of writing one. Clicks and checks it settles skip a call to the model that drives the browser.

  • Picks, never makes up. Which button to click, whether the check passed: Jev chooses from the options Prima lists. It cannot invent an answer that is not there.

  • Says when it is unsure. If Jev is not confident about a choice, Prima hands that step to the regular model instead of guessing.

One check inside a Prima run

“Is the billing form filled with all values?”

Card holder

Jane Doe

Card number

4242 4242 4242 4242

Expiry

12 / 28

ZIP code

empty

Regular model

“Looking at the form, the card holder, number and expiry are filled in. The ZIP code field appears to be empty, so the form may not be fully…”

A paragraph Prima has to read and interpret. Slower, and every word is billed.

Jev

choice: no

probabilities: yes 0.06 · no 0.94

confidence: 0.94

A typed answer in a fraction of a second. Nothing to parse.

Confidence decides who answers. 0.94 is above Prima's 0.70 bar, so Prima marks the check failed without calling the regular model. Had Jev been unsure, the same question would go to the regular model.

Get started

Try it now!

Your agent does the browser work. You only tell it that Prima is there.

Run with npx

Nothing to install: your agent runs it with npx. Connect an AI provider, then tell your agent about it in CLAUDE.md or AGENTS.md.

$ npx prima-cli
Check which models it picked up:
$ npx prima-cli config
Read the prima-cli readme

Install with a skill

Add the skills to your agent. The prima skill teaches it every Prima command, so a short request is enough.

$ npx skills add testomatio/skills
Then ask your agent:
$ claude "check edit works via prima"
Read the prima skill

Setup: Connect to AI Provider

Prima runs its own models. It cannot use your Claude or Codex subscription, so it needs a separate AI provider and API key.

We recommend OpenRouter. One key gets you openai/gpt-oss-120b on the fastest hosts, like Groq, Cerebras and SambaNova, at 500+ tokens per second, and typesafe/jev for decisions. It is billed separately, but the bill for browser checks stays very low.

Put the key in your agent's config, since the agent is what runs Prima.

~/.claude/settings.json

{
  "env": {
    "PRIMA_CLI_AI_MODEL": "openrouter/openai/gpt-oss-120b:nitro",
    "PRIMA_CLI_DECISION_MODEL": "openrouter/typesafe/jev-1.13",
    "OPENROUTER_API_KEY": "your-key"
  }
}

:nitro asks OpenRouter for its fastest host, which is Groq for this model.

Setup: Update instructions

Put it in the CLAUDE.md or AGENTS.md your agent already reads. That is the whole setup. Your agent reads the rest from --help.

CLAUDE.md
# Acme Dashboard
 
Next.js app with a Postgres backend. Unit tests run in Vitest.
 
## Commands
- npm run dev starts the app on http://localhost:3000
- npm test runs unit tests
- npm run lint must pass before a commit
Add this
- Use npx prima-cli for browser checks
 
## Code style
- TypeScript strict mode, no any
- Server actions live in app/actions/
- Keep components small, split at ~200 lines
 
## Git
- Branch from main, one feature per branch
- Never commit .env files
Open source · Elastic License 2.0

Give your coding agent its Prima

Delegate browser checks to a low-cost model. Same browser, same session, one call instead of twenty round-trips.

Questions & answers

FAQ

Why is this cheaper than driving playwright-cli from my agent?

The frontier model stops parsing pages. Snapshots and retries stay inside Prima on a low-cost model; the main agent receives only the verdict and the working code.

Which agents can use it?

Any agent that can run a shell command. npx prima-cli --help is the contract: one call per job, plain-text report, exit code 0 or 1.

Which model drives the browser?

The model in PRIMA_CLI_AI_MODEL. The tested default is gpt-oss-120b via OpenRouter or Groq. Screenshot judgement uses a separate vision model.

Does it replace Playwright CLI?

No. Your agent keeps opening the browser with playwright-cli, and Prima attaches to that same browser and session. When the agent already has a verified locator, it can call playwright-cli or npx prima-cli pw directly.