The noqa CLI: Let Your AI Agent Test Your App on a Real Device

Your coding agent can write a whole screen for your app, wire up the navigation, handle the edge cases and explain the change back to you when it is done. Then it stops, and you are the one who opens the app to find out whether any of it works.
That is odd, because in other places the agent stays with the work until it is finished. On a backend it writes an endpoint, calls it, reads the error it gets back and fixes the code. On the web it opens a browser and clicks through the page it just changed. On mobile it has nowhere to go, since the app only exists behind a screen you touch, and the agent works in text.
The noqa CLI is how we close that gap.
A CLI your coding agent can drive
The CLI ships with the macOS app and puts the whole platform behind a single command, from listing devices and reading the screen to taps and swipes, test cases, runs and results. Everything goes in as a command and comes back as JSON, which is the form Claude Code, Cursor and Codex can actually work with.
You can run it by hand, and sometimes you will, but we built it with the agent in mind: you change some code, the agent takes the app through the flow on a real device, and you read the result without opening the simulator yourself.
What it does there is the same loop a person follows when checking something manually. It looks at the screen, does one thing, then looks again to see what changed.
noqa devices connect <device-id>
noqa screen # what is on screen right now
noqa action tap -d "Login button" # one action
noqa screen # did it work
Targets are descriptions, not selectors
Look at the snippet again and you will not find a selector anywhere in it. The agent never needed one, because -d "Login button" is only a description of the thing it wants to press, and noqa is the part that turns that description into a position on the screen.
A selector is extra work for a person too, but the agent has to do that work again at every step. To write one it first loads the element tree and reads through it to find the right id, and that tree takes up much of the context it has left for the task itself. On a custom control it often picks the wrong node. Even when it picks the right one, the step stops working as soon as someone moves that element in the next redesign.
A description avoids all three problems. The agent writes the same words you would use to point at the button, and we find that button on the screen.
What the agent writes down stays readable as a result. When it saves the flow as a test case, you get a sentence about your product instead of a list of XPaths, so anyone on the team can read the case and tell whether it is checking the right thing.
Reading the screen costs context
Since the agent looks at the screen before and after every action, the way it reads accounts for most of what a session costs. To see how much that varies, we measured the same screen three ways:
| Approach | Tokens |
|---|---|
noqa screen — cleaned element tree |
~800 |
| Screenshot (vision) | ~1,500 |
noqa screen --full — raw Appium tree |
~5,600 |
The raw accessibility tree holds every wrapper and every duplicated label, and it grows with the complexity of the screen. A screenshot is lighter, but it is only pixels: the model has to work out positions itself and read small text visually. noqa screen is the same tree with the noise removed, so the agent gets exact positions for about seven times less than the raw version.
In practice that decides how many steps a session can run before the context fills up.
How the two agents split the work
Your coding agent is the one that knows your code, so it starts by opening the app on a device and walking through the flow to see how it really behaves, and it writes the test case only once it has watched that flow pass. Along the way it picks up things nobody wrote down, like the test credentials, what a screen is called, or a rule the app always follows, and it saves them into the app context so that later runs begin with that knowledge instead of rediscovering it.
Our agent takes over from there. You hand it the saved cases and a build, and it works through them on the device on its own, then returns per-step pass and fail with screenshots, whether you ran it locally or from CI.
Between the two, test coverage stops being a separate project you have to schedule. The agent that built the feature writes the case, and the agent that tests it keeps that case running on every build after.
Get it
The CLI is in the macOS app under Settings → Tools. Click Install CLI, then Install skill to teach your coding agent the commands. Device commands and test management are free with an account, and agent runs need a paid plan.
Every command is in the CLI docs, and the agent workflow is in CLI for agents. Download noqa and connect a device.