From Gemini CLI to Antigravity CLI: A Working Record of the June 18 Migration
On June 18, Gemini CLI and the Code Assist extension stop serving individual users. Here is my actual record of moving to the Go-based Antigravity CLI: what broke, the command mapping, and the auth and quota traps I hit.
Scrolling back through my shell history, I found that the gemini command had sunk deeper roots into my scripts than I expected. Tidying article drafts, drafting commit messages, generating release-note skeletons for several apps. Each is a tiny automation, but if they stop, the day's operations quietly stall.
That gemini stops working for individual users on June 18. Gemini CLI and the Gemini Code Assist IDE extension end request processing on the free tier, AI Pro, and Ultra alike, redirecting to a Go-rewritten Antigravity CLI. When I read the notice, the first thing I did was measure the blast radius by hand. This is the record of that migration.
Inventory what actually breaks first
The first step in any migration is not learning the new tool, but knowing precisely what currently depends on gemini. As an indie developer running apps and four blogs in parallel, my call sites are scattered.
The inventory is a single grep.
# Sweep repos and home dotfiles for gemini dependenciesrg -n --hidden -g '!.git' \ -e '\bgemini\b' \ -e 'code-assist' \ -e 'GEMINI_API' \ ~/repos ~/.zshrc ~/.config 2>/dev/null \ | grep -vE '@google/generative-ai|gemini-1\.5|gemini-2' \ | tee ~/gemini_cli_usage.txtwc -l ~/gemini_cli_usage.txt
Excluding @google/generative-ai (SDK-based API calls) is the key. What is ending is the CLI and the IDE extension, not the Gemini API itself. Code that hits models through the SDK is out of scope. Draw that line first, or the migration scope balloons needlessly.
In my case, the real dependencies came to eleven sites: six shell functions, three CI steps, two editor task definitions. Fewer than I feared, and I relaxed a little right there.
Install and confirm a first round trip
The Antigravity CLI ships as a binary called agy. Being a single Go binary, it almost never trips on dependency resolution the way the old Node global package did.
# Install (official installer)curl -fsSL https://antigravity.google/install.sh | sh# Put it on PATH and confirm connectivityexport PATH="$HOME/.antigravity/bin:$PATH"agy --versionagy auth login # opens a browser, authorize with your Google accountagy "compute 1 + 1 and return only the result"
If that last line answers back, you have connectivity. agy auth login opens a browser and stores a token under ~/.antigravity/. If you used to keep GEMINI_API_KEY in an environment variable, note that the mechanism changes here. More on that below.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦Concrete steps to rewrite Gemini CLI dependent scripts and CI calls for the Antigravity CLI
✦A mapping from old commands to agy subcommands, plus the auth and quota pitfalls I actually hit
✦Startup-time numbers I measured on my own machine, and how to decide whether to migrate now or wait
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
The most time-consuming part of the migration was rephrasing commands. Some map one-to-one; others change in approach. Here is the table I built at my desk.
One-off prompt: gemini -p "..." becomes agy "..." (no -p; the argument is the prompt)
Non-interactive / CI: the equivalent of gemini --yolo is agy --headless --approve all (auto-approval is now explicit)
Plain text output: gemini --format text becomes agy --quiet (drops decoration, stdout only)
Model selection: gemini -m gemini-2.5-flash becomes agy --model flash (alias by default, full names allowed)
It looks one-to-one, but the --headless plus --approve pairing carries a design shift. Where the old --yolo was a blunt "allow everything" switch, agy makes you express approval granularity through arguments. If you use it in CI, running it with that left vague is the unsafe path.
Rewrite scripts and CI
Walk the eleven sites through the table above mechanically. A shell function looks like this.
# Before (Gemini CLI dependency)draft_commit() { git diff --staged | gemini -p "one-line commit message in English" --format text}# After (Antigravity CLI)draft_commit() { git diff --staged | agy --quiet "one-line commit message in English"}
One CI step caught me. In a non-TTY environment like GitHub Actions, calling agy plainly hangs silently waiting for approval. Because the old CLI sailed through on --yolo alone, this is an easy trap to step on in production.
# the relevant step in .github/workflows/draft.yml- name: Generate release note draft env: ANTIGRAVITY_TOKEN: ${{ secrets.ANTIGRAVITY_TOKEN }} run: | # Without making non-interactive explicit, it hangs on approval cat CHANGELOG_RAW.md | agy --headless --approve all --quiet \ "polish this release-note draft into clear, friendly prose" > release_note.md
In CI you pass the token through an environment variable (ANTIGRAVITY_TOKEN); the browser authorization of agy auth login is unavailable. Separating these two paths up front (browser auth locally, env-var token in CI) saves you a lot of later confusion.
The auth and quota traps
This is where migrations fail most quietly. Three things, known in advance, keep you safe.
The old GEMINI_API_KEY is not used for agy's local authorization. Locally it is the agy auth login token; in CI it is ANTIGRAVITY_TOKEN. The auth paths diverge. Leave the old variable lying around and you will puzzle over "I set it, but it has no effect."
Quota counting is shared. Because agy's desktop app, CLI, and SDK share the same agent harness, running several agents in parallel reaches the ceiling faster. On a day I ran background agents concurrently across my four sites, I hit the rate limit before noon. Not being greedy with parallelism actually increases total throughput across the day.
--approve all is convenient, but it auto-approves file writes and command execution too. Confirm it stays inside a CI sandbox. Add it casually in a local working directory and it will push through unintended changes without a word.
Measuring the real speed
"Fast because it is Go" is not a decision input until you confirm it with numbers. On my machine (M2, wired connection), I measured from launch to the start of a prompt response with hyperfine.
# Compare startup overhead only (a light prompt, not model latency)hyperfine --warmup 3 \ 'echo "reply with just ok" | agy --quiet' \ 'echo "reply with just ok" | gemini -p "" --format text'
On my end, agy's startup overhead was about 40% of the old CLI. In seconds that is just under a one-second saving, which feels small for a single call. But across script suites I invoke dozens of times a day, the difference accumulates. My read is that removing the Node runtime startup is what pays off.
What mattered more than the number was dependency stability. The old CLI occasionally spat warnings on Node version drift; the single-binary agy does not care about the environment. Reclaiming the time I used to spend suspecting npm was, for me, the bigger improvement.
My migration call
In the end, I finished migrating without waiting for the deadline, for three reasons.
First, the blast radius was small enough to pin down with grep, and the rewrites were mechanical. Second, scrambling after June 18 risks stalling daily machinery like an automated publishing pipeline. Third, the single-binary form removes a notch of operational uncertainty.
Conversely, some people need not rush. If you only use gemini interactively and have not embedded it in CI or scripts, there is no fire. Even then, installing agy and confirming a round trip means your hands will not freeze on deadline day.
Migration is not flashy work, but for machinery that runs every day, "not stopping" is the value itself. Start by making your own dependencies visible once with rg. From there, it wraps up more quietly than you expect.
Share
Thank You for Reading
Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.