1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GAS × Antigravity で「会話するだけでGASが直る」 秀GASマネージャーを作った話

1
Posted at

はじめに

先日、Google Apps Script(GAS)を clasp を介さずに Python の MCP サーバーから直接操作する記事を書きました。

手元にファイルを落とさず、Google Apps Script API をメモリ上で直撃するようにしたことで、修正から反映までの待ち時間が消え、作業のリズムが大きく変わりました。

せっかくここまで快適になったのだから、先に公開している「秀エクセルマネージャー(shu-excel-manager)」と同じように、誰でも使える形で GitHub に公開しよう。そう思い立ちました。

ただ、公開するからには簡単な手直しで済ませたくありません。

「どうせ出すなら、動作の速さを一番念頭に置いて、とことんまで作り込んでから出そう」

そう決めて、Antigravity の上で親エージェントに陣頭指揮(番頭役)を執らせ、サブエージェント(Gemini Flash)を実装部隊として動かす体制を組み、丸一日かけて徹底的な改修と実機検証を行いました。

こうして仕上がった 「秀GASマネージャー(shu-gas-manager)」 を、本日 GitHub に公開しました。

この記事では、Antigravity と会話するだけで GAS が直り、その場で動き、診断まで終わるようになった仕組みと、公開前に行った徹底検証の裏側を紹介します。

TL;DR

  • Antigravity や Claude などの AI と会話するだけで GAS の読み書き・診断・実行・デプロイが完結する 「秀GASマネージャー(shu-gas-manager)」 を MIT ライセンスで公開しました
  • 動作速度を最優先に設計: プロジェクト名解決を 680ms ➔ 0.35ms、本番稼働コードとの差分比較(diff-prod)を 5.6秒 ➔ 0.305ms(約6,200倍高速)、2回目以降の健康診断を 99ms まで短縮しました
  • 4つの深層アップグレードを搭載:
    1. 関数スコープ限定のピンポイント置換(patch-func)と複数ファイル一括トランザクション(batch)
    2. クラウド上の過去世代一覧(versions)・本番稼働版との Unified Diff(diff-prod)・世代ロールバック(restore-version)
    3. ループ内の重い API 呼び出しや HTML の RPC リンク切れ・引数ズレを見抜く 10項目健康診断(diagnose)
    4. デプロイ不要で任意の GAS 関数をクラウド実行し、Logger.log と戻り値をその場で回収する リモート関数実行(run --fast) & ローカル双方向同期(pull / push)
  • 単体テスト81件 + クラウド実機総当たりテスト48項目 をすべて通過し、実機で起きた 0.2 秒の反映ラグや Windows の改行コード問題まで潰し切ってからのリリースです

「会話するだけでGASが直る」とはどういうことか

従来の GAS 開発では、ちょっとした修正でも人間の手作業がいくつも挟まっていました。ブラウザでスクリプトエディタを開くか、ターミナルで clasp pull してファイルを直し、clasp push して、さらにブラウザで関数を選択して「実行」ボタンを押し、実行ログを確認する。

秀GASマネージャーを Antigravity に繋ぐと、これらの画面移動がすべて消えます。人間がやることは、チャット欄で AI に話しかけるだけです。

たとえば、「〇〇の関数で、エラーになったときの戻り値を直して、実際に動くか試しておいて」と頼むと、AI は裏で次の手順を数秒のうちに自律的に回します。

1. outline(関数マップ取得)で対象ファイルと行番号を 0.1 秒で特定
2. get_function でその関数だけをピンポイント抽出(ファイル全文は読まない)
3. patch_function でその関数の { ... } の内側だけを安全に書き換え
   (反映前に Node.js の vm モジュールで JavaScript 構文エラーを自動検査)
4. run_function でクラウド上の関数を直接叩き、戻り値と Logger.log を回収して確認

人間はブラウザを一度も開きません。AI が自分でコードを直し、自分でクラウド上の GAS を動かしてログを確かめ、「直して実行確認まで終わりました。戻り値は 42、ログも正常です」と返してくるのです。

徹底的に作り込んだ4つの武器

公開にあたって、「ただコードを読み書きできるだけ」のツールから一歩踏み込み、実務で GAS を保守するときに本当に欲しくなる4つの機能を組み込みました。

1. 関数スコープ限定編集と、複数ファイル一括トランザクション

GAS のファイルが大きくなってくると、ファイル全体を対象にした文字列置換(patch)では、別の関数にある同じ名前の変数までうっかり書き換えてしまうリスクがあります。

そこで、指定した関数の { ... } の範囲内だけで置換を行う patch_function(CLI では patch-func)と、関数の追加(重複チェック付き)・削除を行う add_function / delete_function を作りました。

さらに、サーバー側の .gs と画面側の .html の両方を同時に直す場面のために、複数の変更操作をメモリ上で一括合成し、1回のバックアップ + 1回の Node.js 一括構文検査 + 1回の API 通信 でアトミックに反映する batch_patch(batch)を実装しました。途中で1ファイルでも構文エラーがあれば、クラウド側は1バイトも書き換わらずに安全に停止します。

2. GAS特有の地雷を0.1秒で抜く「10項目健康診断(diagnose)」

GAS には、構文エラーにはならないのに実行すると破綻する「特有の地雷」がいくつもあります。これを diagnose コマンド一発で丸ごと検査できるようにしました。

実際に自作の Web アプリ「Qクイック NEXT」に対して py gas.py diagnose "Qクイック NEXT" を走らせたときの実機出力がこちらです。

=== GAS プロジェクト健康診断: [Qクイック NEXT] ===
判定: 正常 (HEALTHY)
ファイル数: 5 | 総関数数: 10 | 検出された問題: 0件

[構文エラー] (0件):
  なし (全ファイル構文チェック合格)

[重複関数・グローバル衝突] (0件):
  なし (グローバル名前空間での関数名衝突はありません)

[グローバル変数・クラス衝突 (const/let/class)] (0件):
  なし (グローバル変数の衝突はありません)

[HTML RPC リンク切れ (google.script.run)] (0件):
  なし (全ての google.script.run 呼び出し先関数が存在します)

[RPC 引数不一致警告] (0件):
  なし (RPC引数の不一致はありません)

[HTML テンプレートリンク切れ (HtmlService)] (0件):
  なし (全てのテンプレート参照先 HTML が存在します)

[パフォーマンス警告 (ループ内同期API)] (1件):
  - GQuick_Server 行 334: UrlFetchApp.fetch -> ループ内での同期GAS API呼び出しは6分実行制限超過やクォータ枯渇の原因になります

[未参照・未使用の疑いがある関数] (1件):
  - [GQuick_Server:486] getOfficialChannelNames

[検出されたエントリーポイント]:
  - doGet -> GQuick_Server:614

[マニフェスト設定 (appsscript.json)]:
  - Runtime: V8
  - TimeZone: Etc/GMT-9
  - WebApp: access=MYSELF, executeAs=USER_DEPLOYING

GAS はすべての .gs ファイルが同じグローバル空間を共有するため、別ファイルに同じ名前の関数やトップレベルの const / let を書くと静かに衝突します。また、HTML 側の google.script.run からサーバー側のプライベート関数(末尾が _ の関数)を呼ぶと無言で失敗します。

こうした GAS ならではの落とし穴に加え、for や forEach ループの中で SpreadsheetApp や UrlFetchApp を呼んでいる箇所(6分制限超過の原因)や、どこからも呼ばれていない未使用関数まで、静的解析で一瞬で洗い出します。

検診

3. デプロイ不要でその場で関数を試す「リモート関数実行(run --fast)」

コードを直したあと、「この関数にテストデータを渡して、ちゃんと動くか今すぐ確かめたい」と思うことはしょっちゅうあります。しかし Google 標準の scripts.run API は、GCP プロジェクトの紐付けなど設定のハードルが非常に高く、気軽には使えません。

そこで秀GASマネージャーでは、開発用の @HEAD エンドポイントと一時ランナー注入を組み合わせた独自のリモート実行エンジン(run) を作りました。

仕組みはこうです。実行したい関数名と引数を渡すと、ツールが一時的に小さな受付フック(__gm_exec_)を注入し、OAuth トークン付きで最新 @HEAD を呼び出します。GAS 側で対象関数を実行し、戻り値・実行時間(ms)・Logger.log・console.log・エラースタックトレースを JSON で回収した直後に、finally ブロックで元のコードへ綺麗に戻します。

さらに、何度も連続で試したい開発中のために --fast モード を用意しました。ランナーを常駐させたままキャッシュで判定することで、2回目以降はコードの書き換え(PUT 通信)を一切行わず、1回の GET 通信だけ で即座に関数を実行します。作業が終わったら clean-runner を叩けば、注入したフックは跡形もなく消去されます。

# クラウド上の関数 e2eAdd(15, 27) をその場で実行してログと戻り値を回収
$ py gas.py run "MCPテスト" e2eAdd "[15, 27]" --fast
[SUCCESS] 関数実行: e2eAdd (所要時間: 4ms)
戻り値: 42
--- 実行ログ ---
  calc=42
  clog=405

即試す

4. 本番稼働コードとの 0.3ミリ秒比較(diff-prod)と双方向同期(pull / push)

Web アプリを運用していると、「いま本番で動いているバージョンと、手直しした最新の HEAD コードで、どこが違うんだっけ?」と確認したくなります。

diff-prod コマンドを叩けば、現在デプロイされている本番バージョンのコードをクラウドから取得し、最新 HEAD との Unified Diff を一発で表示します。そのまま特定の過去バージョンへ巻き戻す restore-version も備えています。

また、普段はメモリ直結で使いながら、「節目のタイミングで手元の Git リポジトリにも .gs や .html として書き出しておきたい」という場面のために、ローカルフォルダとの双方向同期(pull / status / push)も実装しました。push 時は変更のあるファイルだけを一括で Node.js 構文検査にかけ、差分が0件なら API 通信を一切行わずに 0.67ミリ秒 で即終了します。

速さへの執念 ── ミリ秒単位の実測ビフォーアフター

今回の作り込みで私が一番厳しく注文をつけたのが 「とにかく速く動くこと」 でした。AI が連続でコマンドを叩くとき、1回あたり2秒かかるのと0.1秒で返るのとでは、体感速度がまるで違うからです。

そのために、以下の徹底的な高速化を施しました。

  1. 軽量メタデータキャッシュ(.cache.json)とコンテンツキャッシュ(.content_cache.json)の分離永続化:
    プロジェクト一覧・スクリプトID・デプロイURL・構文検査済みファイルの SHA-256 ハッシュをディスクに保持し、別プロセスから CLI を単発実行しても Drive API 通信をスキップしてミリ秒で解決します。
  2. Node.js 構文検査の1プロセス一括バッチ化(_validate_syntax_batch):
    従来はファイルごとに Node.js プロセスを起動していたものを、1回の Node.js 起動で全ファイルをまとめて vm.Script 検査する方式に変えました。さらに一度合格したコードは SHA-256 ハッシュで記憶し、未変更ファイルの再検査を 0ms にしました。

実機(Google クラウド上の実プロジェクト)で計測した改修前後のベンチマーク結果がこちらです。

操作内容 改修前 / 初回通信 改修後(キャッシュ / 高速パス) 高速化倍率
プロジェクト一覧取得 (list) 682.8 ms(Drive API通信) 0.74 〜 5.70 ms 約 120 〜 900倍
スクリプトID解決 (resolve_script_id) 約 680 ms(毎回一覧取得) 名前指定 0.35 ms / ID指定 0.05 ms 約 1,900倍
10項目健康診断 (diagnose) 初回 2,271.7 ms(Node一括検査) 2回目以降 99.18 ms(ハッシュ記憶) 約 23倍(0.1秒未満)
本番稼働版との差分比較 (diff-prod) 初回 5,667.3 ms(Version取得) 2回目以降 0.305 ms(不変版キャッシュ) 約 6,200倍(0.3ミリ秒)
リモート関数実行 (run --fast) 毎回注入・撤去 4,646.2 ms 2回目以降 1,460.9 ms(GAS内実行 2〜4ms) 約 3.2倍(PUT通信ゼロ)
ローカル同期 (pull / status / push) 手動で1ファイルずつ取得・更新 pull: 2.19 ms / status: 16.21 ms / push(差分なし): 0.67 ms 差分0件時は通信ゼロ即答

Antigravity ならではの「番頭AI × サブエージェント」公開前48連撃テスト

今回の開発では、Antigravity の特徴であるサブエージェント機能をフル活用しました。

私がメインの AI に「あなたが陣頭指揮(番頭)を執って、フラッシュ君(Gemini Flash のサブエージェント)に実装させる体制で、徹底的に作り込んでくれ」と指示を出したのです。

最初は簡単な改善案を出してきた番頭 AI に対し、「もっと時間をかけてでも徹底的に改良してほしい」とハッパをかけたところ、そこから番頭 AI とフラッシュ君の猛烈な連携が始まりました。

  1. 第1段階(実装): 番頭 AI が詳細な設計書を書き、フラッシュ君が gas_client.py(約3,500行)・gas.py・gas_mcp_server.py を一気に実装し、単体テストを78件まで増やしてパスさせる。
  2. 第2段階(番頭による意地悪監査): 「本当にまずいところはないか徹底的に検証しろ」と私が指示すると、番頭 AI がコードを1行目から最終行まで精査し、通常のテストでは見つからない7つのエッジケースを洗い出しました。
    • Windows 環境で pull した際、改行コード(CRLF と LF)の違いで未編集ファイルが「変更あり」に化ける問題
    • GAS でよくある同名の index.gs と index.html が共存するプロジェクトで batch を実行した際の辞書キー衝突
    • 不変バージョンのソースコードを軽量キャッシュ側に保存してしまい、繰り返すと起動が重くなる問題
  3. 第3段階(実機への全48項目総当たりテスト): さらに「モックだけでなく実機で全コマンドを徹底的に叩け」と指示し、Google クラウド上のテスト用プロジェクトに対して、全31サブコマンド・全26 MCP ツールを片っ端から実機発火させる総当たりスクリプトを走らせました。

すると、モックの単体テスト(81件)では100%通っていたにもかかわらず、実機でしか起きない2つの現象 がその場で炙り出されました。

  • 1つ目は、CLI(別プロセス)でファイルを追加した直後に、常駐している MCP サーバー側が自分のメモリキャッシュ(TTL 30秒)を優先してしまい、追加されたばかりのファイルを見落とす現象。これはディスクキャッシュの更新時刻(st_mtime)をミリ秒比較する3行の修正で解決しました。
  • 2つ目は、run でランナー関数を API PUT した直後(0ミリ秒後)に @HEAD URL を叩くと、Google 側のサーバー反映に約 0.2 秒のタイムラグがあり、1回目だけ古い doGet が返ってくる現象。これも自動リトライ(0.4秒待機)を入れることで、初回から1発で通るようになりました。

最後にテスト用プロジェクトの全ファイルがテスト前と 1バイトの狂いもなく完全一致(原状回復) していることまで自動確認し、実機総当たり 48 PASS / 0 FAIL、単体テスト 81 PASS を達成してからの GitHub 公開となりました。

「AI にコードを書かせる」だけでなく、「親 AI に監査役を担わせ、実機テストで自分の道具の死角を炙り出させて直す」。このサイクルを回せたことが、今回の最大の収穫でした。

総点検

1分で使える導入手順

秀GASマネージャーは、すでに clasp login 済みの環境なら 面倒な GCP 設定や OAuth 同意画面の作成を一切せずに 1 分で導入 できます。

# 1. リポジトリのクローンと依存パッケージのインストール
git clone https://github.com/shu1551/shu-gas-manager.git
cd shu-gas-manager
pip install -r requirements.txt

# 2. セットアップ診断(Google Apps Script API 設定画面の確認)
py gas.py setup --open

あとは、Antigravity や Claude Desktop、Cursor などの MCP 設定ファイルに以下を登録するだけです。

{
  "mcpServers": {
    "gas-manager": {
      "command": "python",
      "args": ["C:/path/to/shu-gas-manager/gas_mcp_server.py"]
    }
  }
}

リポジトリには、AI が最短手数(outline ➔ get_function ➔ patch_function ➔ diagnose)で賢く動くためのスキル定義書(SKILL.md)も同梱しています。

おわりに

最初は「毎回 clasp push するのが面倒だ」という素朴な疑問から始まった小さな道具でしたが、速度をミリ秒単位まで突き詰め、10項目の健康診断やリモート関数実行、世代比較まで組み込んだことで、GAS 開発の景色がまるで変わりました。

Excel VBA を直撃する「秀エクセルマネージャー」と、Google Apps Script を直撃する今回の「秀GASマネージャー」。場所はデスクトップとクラウドで正反対ですが、根底にある考え方はまったく同じです。

AI に人間と同じ遠回りな画面操作をさせるのではなく、AI が一番速く・安全に力を発揮できる「直通の道具」を作って渡してあげること。

GAS を日常的に触っている方や、Antigravity・Claude で GAS 開発をもっと快適にしたい方は、ぜひ一度試してみてください。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?