agent-shellとGhostelはエージェントを異なるプロトコル層でEmacsに統合する

agent-shellとGhostelは、どちらもEmacsからコーディングエージェントを使う画面になり得るが、同種の端末パッケージではない。agent-shellはエージェントとエディターの間のAgent Client Protocol(ACP)を解釈する専用クライアントであり、GhostelはPTYから届くバイト列をVT端末として解釈する汎用端末エミュレーターである。この違いによって、Emacsが操作の意味をどこまで認識できるかが決まる。

flowchart LR
  U[Emacsの利用者]
  U --> AS[agent-shellのバッファ]
  AS -->|ACPのJSON-RPC| AA[ACP対応エージェント]
  U --> GH[Ghostelのバッファ]
  GH -->|キーとVT画面| CLI[任意のCLIやTUI]

agent-shellが保持する意味

agent-shellはshell-makerを介してcomint系の対話バッファを作るが、エージェントの端末画面を再現しているわけではない。acp.elが標準入出力上のJSON-RPCを処理し、利用者の入力をsession/prompt要求として送り、エージェントからのメッセージ、思考、ツール呼び出し、権限要求を種類の異なるデータとして受け取る。comintは入力履歴とプロンプトを備えたEmacsらしい操作面を提供し、ACPはエージェント固有の意味を提供する。

この構成では、権限要求をボタンとして表示し、ツール呼び出しの状態を更新し、差分やMarkdownをそれぞれに適した表示へ変換できる。ファイルの読み書きをEmacs側で処理したり、エージェントが公開したモデル、セッションモード、推論強度を選択したりすることも、端末出力の文字列を推測せずに実装できる。

ただし、利用できる機能はエージェントまたは変換アダプターがACPで公開した範囲に限られる。CLIでは使えるスラッシュコマンドがACP経由では見えない場合もあり、ACPに対応しないエージェントはそのままでは接続できない。構造化された統合は、汎用端末としての互換性と引き換えに得られる。

Ghostelが保持する端末状態

GhostelはGhosttyと同じlibghostty-vtをZigで書かれた動的モジュールから利用する。動的モジュールがPTYの生成と読み取り、VT状態、キーの符号化、描画を担当し、Emacs Lispがキーマップ、バッファ、コマンド、遠隔プロセスとの統合を担当する。端末アプリから見ればGhostelは現代的な端末であり、24ビット色、Kittyのキーボードと画像プロトコル、ハイパーリンク、同期出力などを扱える。

この構成では、シェル、対話型CLI、全画面TUIをアプリ固有の対応なしに動かせる。コーディングエージェントのCLIも、そのエージェントがACPに対応しているかどうかに関係なく、端末アプリとして利用できる。一方、Ghostelが認識するのは端末の画面状態であり、表示中の文字列が権限要求なのか、ツール呼び出しなのか、通常の応答なのかは認識しない。権限承認も差分表示も、CLIが描いた画面とCLIへ送るキー入力のままである。

Ghostelは文字モード、準文字モード、行モード、Emacsモード、コピーモードを備え、キーを端末へ渡す状態とEmacsで編集や選択をする状態を切り替えられる。これは端末プロトコルを保ったままEmacsの操作性を加える設計であり、アプリの意味をEmacsへ移す設計ではない。

libvtermとemacs-libvtermの位置

libvtermはGhostelと競合するEmacsパッケージではなく、VT220、xterm、ECMA-48互換の端末状態を提供するCライブラリである。描画先を持たず、端末状態が変わると埋め込み側のコールバックを呼ぶ。Emacsでvtermと呼ばれることが多いemacs-libvtermは、libvtermを動的モジュールで包み、端末の画面セルをEmacsバッファへ反映する。

したがって、emacs-libvtermはagent-shellではなくGhostelと同じ層に属する。両者ともPTYの出力を端末状態へ変換するが、emacs-libvtermはC製のlibvterm、GhostelはZig製のlibghostty-vtを端末エンジンに使う。現在の各プロジェクト資料では、vtermはVT220とxtermを中心とする互換性を提供し、GhostelはKittyのキーボードと画像プロトコル、同期出力、五つの入力モードまで扱う。vtermはCMakeで動的モジュールを構築し、Ghostelは通常、配布済みの動的モジュールを初回に取得するという導入方法の違いもある。

選び分け

ACP対応エージェントをEmacsの編集操作、差分、権限管理、セッション管理と結びつけたい場合はagent-shellが合う。エージェント本来のCLIや全画面TUIをそのまま使いたい場合、ACPにない機能が必要な場合、あるいはエージェント以外の端末アプリも同じ画面で動かしたい場合はGhostelまたはvtermが合う。その二つは必要な端末プロトコル、入力モード、導入環境で選び分ける。

したがって、どれか一つをEmacsの「エージェント用端末」として選ぶ必要はない。agent-shellをエージェント専用クライアントとして使い、Ghostelまたはvtermを汎用端末として併用すれば、それぞれの抽象化が得意な範囲を保てる。

性能については、Ghostelの資料が独自の比較測定を掲載しているものの、ここでは再測定していない。設計上の選択はまず意味的統合と端末互換性のどちらが必要かで行い、性能は自分の出力特性と環境で測る必要がある。

https://github.com/xenodium/agent-shell

https://github.com/dakra/ghostel

https://github.com/akermu/emacs-libvterm

https://www.leonerd.org.uk/code/libvterm/

https://github.com/xenodium/shell-maker

https://agentclientprotocol.com/get-started/architecture

#emacs #terminal #coding-agent #acp