エージェントが変更を書き終えた通知が出るたび、別ウィンドウのターミナルへ移っていました。テストを走らせ、落ちた行を目で追い、また戻る。作業そのものより、この往復のほうが疲れる日があります。
2.10.0(8月24日)で、サイドバーから直接ターミナルを開けるようになりました。Ctrl / Cmd + ` の一打です。同時に Review ペインで作業ツリーの差分確認・ステージ・コミットまでアプリ内で完結するようになりました。
一見すると地味な変更です。ただ私の場合は、「変更を通す前に必ず一度は自分でコマンドを打つ」という手順そのものを組み直すきっかけになりました。往復のコストが下がった結果、何を走らせるかを先に決めておかないと確認が散漫になる、という別の問題が見えてきたからです。
往復が消えると、確認の質が問われはじめます
外部ターミナルへ出るのが面倒だった頃は、確認の回数が自然に絞られていました。面倒さが、ある種のフィルターとして働いていたわけです。
その面倒さが消えると、今度は「なんとなく走らせる」が増えます。前回と違うコマンドを打ち、前回と違う範囲を見て、結局のところ何を確かめたのか自分でも説明できない状態になります。個人開発では、この曖昧さを指摘してくれる相手がいません。
ですので、埋め込みターミナルを使い始めるときにまずやるべきは、走らせるコマンドを固定することだと考えています。
走らせるコマンドを3つに固定する
私が使っているのは次の3つです。目的が重ならないように選んでいます。
| 確かめること | コマンドの性格 | 走らせるタイミング |
|---|---|---|
| 形が壊れていないか | 型チェック・構文チェック(tsc --noEmit など) | エージェントの変更を読む前 |
| 振る舞いが壊れていないか | テスト(変更範囲に限定) | 差分を読み終えた後 |
| 範囲が想定内か | git diff --stat | ステージする直前 |
順番に意味があります。形が壊れているうちに差分を読んでも、読んだ内容が無駄になります。逆に、差分を読まずにテストだけ通して満足すると、通ってしまう種類の間違い(意図と違う実装)を見逃します。
3つ目の git diff --stat は、レビューではなく計測です。エージェントに小さな修正を頼んだつもりが 40 ファイルに触れていた、という状況を、コミット前に一度だけ数字で確認します。触れたファイル数が想定の何倍かで、そのまま通すか分け直すかを決めています。差分が膨らんだときの分け方は、Antigravity が一気に書いた巨大な差分を、意味単位のコミットに分け直す にまとめています。
変更したファイルだけを検証する
固定した3つのうち、実際に時間を食うのは1つ目と2つ目です。ここを全件で走らせていると、往復が消えた意味がなくなります。
手元の記事リポジトリ(MDX 1,031 ファイル)で、フロントマターの必須キーを検証する簡単なスクリプトを走らせて比較してみました。
| 対象 | ファイル数 | 所要時間 |
|---|---|---|
| リポジトリ全件 | 1,031 | 6,787 ms |
| 変更分のみを想定 | 3 | 27 ms |
251 倍の差です。1回あたり 6.8 秒であれば我慢もできますが、エージェントに任せた変更を1日に何十回も確認する運用では、この 6.8 秒が確認をためらう理由になります。
対象を絞るスクリプトは次の形に落ち着きました。埋め込みターミナルから直接叩けるよう、リポジトリのルートに置いています。
#!/usr/bin/env bash
# verify-changed.sh — 変更されたファイルだけを検証する
set -euo pipefail
# 未コミットの変更(追加・コピー・変更)を対象にする。
# -z と mapfile -d '' を使うのは、空白を含むパスで壊れないようにするためです。
mapfile -d '' -t CHANGED < <(git diff --name-only --diff-filter=ACM -z HEAD)
if [ "${#CHANGED[@]}" -eq 0 ]; then
echo "変更なし。検証をスキップします。"
exit 0
fi
echo "対象 ${#CHANGED[@]} 件"
# 拡張子ごとに検証を振り分けます。
TS_FILES=()
for f in "${CHANGED[@]}"; do
case "$f" in
*.ts|*.tsx) TS_FILES+=("$f") ;;
esac
done
if [ "${#TS_FILES[@]}" -gt 0 ]; then
# tsc は単体ファイル指定だと tsconfig.json を無視します。
# プロジェクト全体で型検査し、結果を変更ファイルで絞る形にしています。
npx tsc --noEmit --pretty false 2>&1 \
| grep -F -f <(printf '%s\n' "${TS_FILES[@]}") \
|| echo "型エラーなし(変更範囲)"
fi
exit 0tsc の扱いには注意が必要でした。ファイルを引数で直接渡すと tsconfig.json の設定が読まれず、strict を有効にしているプロジェクトでは検査が緩くなります。設定を効かせたまま出力側で絞る、という形にしているのはそのためです。
ここは、ドキュメントを読んだだけでは気づけなかった部分でした。私自身、最初は素直にファイルを引数で渡す書き方をしていて、しばらく「なぜか型エラーが出ない」状態を放置していました。
埋め込みターミナルで最初に確かめる2つの前提
サイドバーのターミナルは、外部ターミナルと同じ環境で立ち上がるとは限りません。使い始めに詰まりやすい箇所が2つあります。
PATH の継承。GUI から起動したアプリケーションは、ログインシェルが読む設定ファイルを通らないことがあります。手元では動くコマンドが、埋め込みターミナルでは command not found になる、という形で表面化します。同じ原因はエージェント側の実行でも起きるため、Antigravity のエージェントが node や python を『command not found』にするときの原因と対処 で扱った確認手順がそのまま使えます。
カレントディレクトリ。マルチルートのワークスペースを開いていると、ターミナルの起点がどのルートになるかが分かりにくくなります。検証スクリプトを相対パスで書いていると、静かに違うリポジトリを見に行きます。私は冒頭で git rev-parse --show-toplevel を確認するようにしました。
日本語の出力が崩れる場合は、エンコーディングの設定が別にあります。こちらは Antigravity 内蔵ターミナルで日本語が文字化けするときの原因と対処 が該当します。
Review ペインとターミナルの役割を分ける
2.10.0 では Git 操作もサイドバーに入りました。両方が手元にあると、どちらで何をするかが曖昧になりがちです。私は次のように分けています。
| Review ペインで見るもの | ターミナルで走らせるもの |
|---|---|
| 意図どおりの実装になっているか | 形が壊れていないか(型・構文) |
| 意図しないファイルに触れていないか | 振る舞いが壊れていないか(テスト) |
| コミット単位として意味が通るか | 変更範囲の計測 |
境目は「人間にしか判断できないか」です。意図との一致は読むしかありません。壊れているかどうかは機械のほうが確実です。この線引きを決めておくと、Review ペインで差分を眺めながら「これ動くのかな」と迷う時間が減ります。
検証コマンドを毎回手で打つのが煩わしくなったら、タスク定義に寄せる手もあります。Antigravity の tasks.json と launch.json でワンキー開発環境を仕上げる で扱った構成と組み合わせると、埋め込みターミナルからの起動も一手で済みます。
次の一手
まずは verify-changed.sh に相当するものを、いま触っているリポジトリに1本置いてみてください。中身は空でも構いません。「変更分だけを対象にする入口」がリポジトリのルートにあること自体が、確認をためらわない仕組みになります。
エージェントに任せる範囲そのものをどう決めるかについては、メンバーシップ向けの記事で、実際の作業ツリーを数えながら整理しています。手順の話より一段手前の、範囲の話に興味があればそちらもどうぞ。