Hero Background

Next-Gen App & Browser Testing Cloud

Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Next-Gen App & Browser Testing Cloud
AIAutomationCoding

How to Test Code Written by Antigravity CLI (and Gemini CLI Before It)

Both run headless, both stream newline-delimited JSON, and neither one opens a browser. Here is the loop that closes that gap end to end.

Author

Bhawana

Author

Author

Shahzeb Hoda

Reviewer

Published on: August 27, 2026

A pipeline step runs Antigravity CLI with a prompt, it edits four files, and it exits 0. The next step deploys. Twenty minutes later somebody notices the pricing page renders an empty grid.

The exit code was honest. The CLI did what it was asked, and nothing in its contract ever claimed the page still worked.

Closing that gap is a matter of chaining one more command, and knowing which output to read from each link in the chain.

Where the Two CLIs Overlap

They share more than a vendor. Both run one-shot with a print flag, both emit newline-delimited JSON on request, and both keep their configuration under the same Gemini directory in your home folder.

That last detail is easy to miss and useful to know. Google documents Antigravity CLI's scoped permission rules as living in a settings.json under the Gemini configuration directory, so a machine already set up for Gemini CLI has most of the structure in place.

Where they differ is worth writing down before you script either one. Gemini CLI documents four exit codes rather than the usual two: 0 for success, 1 for a general error or API failure, 42 for an input error, and 53 when the turn limit is exceeded, per its headless mode documentation.

A shell script that treats every non-zero code as the same failure will report a malformed prompt as an API outage.

Running Antigravity CLI Headless

The interactive terminal interface is the default. To use it in a script, pass the prompt on the command line and pick an output format.

# one-shot run, human-readable output
agy -p "add a currency selector to the pricing table"

# one-shot run, a single JSON envelope when it finishes
agy -p "add a currency selector to the pricing table" --output-format json

# one-shot run, NDJSON events as the run progresses
agy -p "add a currency selector to the pricing table" \
    --output-format stream-json \
    --print-timeout 10m

Three flags carry most of the behaviour, and the defaults matter.

  • The print flag - -p, with --print and --prompt as documented aliases, runs once and exits rather than opening the interface.
  • The output format flag - text is the default, json returns one envelope on completion, and stream-json emits one JSON object per line as the run progresses.
  • The print timeout - it defaults to five minutes, which is shorter than many real tasks, so set it explicitly in CI.
  • Permissions - --dangerously-skip-permissions auto-approves every tool for a run, and scoped permissions.allow rules in the settings file are the safer route outside a sandbox.

The full flag list is in Google's Antigravity CLI headless mode documentation. Structured output schemas and multi-turn input over stdin are documented there too.

Note

Note: A CLI that exits 0 said it finished, not that it worked, and TestMu AI's Kane CLI answers the second question. Try TestMu AI free!

Running Gemini CLI Headless

Gemini CLI gets to the same place by a slightly different route. Its documentation states headless mode triggers either when you pass a query with the prompt flag or simply when the CLI runs in a non-TTY environment.

That second trigger is the one that surprises people. Piping into it from a CI job puts it in headless mode whether or not you passed the flag.

# explicit one-shot
gemini -p "refactor the checkout reducer and keep the public API stable"

# a single JSON object with the response and usage statistics
gemini -p "refactor the checkout reducer" --output-format json

# newline-delimited JSON events, one per line
gemini -p "refactor the checkout reducer" --output-format stream-json

# exit codes to branch on: 0 success, 1 error, 42 bad input, 53 turn limit

Handle 42 and 53 separately from 1 in any wrapper you write. A turn limit is a budget problem you can retry differently, and an input error is a bug in your own script.

Reading the Event Stream

Once more than one tool is in the chain, stop branching on exit status and start reading the structured output. Every CLI in the chain has its own exit-code vocabulary, and they do not agree.

A status field in the final JSON object means the same thing in every run. An integer does not.

# capture the stream, keep the last event, read one field
agy -p "$TASK" --output-format stream-json > build.ndjson
tail -1 build.ndjson | jq -r '.status // .type'

# keep the whole stream as a build artifact, not just the tail
# it is the only record of which files the agent touched and why

Keep the full NDJSON file. When a change turns out wrong three days later, the stream is what tells you whether the agent misread the task or did exactly what it was told.

Run tests up to 70% faster on the TestMu AI cloud grid

The Gap Neither CLI Closes

Neither one opens a browser. Both write files and run commands, so anything that only shows up when a page renders leaves no trace in any output either tool produces.

  • Rendering failures - a component that throws at mount looks identical to one that renders, from the file system's point of view.
  • Broken navigation - a route that now redirects to itself passes every type check on the way there.
  • Interaction regressions - an element covered by an overlay is still present in the DOM and still absent to a user.
  • Third-party breakage - a payment widget that fails to load is somebody else's script failing inside your page.

A unit test suite does not close this either, because it runs the same code the agent just wrote against assumptions the agent also just wrote.

Adding the Browser Step

The step you are missing has to be a plain command, because that is all either CLI can invoke. It also has to work without a test file, since the feature was written four minutes ago.

Kane CLI from TestMu AI answers both. The objective is written the way you would describe the check to a colleague, and a real Chrome browser carries it out.

#!/usr/bin/env bash
set -euo pipefail

agy -p "$TASK" --output-format stream-json --print-timeout 10m > build.ndjson

npm run build && npm run preview &
sleep 5

kane-cli run --agent --headless \
  "open the pricing page, switch the currency selector to EUR,
   assert every plan card shows a euro amount and none show NaN" \
  --url http://localhost:4173/

# exit 0 verified, 1 assertion failed, 2 environment error, 3 timed out

Two properties of that middle command matter more than the syntax.

  • The assertion is user-visible - it names what somebody would see, so it stays true through a refactor that renames every class in the file.
  • The failure states are distinct - a Chrome crash exits 2 and a real regression exits 1, so an infrastructure problem never gets filed as a product bug.
  • The evidence survives - per-step screenshots, a HAR network log, and console output are sealed into a pack under .testmuai/evidence in the repository.
  • Setup is one install - npm install -g @testmuai/kane-cli, with Node.js 18 or higher and Chrome on the PATH.

Here is a real run of that shape against the TestMu AI Selenium Playground, on Kane CLI 0.8.4, asserting on a value the page renders rather than on any element in the source.

$ kane-cli run --agent --headless \
    "open the Drag and Drop Sliders page, move the slider labelled
     'Default value 15' to 95, and assert the displayed value reads 95" \
    --url https://www.testmuai.com/selenium-playground/ | tail -1

{"type":"run_end","status":"passed",
 "summary":"Moved the slider labeled 'Default value 15' until its displayed value
            changed to 95. Finished with the slider showing 95, matching the
            requested value.",
 "final_state":{"displayed_value":"95"},
 "reason":"Objective completed","duration":31.2,"bifurcated":false,"total_runs":1}

$ echo $?
0

A drag is the kind of interaction that never appears in a diff. Whether the handle actually moved is only knowable by moving it.

Note

Note: TestMu AI's Kane CLI seals per-step screenshots, a HAR network log, and console output into one evidence pack per run. Read the Kane CLI documentation

Wiring It as a Skill

Scripting the chain works for CI. Inside an interactive session you want the agent to reach for the check itself, which is what a skill file does.

A skill is a markdown instruction file that teaches the agent when to invoke the verifier, how to build the command, and how to read the result back. Install it once and the behaviour is available in every session.

# global: available in every repository on this machine
mkdir -p ~/.gemini/skills/kane-cli
curl -o ~/.gemini/skills/kane-cli/SKILL.md \
  https://raw.githubusercontent.com/LambdaTest/kane-cli/main/skills/gemini/SKILL.md

# project-level: the skill travels with the code
mkdir -p .gemini/skills/kane-cli
curl -o .gemini/skills/kane-cli/SKILL.md \
  https://raw.githubusercontent.com/LambdaTest/kane-cli/main/skills/gemini/SKILL.md

With the skill loaded, the agent recognises a browser-shaped request, builds an agent-mode command itself, parses the NDJSON, and reports steps, duration, and assertion results instead of a sentence. The installation walkthrough is in verifying Gemini CLI output with Kane CLI.

Get Kane CLI certified for free with TestMu AI

Running the Whole Loop

Put together, the loop is four steps: the CLI writes, the build runs, the browser check decides, and the failure feeds back as structured output rather than a screenshot somebody pastes into a chat.

  • Run the CLI headless with stream-json output and keep the NDJSON file as a build artifact.
  • Build and serve the result locally, because verifying against a stale bundle proves nothing about the change.
  • Run the browser objective against the local URL and branch on its distinct exit codes rather than on truthiness.
  • On a failure, hand the agent the evidence pack and the failing objective, then let it try again with something to read.

Step two is the one teams skip and then spend an afternoon on. Verifying a stale build is how a fixed bug appears to persist.

For the same loop viewed from a different terminal agent, Claude Code vs Antigravity compares the two products directly. And for how this pattern extends from the local loop through to production, see continuous verification for AI-generated code.

Author

...

Bhawana

Blogs: 76

  • Twitter
  • Linkedin

Bhawana is a Community Evangelist at TestMu AI with over 3 years of experience creating technically accurate, strategy-driven content in software testing. She has authored 50+ blogs on test automation, cross-browser testing, mobile testing, and real device testing. She also serves as Product Marketing Manager for Kane CLI, the command-line tool that runs browser automation from the terminal using natural-language flows in a real Chrome browser. Bhawana is certified in KaneAI, Selenium, Appium, Playwright, and Cypress, reflecting her hands-on knowledge of modern automation practices. On LinkedIn, she is followed by 6000+ QA engineers, testers, AI automation testers, and tech leaders.

Reviewer

...

Shahzeb Hoda

Reviewer

  • Linkedin

Shahzeb Hoda is the Associate Director of Marketing and a Community Contributor at TestMu AI, leading strategic initiatives in developer marketing, content, and community growth. With 10+ years of experience in quality engineering, software testing, automation testing, and e-learning, he has authored and reviewed 70+ technical articles on software testing and automation. Shahzeb holds an M.Tech in Computer Science from BIT, Mesra, and is certified in Selenium, Cypress, Playwright, Appium, and KaneAI. He brings deep expertise in CI/CD pipeline automation, cross-browser testing, AI-driven testing practices, and framework documentation. On LinkedIn, he is followed by 3,700+ engineers, developers, DevOps professionals, tech leaders, and enthusiasts.

Add to Google preferred sources

Summarise with AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Antigravity and Gemini CLI Testing FAQs

Did you find this page helpful?

More Related Blogs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests