Geminiこびと化計画
Gemini CLI + ttyd + tmux でGeminiをこびとにする

概要
退屈なことはPythonでもGemini CLIを使ってでもやりたくない
寝てる間に,ほんとに全部Gemini CLIにやってほしい
小人になってほしい
(いま思いつく) 結論
Gemini CLI + ttyd + tmux
経緯
Gemini CLIを使っていて思うこと
- リモートサーバで常時稼働していてほしい
- 壊しても,壊されてもよくて,すぐ作り直せる環境がいい
- 指示の与え方は簡単なほうがいい
- コンテキストを維持してほしい

この記事でDiscordからGemini CLIを呼び出せるようにしたものの,裏側ではメッセージをプロンプトとしてgeminiコマンドに対してパイプしているだけ.
一発の指示で理想がアウトプットされればなにも困らないが,それは対人間であっても叶わない.やはり対話したうえで細かい調整が必要になる.
前述の方法だと単発で実行しているのでコンテキストが維持されないのが悩みどころ.
さっき話した内容の続きから対話できるところが良さなのに,これだとあまり旨味がない.
かといって,Gemini CLIのようなインタラクティブなCLIツールに対してどうやって継続的に外部から入力するか.
オプションを見ても,前述したとおり単発でのプロンプトの入力はできるものの,上記の要件を満たせるようなものは見当たらない (20250720時点)
--prompt-interactive
オプションはそれっぽいと思い期待したが,初回の入力を渡せるだけで以降はインタラクティブモードになる.
理想はセッションIDみたいなものをオプションで渡して過去のコンテキストを引き継げることだが,無理そうなので代替案を考える
解決方法模索
まず,バックグランドで動いていてもらう方法と,壊してもよい環境の作り方.
これはdocker composeでコンテナとしてupしておけば問題なし.作り直しも容易
次の問題はプロンプトの入力方法.
一見execでよさそうだが,これはコンテナ内に新たにプロセスを生成するので,これだと単発実行と同義.
やるならattach.
ただ,リモートサーバにsshしてディレクトリ移動してdocker compose attachするまでが長い.しかもattachは油断してctrl-cするとコンテナは終了するし でまあ気にしないといけないことも多い (そもそもsshしてる時点で切れるかもなので微妙)
となると,Webからのアクセスがもっとも楽.MacからでもiPadからでもアクセスできて指示が出せればよさげ
ttydというのがいるのでありがたく使わせてもらう.ターミナルをWebとして配信することで,ブラウザからシェルが見えるようになるというもの.
https://github.com/tsl0922/ttyd (詳細はリンク先へ)
例えば ttyd bash
すればbashが見えるようになるので,ttyd gemini
すればよいと思ったが,ここでまた問題発生.
これはdocker compose execと同じようなもので,ブラウザからアクセスするたびに子プロセスとしてgemini
が起動する.つまり,ブラウザを閉じるとまた初めからとなる.
寝る前に指示を投げてからブラウザを閉じるとセッションが閉じてしまうのでこれだとNG
Webターミナルを自作することを試みるも,あまりに複雑で動作も安定しないので断念
普通にtmux噛ませばよくないか?とあとから思ってしまったので,それでやってみる
ここでもいろいろ試行錯誤はあったものの,以下の形とコマンドに落ち着いた
# こんなイメージ
# ttyd → tmux → $CMD
# $CMDははgeminiでもbashでもpythonでも何でもよい.インタラクティブなCLIツール)
ttyd -b $BASE_PATH --writable tmux new-session -A -s shared-session "$CMD"
shared-sessionというセッションがあればアタッチ,なければ作成して$CMDで渡された値を実行するというもの.
これにより,毎回ブラウザを開いても続きが見えるようになる.

これらをいい感じにコンテナイメージにまとめてローカル(docker compose)でもk8sでも動かせるようにした
Dockerfileにgemini-cliとtmuxとttydを入れるスクリプト,
entrypoint.shはBasic認証を入れるための環境変数のハンドリング,
それらをいい感じにまとめた docker-compose.yaml (とk8sデプロイサンプル)
というのが実装概要.
動作検証1
1回の指示から完了までが長い適当なプロンプトを流して,ブラウザを切っても裏で処理してくれるのか (寝ている間に作業してくれるか) 検証
google.comに対してpingを100して.コマンドがなければインストールして.

このあたりでページをそっと閉じて,あとはGeminiにお任せする
開き直してpingが100回通って完了していることが期待値.

よさげ
動作検証2
適当なHTMLを配信するサーバをPythonで書いてもらって,実際のポートを使ってアクセスできる状態にしてもらう.
ポートはあらかじめ適当にいくつか開けておいて,Geminiが自由に使えるようにしておく.
適当なディレクトリを切って,適当なHTMLを配信するWebサーバをPythonで書いて.ポートは8000番をつかって起動してアクセスできる状態にしてほしい

gemini-2.5-proの上限にあたったらしいので切り替えて続き
(ポートも8000じゃなくて7682にした)

放置

完了して動作確認もできたらしいので見てみる

よさげ
所感
とりあえずやりたいことはできた
これで普段の開発に耐えうるのかは不明