ANTIGRAVITY LABJP
Articles/Antigravity Basics
Antigravity Basics/2026-06-14Intermediate

A Compatibility Shim That Bridges Old Scripts to agy Before Gemini CLI Shuts Down

Ahead of the June 18 Gemini CLI shutdown, instead of rewriting every gemini call scattered across cron and CI at once, a thin compatibility shim can bridge them to the Antigravity CLI (agy). Here is the approach with working shell scripts.

Antigravity CLI18Gemini CLI12Migration5Shell ScriptCI6

The real headache was that the command name gemini is scattered across cron, CI, Makefiles, and old notes—and I could not honestly account for every place it gets called from. Trying to replace them all on shutdown day, a few always slip through and fail quietly at 3 a.m. As an indie developer running an automated publishing pipeline, that "one that slipped through" goes unnoticed until the next morning.

So before rewriting every call site directly, I slipped in a thin compatibility shim that keeps the name gemini but routes the body to agy (the Antigravity CLI). That decoupled me from the deadline and let me move call sites over one at a time, calmly.

Why a shim instead of a one-shot replace

What is genuinely scary about migrating from gemini to agy is not the command disappearing—it is not holding a correct, complete list of every caller. grep only finds what is inside the repo; crontab, systemd timers, and scripts on another machine all escape it.

A shim absorbs that uncertainty over time. It keeps the old name while delegating to the new implementation, separating the migration deadline (June 18) from your own deadline to fix every caller. As long as you secure name compatibility before the command goes away, you can move the internals at your own pace.

Build the flag mapping table first

Before writing the shim, map only the flags you actually use. There is no need to cover every flag—porting ones you never call buys nothing. My pipeline used just these four.

  • -p / --prompt (prompt string) → agy run -p
  • -m / --model (model selection) → agy run -m
  • --json (machine-readable output) → agy run --format json
  • -f / --file (input file) → agy run --input

What matters here is the output-format difference. The old CLI's --json and the new CLI's --format json can differ in key names and nesting. If anything downstream parses it, look at the real output once right after routing through the shim and confirm your jq paths still work. Skip this and you get the worst failure: the command succeeds while the downstream silently grabs nothing.

The compatibility shim itself (drop-in replacement)

Prepare an executable named gemini placed at the front of PATH. It is a thin layer that parses the arguments and re-passes them to agy.

#!/usr/bin/env bash
# /usr/local/bin/gemini  ← place under the old command name, first on PATH
# Role: a compatibility shim that bridges old gemini calls to agy run
set -euo pipefail
 
# Resolve the real agy (fail loudly if missing)
AGY="$(command -v agy || true)"
if [ -z "$AGY" ]; then
  echo "gemini-shim: agy not found. Please install the Antigravity CLI." >&2
  exit 127
fi
 
args=()
while [ $# -gt 0 ]; do
  case "$1" in
    -p|--prompt) args+=( -p "$2" ); shift 2 ;;
    -m|--model)  args+=( -m "$2" ); shift 2 ;;
    -f|--file)   args+=( --input "$2" ); shift 2 ;;
    --json)      args+=( --format json ); shift ;;
    -h|--help)
      echo "gemini-shim → agy run compatibility layer. Unknown flags pass through." >&2
      shift ;;
    *)           args+=( "$1" ); shift ;;   # pass unknown args through as-is
  esac
done
 
# Make migration visible: log shim-routed calls to surface remaining callers
echo "$(date -Iseconds) shim-call: $*" >> "${HOME}/.gemini-shim.log"
 
exec "$AGY" run "${args[@]}"

The exec replacement passes the exit code and signals straight through to agy. Inserting another process in between can make CI misjudge the exit code or fail to deliver the timeout signal.

Use the log as a map of "remaining callers"

The hidden star of this shim is the last log line. By recording shim-routed calls, just a few days of operation naturally collects "where gemini actually gets called from." Even a crontab or another script grep never found will leave a footprint in the log the moment it runs.

# Tally the actual callers of gemini over the past week into a to-migrate list
sort "${HOME}/.gemini-shim.log" | awk '{$1=""; print}' | sort | uniq -c | sort -rn

Looking at this tally, I noticed an old backup cron that did not exist anywhere in the repo. It was a caller static grep would never have found. Once you can measure migration progress by "how many callers remain," the pre-deadline anxiety drops a lot.

Judging when to remove the shim

The shim is a bridge, not a destination. Once the tally hits zero for several days straight, you can conclude every caller has moved to calling agy directly.

# If there have been zero shim-routed calls in the past 3 days, it is a removal candidate
RECENT=$(awk -v cut="$(date -d '3 days ago' -Iseconds)" '$1 > cut' "${HOME}/.gemini-shim.log" | wc -l)
[ "$RECENT" -eq 0 ] && echo "No shim-routed calls → you can remove /usr/local/bin/gemini"

Migration is only complete when removal is included. Leave the shim in place and the call sites you should have fixed get preserved "because they still work," leaving you with permanent double maintenance. I deliberately set a deadline and pulled it out.

The first thing to do is write down just four or five flags you actually use and run the shim above within that scope. You do not need perfect compatibility. If you reach a state where "as long as the name lives, the body can move later" before the June 18 shutdown, you are freed from a deadline-driven migration. I hope this helps anyone with an automation-script migration coming up.

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.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Antigravity2026-06-16
Does the New CLI Do the Same Job? An Output-Parity Gate Before Switching to Antigravity CLI
With Gemini CLI shutting down on June 18, here is how I froze the old CLI's artifacts as a golden baseline and built a parity harness to catch regressions before cutting over to Antigravity CLI — with normalization and a go/no-go gate, in code.
Antigravity2026-06-12
Six Days Until Gemini CLI Shuts Down — Auditing Automation Dependencies and Migrating to Antigravity CLI
With Gemini CLI ending on June 18, here is a practical walkthrough for finding gemini command dependencies hiding in cron, CI, and shell scripts, then migrating and verifying them on Antigravity CLI.
Antigravity2026-05-23
Moving to the Antigravity CLI (agy): Shifting Your Scripts Off Gemini CLI Before the June 18 Shutdown — Without Downtime
A grounded walkthrough of Google's Antigravity CLI (agy): fastest setup, a no-downtime migration off Gemini CLI, a compatibility shim, the Pro vs Ultra cost break-even, and running recurring work with scheduled messages — based on actually moving my own repos across.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →