ANTIGRAVITY LABEN
記事一覧/連携・プラグイン
連携・プラグイン/2026-09-12中級

Antigravity CLI 1.1.28 で print-timeout 超過が成功終了になりました — 無人実行の判定を見直す

1.1.28 から --print-timeout の超過は例外ではなく、部分出力を返しての正常終了になりました。外部 URL の取得も既定で承認待ちです。終了コードだけで成否を決めている無人実行を、どう組み直したかを書き残します。

Antigravity CLI32headless3CI9自動化39終了コード

夜のうちに走らせていた処理のログを、朝いちばんに開いた日のことです。行末には「成功」とだけ書いてありました。ところが同じ時刻に書き出されているはずの成果物は、途中の段落で切れておりました。

終了コードは 0 です。スクリプトはその 0 だけを見て、成功として記録していました。

原因を探して設定を疑い、プロンプトを疑い、最後に版の更新履歴へ戻りました。答えはそこにありました。読み落としていたのだと気づいたのは、三度目に開いたときでした。Antigravity CLI 1.1.28(9月9日)で、--print-timeout の超過が「失敗」から「部分出力を返しての正常終了」へ変わっていたのです。

9月12日時点の最新は 1.2.2 で、この挙動は 1.2 系にもそのまま入っております。1.1.27 以前から一気に上げた場合は、以下の変更をまとめて受け取ることになります。

1.1.28 で変わったのは、失敗の伝え方でした

まず全体像をお伝えします。1.1.28 の変更のうち、無人実行に直接効くのは次の4点です。

変更点1.1.27 以前1.1.28 以降
--print-timeout の超過タイムアウトエラーで失敗部分出力を返し、stderr に警告を出して正常終了(Ctrl+C 等の割り込みは従来どおり非ゼロ)
外部 URL の取得既定で常に許可既定で先に承認を求める(事前に許可していない場合)
致命的エラーの出力黙って終わることがあったstderr に error: という安定したマーカー付きで出る。打ち切りの可能性がある場合は注記も出る
-p の終了タイミング最終回答を返したら速やかに終了。実行中のバックグラウンドタスクとタイマーは --print-timeout の範囲で待ち、dev server などのデーモンは止めずに残す

一段落目と二段落目は、方向が逆に見えます。片方は失敗を成功として返すようにし、もう片方は黙っていた失敗を喋らせるようにしました。

けれども並べてみると、意図は一つに見えてきます。終了コードという 1 ビットに載せていた情報を、stderr という帯域の広い場所へ移したのです。0 と 1 では「途中まではできた」を表せません。

私は最初のうち、この変更を歓迎しきれませんでした。終了コードで全部を判定できたほうが、スクリプトは短く済むからです。いまは考えを改めております。短く書けていたのではなく、表現できないものを 0 に丸めていただけでした。

--print-timeout の超過を受け取り直す

判定を書き直します。要点は、成功と失敗の二値ではなく、部分(partial)という第三の状態を持たせることです。

#!/usr/bin/env bash
set -uo pipefail
 
OUT="$(mktemp)"; ERR="$(mktemp)"
trap 'rm -f "$OUT" "$ERR"' EXIT
 
agy -p "$PROMPT" --print-timeout 600 >"$OUT" 2>"$ERR" </dev/null
code=$?
 
if [ "$code" -ne 0 ]; then
  status=failed                       # 割り込み・起動失敗はここに落ちます
elif grep -q '^error:' "$ERR"; then
  status=failed                       # 終了コードが 0 でも、マーカーがあれば失敗です
elif [ -s "$ERR" ]; then
  status=partial                      # 警告が出ている = 途中で区切られた可能性があります
else
  status=ok
fi
 
printf '%s\t%s\t%s\n' "$(date -u +%FT%TZ)" "$status" "$(wc -c <"$OUT")" >> run.tsv

grep -q '^error:' でマーカーを見ているのは、この文字列だけが安定したものとして定められているからです。タイムアウト時の警告文そのものは版で変わりえますので、文字列一致に頼らず「stderr に何か出ていること」を条件にしております。ここを凝った正規表現にすると、次の版で静かに外れます。

もう一つ添えておきたいことがあります。この判定でも、成果物が意味のあるかたちで完結しているかは分かりません。stderr が空でも、モデルが早めに話を畳んだだけかもしれません。

ですから私は、バイト数を毎回記録して、前日までの中央値から大きく外れた日を別途拾うようにしました。判定を賢くするより、外れ値を後から見つけられる形で残すほうが、結果として手戻りが少なくなります。

終了コードは走り切ったかを答えるだけです。完結したかどうかは、成果物に聞きます。 この順番だけは、急いでいる日でも崩さないようにしております。

なお、呼び出し側のパイプが終了コードそのものを握りつぶしてしまう問題は、これとは別の層の話になります。そちらはAntigravity CLI の失敗を握りつぶしていたのは呼び出し側のパイプでしたに書きました。set -o pipefail を入れていない環境では、まずそちらから直したほうが早いはずです。

外部 URL の取得が承認待ちになりました

4点のうち、いちばん気づかれないまま事故になるのがこれです。外部 URL の取得が、既定で「常に許可」から「先に尋ねる」へ変わりました

対話で使っているぶんには、承認のプロンプトが出て終わりです。1.1.28 では表示も具体的になり、Run this command? Allow access to this URL? Allow calling this tool? と、何を承認するのかが明示されるようになりました。フックや別プロジェクトのファイルが理由のときは Reason: の行も添えられます。

問題は無人で走らせている側です。応答する人がいない場所で承認を求められると、処理はそこで待ちます。

私自身、無人で回す処理に「止まるべきところで止まる」仕組みを入れる意味は、よく分かっているつもりです。ただしそれは、止まる条件をこちらが把握している場合の話なのです。把握していなければ、ただ進まないだけになります。

対処は二つの方向があります。

一つめは、事前に許可ルールへ登録しておく方法です。許可ルールは CLI 側・共有・プロジェクトの各設定ファイルに書けます。ただし設定キーの名前は自分の版のドキュメントで確認してください。私は過去に、それらしい名前のキーを書いて、警告も出ないまま何も効いていなかったことがあります。誤ったキーに対する反応は一様ではなく、落ちるもの・警告だけのもの・完全に黙るものがあるのです。

ですから、書いたら必ず挙動で確かめます。

# 許可が効いているかを、待たせずに確かめます
timeout 90 agy -p "https://example.com の h1 を一行で返してください" \
  --print-timeout 60 </dev/null 2>err.txt
echo "exit=$?"; cat err.txt

標準入力を閉じ、--print-timeout を短く切り、外側にも timeout を重ねます。許可が効いていれば結果が返り、効いていなければ 60 秒で区切られて stderr に警告が残ります。どちらの場合も、待ち続けることはありません。

二つめは、そもそも URL を読ませない構成にしてしまう方法です。無人の処理で外部の内容を取りに行かせると、取得先が変わっただけで出力が変わります。私は定期実行の側では、取得は別工程で済ませ、CLI には手元のファイルだけを渡すようにしております。

終了のタイミングと、残されるデーモン

もう一つ、CI で引っかかりやすい変更があります。1.1.28 の -p は、最終回答を返したら速やかに終了するようになりました。実行中のバックグラウンドタスクとスケジュールされたタイマーは --print-timeout の範囲で待ちますが、dev server のようなデーモンは止めずに残します

つまり、CLI は正常に終了したのに、ジョブそのものは終わらない、という並びが起こりえます。CLI が起動したプロセスが、まだポートを掴んだまま生きているからです。

エージェントに開発サーバーを立てさせる工程を挟んでいるなら、後始末は呼び出し側で持ってください。プロセスグループごと畳むか、確保させるポートを固定して最後に解放するか、どちらかです。同じ版で、実装計画の承認待ちで非対話実行が永久に止まる不具合も直っておりますので、1.1.27 以前で「たまに帰ってこない」に悩んでいた場合は、まず版を上げるのが先になります。

ついでに、地味ですが効く変更も書き残します。指定したモデル名が別のモデルへ解決されたとき——別名の解決、--effort による変種の選択、廃止されたモデルの置き換え——その事実が CLI のログに記録されるようになりました。「指定したはずのモデルで動いていない」を確かめる手段が、ようやく手元に来たわけです。

版を上げる前後で、確かめておく順序

最後に、私が実際に踏んだ順番をそのまま置いておきます。

やること見るところ
1上げる前に、いまの判定が終了コードだけに依存していないか読み返すラッパーの if [ $? -ne 0 ] が唯一の分岐になっていないか
2stderr を捨てていないか確かめる2>/dev/null2>&1 でマーカーが混ざっていないか
3URL 取得の許可を、挙動で確かめる標準入力を閉じた短い実行が、待たずに返るか
4上げたあと、一度は人が見ている時間帯に流すpartial が出る頻度と、そのときの成果物
5成果物の大きさを毎回記録し始める数日ぶんの中央値から外れた日

4 の「人が見ている時間帯に流す」は、面倒でも飛ばさないでいただきたいところです。無人実行の変更点は、無人のまま確かめようとすると、確かめたつもりだけが残ります。

まずは手元のラッパーを開いて、stderr をどこへ流しているかだけ見てみてください。私の場合、そこが 2>/dev/null になっていたせいで、error: マーカーが一度も届いていませんでした。

お読みいただきありがとうございました。同じ朝を迎える方が一人でも減りましたら幸いです。

シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

連携・プラグイン2026-07-18
黙って通していた確認ツールを、ソフト拒否から allow ルールに起こす
Antigravity CLI 1.1.3 で、ヘッドレスの -p は確認の要るツールを黙って自動承認する代わりに、ソフト拒否して必要な allow ルール名を stderr に示すようになりました。この出力を「発見」に使い、全許可からではなく空許可から最小権限を組み上げる逆向きのループを、動くハーネスと個人運用の実測でまとめます。
連携・プラグイン2026-06-13
Antigravity CLI を非対話で回す — CI と cron に載せる前の設計
Gemini CLI の提供終了を機に移行した Antigravity CLI を、CI と cron に載せる前の設計です。対話前提のまま置くと固まる理由、二重起動に耐える冪等性、終了コードと JSON での成否判定、認証情報の安全な渡し方までを扱います。
連携・プラグイン2026-08-22
stream-json 入力で Antigravity CLI を外部から回すとき、会話をどこで切るか
print モードに加わった --input-format stream-json は、外部のドライバがセッションを開いたまま一件ずつ流せる仕組みです。24 件のジョブで会話が抱える量を計測し、バイト予算だけで切ると仕事の途中で文脈が切れることを確かめ、切る単位の決め方を整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます