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 CLI5Gemini CLI10Migration3Shell ScriptCI

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-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
Antigravity CLI (agy) First Look: Migrating from Gemini CLI and Reading the Slash Commands
A grounded walkthrough of Google's new Antigravity CLI (agy): how to choose between Antigravity 2.0 and Antigravity IDE, how to migrate from Gemini CLI, and the slash commands worth memorising on day one.
Antigravity2026-04-07
Introduction to Context Engineering: How to Grow AI Into Your Personal Partner
What context engineering is, why it matters now, and how to apply it. Learn how it differs from prompt engineering, and how to deliberately design the context you give AI to dramatically improve its output quality.
📚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 →