Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

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.

Bhawana
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.
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.
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 10mThree flags carry most of the behaviour, and the defaults matter.
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: 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!
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 limitHandle 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.
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 whyKeep 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.
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.
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.
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 outTwo properties of that middle command matter more than the syntax.
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 $?
0A drag is the kind of interaction that never appears in a diff. Whether the handle actually moved is only knowable by moving it.
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
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.mdWith 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.
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.
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 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 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.
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance