はじめに ―― 直近4記事の大反響に背中を押されて
直近で公開した『秀GASマネージャー』に関する一連の4記事に、予想をはるかに超える大きな反響をいただきました。
- claspでやるのが馬鹿らしくなってきた ── Python MCPでGASを直撃したら、修正が爆速になってコードの質まで上がった話
- 「画面でデプロイしてください」と AI に言わせない ── GAS をブラウザゼロ・1秒台で直しきる『秀GASマネージャー』ができるまで
- GAS × Antigravity で「会話するだけでGASが直る」 秀GASマネージャーを作った話
- どうやら大変なものを作ってしまったかもしれない ── Gemini 4 Argon(ゴンちゃん)と組んでGASの自律カイゼン関所を作った夜
特に第2弾の記事は、公開からわずか1〜2日で 3,700 views を突破。「ブラウザを開かずにGASを直したい」「AIに画面ポチポチを頼まれる絶望から解放されたい」という現場の悲鳴と熱い共感が、数字となってダイレクトに伝わってきました。読んでくださった皆様、本当にありがとうございます。
しかし、道具というものは「作って公開して終わり」ではありません。
「現場で本当に役立つのか?」「実際の複雑なWebアプリを前にしても耐えられるのか?」
ここを証明して初めて、本物の武器と言えます。
そこで今回、私が日頃から仕事でガチ使いしている本番GAS Webアプリケーション『Mクイック』を俎上に載せ、実際に発生していた厄介なバグの撲滅と機能強化に挑みました。
結論から言えば、GASマネージャーの威力は本物でした。
劇的な改善を遂げたその生々しい実録と、本日 GitHub へ新たに公開した「新兵器」の全貌をお話しします。
舞台は、自作の Gmail 爆速ビューア『Mクイック』
今回の舞台となるのは、私が Google Apps Script の HTML Service で構築した Gmail 専用ダッシュボード 『Mクイック』 です。
Gmail の標準画面はどうしても重く、大量のメールを捌くときにワンテンポ待たされます。そこで、IndexedDB キャッシュ、仮想スクロール、楽観的UI更新をフル動員し、メール一覧を瞬時に切り替えられるようにした独自アプリです。
見た目はダークモードで軽快そのもの。
ですが、毎日使い倒していると、現場ならではの**「地味だが致命的にイラッとする怪奇現象」**に直面していました。
現場で起きた怪奇現象 ―― 「消したはずのメールがゾンビ復活する」
遭遇した不具合は、主に次の2点でした。
-
完全削除したメールが、しばらくするとゾンビのように復活する
ゴミ箱から完全に抹消したはずのメールが、画面をリロードしたりバックグラウンド同期が走ると、なぜか一覧にひょっこり再表示される。 -
削除や復元のボタンを押しても、たまに反映されない
サクサク動いているように見えて、Gmail の実データと通信がすれ違い、エラーで取り残されることがある。
普通の開発なら、ここでブラウザのデベロッパーツールを開き、コンソールログを仕込み、GAS のエディタを開いてブレークポイントを張り……と、何時間も溶かすところです。
しかし、私には 秀GASマネージャー があります。ブラウザを 1 秒も開かずに原因調査に入りました。
ブラウザを開かずにブラウザの中身を暴く新兵器『verify-ui』
まず、健康診断コマンドを一発叩いてみました。
py gas.py diagnose Mクイック
すると、サーバー側の関数とフロント側の呼び出しを突き合わせる深層解析が、即座に不整合を炙り出しました。
[RPC 引数不一致警告] (2件):
- Index 行 840: 関数 'deleteMessage' (期待: 1, 呼出: 3)
- Index 行 840: 関数 'restoreMessage' (期待: 1, 呼出: 3)
原因の半分はこれでした。
画面側の JavaScript が、引数を 1 個しか受け取らないサーバー関数に対して、余計な引数を 3 個も送りつけていたのです。そのため通信が不正となり、Google 側で弾かれていました。
しかし、もうひとつの「ゾンビ復活バグ」はこれだけでは説明がつきません。ブラウザの内部ストレージ(IndexedDB)の中で何かが起きています。
「ブラウザを開かずに、ブラウザの中身をどうやってテストするのか?」
そこで今回、ガスマネージャーに新たに組み込んだ秘密兵器が verify-ui(フロントエンド実機シミュレーション) です。
Node.js の vm 環境上に、インメモリの仮想 IndexedDB、模擬 DOM、そして google.script.run のスパイ機構を丸ごと構築。HTML ファイル内の JavaScript をヘッドレスで実際に動かし、「保存 → 削除 → 再読込」のライフサイクルを機械的に走らせる道具です。
これでテストを撃ち込んだ瞬間、犯人が完全に割れました。
// 以前の壊れたコード
async function saveToDB(items) {
const db = await openDB();
const tx = db.transaction('store', 'readwrite');
items.forEach(i => tx.objectStore('store').put(i)); // ← 既存を clear() していなかった!
}
サーバー側でメールが削除されても、ローカルの IndexedDB に古いレコードが残りっぱなし(put 追記のみ) だったのです。そのため、画面の初期化時に IndexedDB から古いゴミデータを拾い上げ、ゾンビのように画面へ再描画していました。
原因が分かれば一撃です。store.clear() を挟んで綺麗に全消去してから保存するよう修正し、シミュレータで検証。
py gas.py verify-ui Mクイック Index --test-js "await saveToDB([{id:'1'},{id:'2'}]); await saveToDB([{id:'1'}]); const r = await loadFromDB(); if(r.length !== 1) throw new Error('zombie!'); return r.length;"
=== フロントエンド実機シミュレーション: [Mクイック] (Index) ===
判定: [SUCCESS]
test_result: 1(ゾンビ検出ゼロ)
ブラウザを一度も開くことなく、長年悩まされていたゾンビメールの息根を完全に止めることができました。
「0.5秒の連打」にも一切狂わず追従する快感
ゾンビを退治した勢いに乗り、長らく欲しかった機能を追加しました。
「メールを開いて読んでいるその詳細画面から、直接ゴミ箱にポイっと捨てたい」という機能です。
ヘッダーの「印刷」と「閉じる」の間に、上品な赤色のゴミ箱ボタン(🗑️)を新設。
クリックした瞬間にモーダルがサッと閉じ、一覧画面からも対象メールが 0 秒で消滅し、裏側でバックグラウンド通信が走るように配線しました。
ここで気になるのが、「画面上で削除と復活を素早く繰り返しても、実際の Gmail とリンクしているのか?」 という点です。
手元の画面がサクサク動いていても、裏側の Google サーバーが追いついていなければ意味がありません。実際にネットワークとサーバーの所要時間を計測してみました。
- ブラウザ 〜 Google サーバー間の往復通信: 約 0.15 〜 0.2 秒
- GAS の起動と Gmail への命令実行(
moveToTrash等): 約 0.2 〜 0.3 秒 - 1 回の処理が Gmail 側で確実に着地するまでの合計: 約 0.4 〜 0.6 秒
つまり、キリの良い数字で言えば 「0.5秒」。
人間が「削除」を押し、画面の変化を目で見て、カーソルを動かして「元に戻す」を押すまでには、どれだけ急いでも自然と 0.7〜1.0 秒ほどかかります。
通常の操作スピードであれば、0.5秒以内に同じメールを2度叩くことは人間工学的にあり得ません。
画面の見た目も、IndexedDB の保存庫も、本家 Gmail のサーバーも、一切のズレなく「0.5秒のテンポ」で完璧に同期して追従する怪物アプリ へと生まれ変わったのです。
もちろん、この修正の反映もブラウザゼロ。
batch_patch コマンド一発でサーバー側とHTML側を同時にアトミック更新し、わずか 1 秒台で Version 14、そして Version 15 へと本番再デプロイ を完了させました。
なぜAIがここまで自律完走できるのか? ―― 『からくりポケット』の全貌
ここまで読んでくださった方の中には、こう思われた方もいるかもしれません。
「いくらガスマネージャーがあるとはいえ、AIがそんなに複雑な修正をノーミスで完走できるものなのか?」と。
実は、この裏側にはもうひとつの強力な仕組みが動いていました。
私たちが 『からくりポケット(AI指示書ループ自律開発環境)』 と呼んでいる、モデル間リレーの型です。
[設計役(番頭 / 大型モデル)]
│
▼ 課題と厳格な合格条件を書いた指示書を作成
[queue/XXX_指示書.md]
│
▼ 作業役(フラッシュ君 / 高速モデル)が自律検知して実行
[ローカル実装・テスト・デプロイ]
│
├─ 全関所PASS ──► [queue/reports/XXX_report.md] を書き、待機シグナル (_idle.txt)
└─ 不合格 ──► [queue/reports/_stopped.txt] を書き、作業停止して設計役に報告
AIにチャットで「あれやって、これやって」と口頭で指示を出し続けると、文脈が肥大化してすぐに知能が落ちたり、途中で勝手に妥協して「動くはずです」と嘘の報告をしてきたりします。
それを防ぐため、役割を完全に二分しました。
-
設計役(番頭):
大局的なアーキテクチャ設計と、厳しい「合格の条件(関所)」を記載した指示書をqueue/フォルダに置く。 -
作業役(フラッシュ君):
指示書を読み、コードをピンポイントで修正し、実機テスト(diagnoseやverify-ui)を上から1行ずつ指差し確認する。合格条件が 1 つでも通らなければ次の作業へ進めず、作業を止める。
この「関所テスト」を設けることで、AIの嘘や手抜き、推測報告を物理的にゼロに封じ込め、人間が寝ている間でも自律的に 100 点満点までループを回し切ることができるのです。
GitHubに「AIが自律ループで回す箱」ごと同梱して公開しました
この『Mクイック』の劇的改善を経て磨き上がった最新機能、そして開発を支えた『からくりポケット』の仕組みを、本日すべて GitHub に push 完了いたしました!
🔗 GitHub リポジトリ:
https://github.com/shu1551/shu-gas-manager
(最新コミット: e862bb9 / pytest 85 passed 全勝パス)
今回追加された目玉は以下の通りです。
1. フロントエンド実機シミュレーション verify-ui
ブラウザを開かず、Node.js 上で IndexedDB や DOM のライフサイクルを自動検証できるコマンドです。
py gas.py verify-ui <プロジェクト名> Index --test-js "/* ここに検証コード */"
2. 誤爆ゼロの深層健康診断(diagnose)
動的ブラケット呼び出し(google.script.run[gasMethod]())の引数不一致検知、未使用の引数検知、ループ内重いAPI警告などを拡充。現場のコードに合わせて徹底的に誤爆を排除し、本当に直すべき問題だけを正確に指摘します。
3. からくりポケット(queue/ フォルダ)の公式同梱
ダウンロードしてすぐに、皆様の開発環境でも「指示書ループ」を立ち上げられるよう、ピカピカの空の箱とルール文書をリポジトリに含めました。
-
queue/README.md: 自律開発ループのルールと行動規範 -
queue/001_sample_テンプレート指示書.md: すぐに真似して書ける指示書の型 -
queue/reports/: 完了報告書が入る空のポケット
個人情報や過去の泥臭いテストデータは一切含まず、完全にクリーンなテンプレートとしてパッケージ化してあります。
おわりに
「clasp の認証ファイルを直接叩いたら速かった」という小さな実験から始まった『秀GASマネージャー』は、
わずか数日のうちに、ブラウザ不要の実機シミュレーションを備え、AI同士が自律ループで品質を高め合う総合開発基盤 へと進化を遂げました。
現場で実際に使っている Web アプリの泥臭いバグを真正面から叩き潰したからこそ、机上の空論ではない「本当に使える道具」になったと確信しています。
GAS のブラウザ往復やデプロイ待ちに疲弊している方は、ぜひ手元にクローンして、この「1秒台で世界が変わる体験」を味わってみてください。
最後までお読みいただき、ありがとうございました!




