6/18 で Gemini CLI と Gemini Code Assist の IDE 拡張が、無料個人ユーザーと AI Pro / Ultra 加入者向けのリクエスト処理を終了し、Go 製の Antigravity CLI へ集約されます。手元のターミナルで gemini を打ち直すだけなら数分の作業です。
ところが、私が自分のアプリ運用の自動化を点検していて肝を冷やしたのは、gemini という文字列が「自分でも忘れていた場所」に何度も埋まっていたことでした。GitHub Actions のワークフロー、コミット前に走る git フック、深夜に回している cron、package.json の scripts、Makefile のターゲット。どれもターミナルでは目に入りません。締切当日にこれらが静かに失敗し、しかも「終了したから失敗した」と気づけるエラーすら出ないケースがあります。
この記事は「コマンド名を置き換える方法」ではなく、置き換え漏れをゼロにし、本番の自動化を止めずに切り替え、いざというとき即座に戻す ための実務手順です。私自身、個人開発で複数のリポジトリと自動パイプラインを並行して回しているので、この棚卸しの重要さは身に染みています。
なぜ「手元で動く」確認だけでは移行が完了しないのか
CLI の移行で事故が起きるのは、たいてい次の3つの理由が重なったときです。
第一に、呼び出し箇所が分散している こと。対話的に使う gemini は氷山の一角で、実際には非対話モード(パイプやサブコマンド)で機械的に呼んでいる箇所のほうが多いものです。第二に、失敗が静かに起きる こと。CI のステップが || true で握りつぶされていたり、cron の標準エラーがどこにも飛んでいなかったりすると、終了後しばらく誰も気づきません。第三に、コマンド名以外もずれる こと。設定ファイルの場所、環境変数名、認証情報の参照先が新 CLI で変わっていれば、antigravity に置換しても「コマンドは見つかるのに認証で落ちる」状態になります。
ここでの落とし穴は、こうした不整合が本番運用に入ってから初めて顕在化する ことです。だからこそ事前に注意点を洗い出して回避し、それでも起きた場合の対処を先に決めておきます。
ですから移行の最初の一手は、置換ではなく棚卸し です。「どこで・どう・誰の権限で gemini を呼んでいるか」を一覧にしてから動きます。
まず参照箇所を機械的に洗い出す監査スクリプト
最初に、リポジトリと運用環境の両方を横断して gemini 参照を引き出します。コメントや文字列リテラルも含めて広めに拾い、あとから人間が取捨選択する方針です。漏れより過検出のほうが安全だからです。
#!/usr/bin/env bash
# audit-gemini.sh — gemini CLI への依存を横断的に洗い出す
# 使い方: ./audit-gemini.sh /path/to/repo1 /path/to/repo2 ...
set -euo pipefail
REPORT = "gemini-audit-$( date +%Y%m%d-%H%M).md"
echo "# Gemini CLI 依存監査 $( date )" > " $REPORT "
scan_dir () {
local root = " $1 "
echo -e "\n## $root " >> " $REPORT "
# 1) ソース・設定ファイル内の呼び出し(.git や node_modules は除外)
echo -e "\n### ファイル内参照" >> " $REPORT "
grep -rInE '\bgemini\b' " $root " \
--include= '*.sh' --include= '*.yml' --include= '*.yaml' \
--include= '*.json' --include= '*.toml' --include= 'Makefile' \
--include= '*.mjs' --include= '*.ts' --include= '*.js' \
2> /dev/null | grep -v '/node_modules/' | grep -v '/.git/' \
>> " $REPORT " || echo "(該当なし)" >> " $REPORT "
# 2) git フック(追跡対象外なので個別に見る)
echo -e "\n### git フック" >> " $REPORT "
if [ -d " $root /.git/hooks" ]; then
grep -rIn 'gemini' " $root /.git/hooks" 2> /dev/null \
| grep -v '\.sample:' >> " $REPORT " || echo "(該当なし)" >> " $REPORT "
fi
}
for target in " $@ " ; do
scan_dir " $target "
done
# 3) ユーザーの cron(リポジトリ外に潜むことが多い)
echo -e "\n## crontab(現在のユーザー)" >> " $REPORT "
crontab -l 2> /dev/null | grep -n 'gemini' >> " $REPORT " || echo "(該当なし)" >> " $REPORT "
# 4) PATH 上に旧バイナリが残っていないか
echo -e "\n## PATH 上の gemini バイナリ" >> " $REPORT "
command -v gemini >> " $REPORT " 2> /dev/null || echo "(PATH になし)" >> " $REPORT "
echo "✅ レポート出力: $REPORT "
このスクリプトの肝は、追跡対象外の場所まで見にいく 点です。.git/hooks と crontab -l は git grep では絶対に引っかかりません。私が冷や汗をかいたのも、まさに pre-push フックの中に整形チェック用の呼び出しを仕込んでいたケースでした。出力された Markdown を上から眺め、各行を「対話用途/自動化用途」に色分けしておくと、次のドライランの優先順位が決まります。
package.json の scripts に潜むものは、依存関係としても確認しておくと確実です。
# scripts セクションだけを抜き出して確認
node -e "const p=require('./package.json'); console.log(JSON.stringify(p.scripts||{}, null, 2))" \
| grep -n 'gemini' || echo "scripts に gemini 参照なし"
コマンド対応の確認とドライランの順序
洗い出しが済んだら、置換の前に新旧の挙動差を1か所で確認 します。バイナリ名は gemini から antigravity へ変わりますが、移行で本当に効いてくるのは名前ではなく、その周辺です。最低限、次の4点は新 CLI 側の実体を自分の目で確かめてから一括置換に進みます。
起動コマンド名(gemini → antigravity)と、非対話実行のサブコマンド/フラグが従来と同じ綴りか
設定ファイルの探索パス(旧 CLI のホーム配下の設定を新 CLI が読むのか、別の場所を見るのか)
認証情報の参照元(環境変数名・認証フローが変わっていないか)
終了コードの意味(成功時 0/失敗時非ゼロが従来と一致するか。CI の合否判定はここに依存します)
確認は「壊れても影響のない一時ディレクトリ」で、読み取り専用の軽い処理から始めるのが鉄則です。いきなり本番のスクリプトを流すと、副作用込みで失敗したときに切り分けが難しくなります。
# ドライラン用の隔離ディレクトリで最小確認
TMP = "$( mktemp -d )" ; cd " $TMP "
echo "console.log('hello')" > sample.js
# 新 CLI が PATH にあるか・バージョンが取れるか(副作用ゼロの確認から)
antigravity --version || { echo "❌ antigravity が見つかりません。インストールを先に" ; exit 1 ; }
# ヘルプを読んでサブコマンド/フラグの実体を確認する
# ※ 実際のサブコマンド名は公式の移行ノートで必ず確認すること
antigravity --help | head -40
echo "確認が済んだら本番スクリプトの置換に進む" ; cd - > /dev/null
ここで --help の出力を素直に読むのが近道です。私は「旧 CLI と同じフラグだろう」と決めつけて一括 sed をかけ、非対話実行のフラグ綴りが一字違っていて CI が赤になった経験があります。綴りの推測は禁物 で、必ず実体を見てから機械置換に入ります。
CI ワークフローの書き換えは「失敗を見えるように」しながら
CI の中の呼び出しは、置換と同時に失敗が見える形に整える のが移行のチャンスです。終了間際の自動化が静かに死ぬ最大の原因が、エラーの握りつぶしだからです。
# Before(GitHub Actions の一例)— 失敗が握りつぶされている
- name : コード要約を生成
run : gemini summarize ./src > summary.txt || true
# After — コマンドを置換し、失敗をジョブの失敗として顕在化させる
- name : コード要約を生成
run : |
set -euo pipefail
antigravity summarize ./src > summary.txt
# 移行直後だけは continue-on-error で「落ちるが止めない」観測期間を作るのも手
continue-on-error : true
ポイントは2つあります。1つは || true を外して set -euo pipefail を入れ、本当に動いているかを終了コードで判定できる状態にする こと。もう1つは、移行直後の数日だけ continue-on-error: true を付け、「失敗しても全体は止めないが、ログとステータスには残す」観測モードを挟むことです。こうしておけば、置換漏れや認証ずれが本番を巻き込む前にダッシュボード上で気づけます。観測期間が過ぎたら continue-on-error を外し、通常の必須ステップへ戻します。
エージェントを CI から呼ぶ設計そのものを見直すなら、Antigravity の CLI とエディタをどう使い分けるか の整理も合わせて確認すると、移行のついでに役割分担を整えられます。
切り戻し(ロールバック)を先に設計しておく
移行で一番やってはいけないのは、「新 CLI に全部差し替えてから祈る」ことです。本番の自動化を止めないために、戻し方を先に用意してから 前に進みます。
実務的に効くのは、呼び出しを薄いラッパー1枚に集約しておく方法です。各スクリプトが直接 antigravity を叩くのではなく、ai-cli のような中間コマンドを経由させ、ラッパーの中で実体を切り替えます。
#!/usr/bin/env bash
# ai-cli — 移行期間中の薄いラッパー。実体を環境変数1つで切り替える
set -euo pipefail
# AI_CLI_IMPL=antigravity(既定) / gemini(緊急時の切り戻し用)
IMPL = "${ AI_CLI_IMPL :- antigravity }"
if ! command -v " $IMPL " > /dev/null 2>&1 ; then
echo "❌ ' $IMPL ' が見つかりません(AI_CLI_IMPL を確認)" >&2
exit 127
fi
exec " $IMPL " " $@ "
各所の呼び出しを ai-cli ... に置換しておけば、万一 antigravity 側で想定外の挙動が出たとき、AI_CLI_IMPL=gemini を立てるだけで(6/18 まで、あるいは旧バイナリが手元に残っている間は)瞬時に戻せます。切り替え点が1か所に集約されているので、全スクリプトを再 sed する必要がありません。
もちろん 6/18 以降は gemini 側がリクエストを受け付けなくなりますから、これは「移行当日に新 CLI で事故っても、原因切り分けの間だけ旧挙動で延命する」ための保険です。恒久対策は、観測期間中に置換漏れと認証ずれをすべて潰し切ることにあります。ラッパーを残しておけば、将来また CLI が変わったときにも同じ防御が使えます。
移行後の検証を「人手のチェックリスト」にしない
切り替えた後に「たぶん大丈夫」で終わらせると、次に動くのが深夜の cron だった場合、翌朝まで失敗に気づけません。検証も機械化します。
#!/usr/bin/env bash
# verify-migration.sh — 移行が完了したかを機械判定する
set -uo pipefail
FAIL = 0
echo "== 1. 旧バイナリへの残存参照 =="
if grep -rInE '\bgemini\b' . \
--include= '*.sh' --include= '*.yml' --include= '*.yaml' \
--include= '*.json' --include= 'Makefile' 2> /dev/null \
| grep -v '/node_modules/' | grep -v 'ai-cli' | grep -q . ; then
echo "⚠️ まだ gemini 参照が残っています(上で確認)" ; FAIL = 1
else
echo "✅ 直接参照なし"
fi
echo "== 2. 新 CLI が応答するか =="
if antigravity --version > /dev/null 2>&1 ; then echo "✅ antigravity 応答 OK" ; else echo "❌ antigravity が応答しません" ; FAIL = 1 ; fi
echo "== 3. ラッパー経由で実行できるか =="
if AI_CLI_IMPL = antigravity ./ai-cli --version > /dev/null 2>&1 ; then echo "✅ ai-cli 経由 OK" ; else echo "❌ ラッパーが失敗" ; FAIL = 1 ; fi
[ " $FAIL " -eq 0 ] && echo "🎉 移行検証 PASS" || { echo "🛑 未完了の項目があります" ; exit 1 ; }
この検証スクリプトを移行ブランチの CI に1ステップとして組み込み、exit 1 でマージをブロックすれば、「検証を忘れる」という人的ミスそのものを消せます。エラー時にエッジで壊れた結果が固定化されると厄介なのは Web 配信でも同じで、キャッシュに壊れた結果を固定させない設計 と発想は共通しています。失敗を観測可能にし、固定化を防ぎ、戻せるようにする。CLI 移行もキャッシュ設計も、突き詰めると同じ原則に行き着きます。
個人開発でやってよかった順序
私が実際にうまくいったと感じた順序は、次の5段でした。
監査スクリプトで全参照を出す
隔離ディレクトリでドライランして新旧差を確認する
呼び出しを薄いラッパーに集約する
CI を観測モードで置換する
検証スクリプトを CI に組み込む
所要は半日ほどでしたが、そのうち実際の置換作業は全体の約10%にすぎず、残りの90%は「どこで呼んでいるか」を可視化する時間でした。逆に言えば、可視化さえ終われば移行はもう怖くありません。
締切まで日がない今やるべき具体的な一歩は1つだけです。まず上の audit-gemini.sh を、自分が関わる全リポジトリと現在のユーザーの crontab に対して走らせ、gemini がどこに埋まっているかの一覧を手元に出してください。置換はそのあとで構いません。見えてさえいれば、6/18 は静かに通り過ぎます。
移行を機にエージェントの定期実行そのものを設計し直すなら、スケジュール実行するエージェントの実装メモ も土台になります。お読みいただきありがとうございました。同じように複数の自動化を抱えている方の助けになれば嬉しいです。