iTerm2 + tmuxからHerdr + Ghosttyに移行した

モチベーション
コーディングエージェントの台頭によって、普段の開発業務がリポジトリやブランチを行き来しながら複数のClaude Codeに指示を出し続けるお仕事になってしまった。
そうするとtmuxのどのタブでどのエージェントがどういう状態なのか、を把握するのが難しくなってしまったため、評判の良いHerdrを導入することにした。
Herdr ドキュメント
AI コーディングエージェントのためのターミナルワークスペースマネージャー。

また、ついでにターミナルエミュレーターもGhosttyに乗り換えることにした。
Ghostty
Ghostty is a fast, feature-rich, and cross-platform terminal emulator that uses platform-native UI and GPU acceleration.

自分好みの使い勝手にするまでに少々設定が必要だったので、メモ。
Ghosttyは必要最低限の設定しかしていないため、Herdrの設定についてがメイン。
記事執筆時点でのherdrのバージョンは0.8.0、Ghosttyは1.3.1。
インストール
どちらもHomebrewでインストールできる。
$ brew install herdr
$ brew install --cask ghostty
設定を始める前に
エージェントスキルファイル | herdr
に書かれているが、Herdrはエージェント向けのスキルファイル skills/herdr/SKILL.mdに加え、
人間が Herdr を学習・セットアップ・トラブルシューティングするのをエージェントが手伝うための
ガイドも提供している。
そのため、一番初めにこのファイルをエージェントに渡して、「Herdrをセットアップしたいんだけどやり方教えて」みたいにするとスムーズ。
Herdrの基本概念
ref. コンセプト | herdr
| 階層 | 内容 |
|---|---|
| Session | herdrサーバーの名前空間(基本1つで運用) |
| Workspace | プロジェクト単位のコンテナ |
| Tab | Workspace内の画面(agents/logs/serverなど。Chromeのタブ相当) |
| Pane | Tab内の分割ターミナル |
| Agent | Pane内のプロセス(Claude Codeなど) |
Workspace > Tab > Paneという階層構造。Sessionは基本意識することがない。
Workspaceについては
リポジトリ、タスク、調査ごとにひとつのワークスペースを使ってください。
と記載があるので、複数タスク並列で回すときは基本Workspaceをばんばん立ち上げる運用になりそう。
またPaneは自分はあまり使わなそう。
設定
ここから実際に行った設定をいくつか。
HerdrのTabの作成/移動/削除をChromeのタブみたく操作したい
iTerm2 + tmuxのときもやっていたのだが、タブはcmd+tでシュッと立ち上げたいし、タブ間の移動はcmd+shift+[ or ]で行いたい。
そのために、まずHerdr側の設定では
# ~/.config/herdr/config.toml
[keys]
new_tab = "cmd+t"
next_tab = "cmd+shift+]"
previous_tab = "cmd+shift+["
close_tab = ["prefix+shift+x", "cmd+w"]
を割り当てる。次にGhostty側ではこれらのキーバインドを無効化しておく。
# ~/.config/ghostty/config.ghostty
keybind = super+t=unbind
keybind = super+shift+[=unbind
keybind = super+shift+]=unbind
keybind = super+w=unbind
workspace navi内でj/kでworkspaceを選択したい
prefix+wで左上のworkspace一覧にフォーカスがあたるが、このときj/kでカーソルを上下に移動してworkspaceを選びたい。
[keys]
navigate_workspace_up = "k"
navigate_workspace_down = "j"
agentsにClaude Codeのセッション名を表示したい
Claude Code使ってるとき、こまめに/renameでセッション名をつけるようにしてるので
agents一覧の2行目のところに出したい。

調べてみると、ここはui.sidebar.agentsという項目でカスタマイズできるらしい。
https://herdr.dev/docs/configuration/#sidebar-row-layouts
[ui.sidebar.agents]
row_gap = 0
rows = [
["state_icon", "workspace", "tab"],
[{ token = "terminal_title_stripped", fg = "#89b4fa", dim = false }],
]
このように、表示したい項目(トークン)を行ごとに並べてrowsに配列で指定する。
また、Claude Codeのセッション名はterminal_title_strippedで取れた。
agentsもworkspace naviみたく選択したい → できなさそう😢
workspaceはprefix+wでフォーカスがあたるのだから、agentsも同じことやりたい。
と思ったがこれはできないらしい。
しかたないので、prefix+j/kで前/次のagentを開くようにした。
iTerm2のようなHotkeyを割り当てたい
元々使っていたiTerm2にはHotkeyを設定することができ、Ctrl+;で表示非表示を頻繁に切り替えて使っていた。
これはGhostty、Herdrいずれも標準機能では無理だった。
そこで、こちらの記事を参考にRaycastで設定した。
iTerm2 から Ghostty に乗り換える
世間では Ghostty が賑わいを見せています。 ミーハーな僕もこのビッグウェーブに乗って iTerm2 から Ghostty に乗り換えることにしました。 今回はその記録です。 Ghostty Zig で書か

tmuxのコピーモードをherdrでもやりたい
あります。キーバインドもtmuxと同じでprefix+[です。
Keyboard
What the prefix is, which bindings to learn first, and how to go prefix-free.

使ってみた感想
1週間ぐらい使ってみたが、たしかに世間の評判通り便利。
- エージェントの一覧が状態とともに常にサイドバーに表示されるのは良い
- マウスでの操作(
ui.mouse_capture)いらないかなと思ったけど、実際あるとちょっとした切り替えはマウスで済ませられて便利 - エージェントがこちらの入力待ちで止まったときに通知や音で気付ける
- 一方、ただ完了してidle状態になったときに通知を出す方法はわからず…
未解決なこととしてはカラーテーマぐらいかな。標準で用意されてるテーマはどれもいまひとつだった。
完成したconfig
Herdr
onboarding = false
[ui.toast]
delivery = "terminal"
[experimental]
switch_ascii_input_source_in_prefix = true
[ui]
agent_panel_sort = "spaces"
show_agent_labels_on_pane_borders = true
[ui.sidebar.agents]
row_gap = 0
rows = [
["state_icon", "workspace", "tab"],
[{ token = "terminal_title_stripped", fg = "#89b4fa", dim = false }],
]
[ui.sidebar.spaces]
row_gap = 1
[theme]
name = "terminal"
auto_switch = false
[keys]
prefix = "ctrl+t"
# --- Workspace層(プロジェクト単位) ---
previous_workspace = "prefix+shift+["
next_workspace = "prefix+shift+]"
switch_workspace = "prefix+shift+1..9"
# --- Tab層(Workspace内の画面。Chromeのタブ相当) ---
new_tab = "cmd+t"
next_tab = "cmd+shift+]"
previous_tab = "cmd+shift+["
close_tab = ["prefix+shift+x", "cmd+w"]
# --- Pane層(Tab内の分割ターミナル) ---
# 方向移動(focus_pane_left/down/up/right)はh/j/lをレイヤー横断ジャンプに
# 明け渡すため廃止。pane間移動はcycle_pane_next/previousとlast_paneで代替。
cycle_pane_next = "prefix+tab"
cycle_pane_previous = "prefix+shift+tab"
last_pane = ["prefix+;", "prefix+l"]
# --- Agent層(サイドバーのプロセス一覧) ---
previous_agent = "prefix+k"
next_agent = "prefix+j"
focus_agent = "prefix+alt+1..9"
# --- Navigate mode内の移動(prefix+wで入るワークスペース選択面) ---
# j/kでworkspace選択を上下に動かす。衝突するnavigate_pane_down/upは外し、
# pane方向ジャンプはh/lの左右のみ残す。
navigate_workspace_up = "k"
navigate_workspace_down = "j"
navigate_pane_left = "h"
navigate_pane_right = "l"Ghostty
# herdrへタブ操作系のキーを素通しするため、Ghostty標準のタブ切り替えを解除
# unbind: バインドを削除し、印字可能なキーは子プロセス(herdr)まで送信されるようになる
keybind = super+t=unbind
keybind = super+shift+[=unbind
keybind = super+shift+]=unbind
keybind = super+w=unbind
# リガチャを無効化
font-feature = "-calt"
font-feature = "-dlig"
font-feature = "-liga"
window-padding-x = 20
window-padding-y = 50
window-padding-balance = trueおわりに
過去のブログ記事を遡ると、2014年にはすでにiTerm2+tmuxという構成だったみたいなので、10年以上使い続けていた環境からの乗り換えだったらしい。感慨深い(そうでもない)。
[tmux][iTerm]ショートカットキーでタブ(ウィンドウ)切り替え - dackdive's blog
職場のPCもプライベートのPCもmacなんですが、 ターミナル環境としてiTerm2とtmuxを使ってます。 一般的にそうなのかわかりませんが、 Cmd+tでiTermにより新規タブを作成した時 タブ同士がなぜか同じウィンドウを指しているようで、 タブで複数の環境を立ち上げておくことができませんでした。

参考リンク
公式ドキュメント
- Herdrコンフィグリファレンス:https://herdr.dev/docs/config-reference/
- Ghosttyオプションリファレンス:https://ghostty.org/docs/config/reference
参考にしたブログ記事
zaki-yama's blog