ターミナルを中心とした作業環境 第2回 herdrで作るエージェントベースのターミナル環境
複数のAIエージェントを同時に動かす時代のターミナルワークスペースマネージャー「herdr」を紹介します。tmuxとの違い、マウス中心の操作、エージェントの状態表示と完了通知、セッションの自動復元、カスタムコマンドやプラグインによる拡張までを解説します。
はじめに
Claude CodeやCodex CLI、GitHub Copilot CLIなど、CLIで動くAIエージェントを使うようになると、大きなタスクを投げてから完了までの待ち時間を使って、別のプロジェクトも並行で進めたくなってきます。
そうして複数のエージェントを同時に走らせるようになると、「あのエージェントは今どうなっているんだろう?」「承認待ちで止まっていないか?」といった管理の問題が出てきます。前回は、tmuxのセッションで作業をまとめ、監視ツール(tmuxcc)でエージェントの状態を見張り、セッション管理ツール(sesh)で行き先を選ぶ、という形で少しずつ環境を育てていく方法を紹介しました。
herdrとは
herdrは、2026年3月頃に登場したツールです。公式には「ターミナルワークスペースマネージャー」と称していますが、1つのターミナルの中で複数の作業画面を扱うという役目は第1回で紹介したtmuxと同じなので、本記事ではマルチプレクサとして扱います。
記事執筆時点(2026年8月)のバージョンはv0.8.0で、まだv1.0には達していません。登場から日が浅いプロジェクトですが、短期間でバージョンアップを重ねています。
技術的な特徴としては、次のような点が挙げられます。
- Rust製の単一バイナリのCLIツール(Electronベースのデスクトップアプリではない)
- セッションを永続化するため、切断しても作業が残る
- SSH経由でリモートからアタッチできる。画面の幅が狭いときは1列のレイアウトに切り替わるため、スマートフォンやタブレットからも操作できる
- マウス中心の操作に対応している。tmuxライクなプレフィックスキー操作も併用できる
- Claude Code、Codex、OpenCodeなど主要なコーディングエージェントに対応している
tmuxとの違い
「セッションの永続化やリモートからのアタッチなら、tmuxでもできるのでは?」と思った方もいるでしょう。1つのターミナルの中で画面を分割し、切断してもセッションが残り、あとから再接続できる、といった機能はtmuxをはじめとする既存のマルチプレクサでも実現できます。
herdrが他のマルチプレクサと決定的に違うのは、エージェントを動かすことが前提になっている点です。tmuxにとって各ペインは「ただの端末」ですが、herdrは各ペインでどのエージェントが動いているかを追跡し、その状態(作業中なのか、承認待ちで止まっているのか、完了したのか)を認識します。そして、その状態をタブやワークスペース単位に集約して見せ、必要なら通知まで出してくれます。
つまり、「マルチプレクサで画面を分割し、別の監視ツールでエージェントの状態を見張る」という組み合わせで実現していたことが、herdrでは1つのツールにまとまっています。
インストール
macOS/Linuxでは、公式のインストールスクリプトを実行するのが手軽です。
インストールスクリプトでの導入
curl -fsSL https://herdr.dev/install.sh | sh
Homebrewやmiseを使っている場合は、次のようにも導入できます。
Homebrew/miseでの導入
brew install herdr
# または
mise use -g herdr
インストール後、herdrコマンドを実行すると起動します。初回起動時にはオンボーディングが表示され、通知の設定や、後述のエージェントインテグレーションの導入をその場で済ませられます。
画面の構成
herdrを起動すると、1つのワークスペースに1つのタブがあり、その中に1つのペイン(シェル)がある状態で立ち上がります。
herdrの画面は、次の3つの階層で構成されています。
- ペイン: シェルやエージェントが動く、いちばん小さい単位
- タブ: 複数のペインをまとめたレイアウトの単位
- ワークスペース: タブをまとめる最上位の単位。プロジェクトごとに分けておくと、サイドバーで横断的に見渡せる
エージェントを動かすのにも、特別な操作は要りません。ペインを分割し、目的のプロジェクトのディレクトリでclaudeやcodexなどをいつもどおり起動するだけです。主要なエージェントは自動で検出されるため、起動した時点でその状態がサイドバーに表示されます。
ペインの名前が境界に表示されるため、「実装」「レビュー」のように名前を付ければ、見分けがつくようになります。ペインの名前をサイドバーにも表示したい場合は、設定ファイルconfig.tomlを以下のように修正します。
サイドバーにペインの名前を表示する
[ui.sidebar.agents]
rows = [
["state_icon", "workspace", "tab"],
["agent", "pane"],
]
メニューと設定画面を開く
メニューもサイドバーにあります。そこから設定画面の表示、キーバインドの一覧の表示、設定の再読み込み、リリースノートの確認、アップデートの適用、デタッチといった操作ができます。設定画面はテーマ、通知の有無、エージェントインテグレーションの導入などをタブで切り替えて選べるようになっていて、設定ファイルを開かずにマウスだけで変更できます。細かくカスタマイズしたくなったら、config.tomlを更新してください。
マウスで操作する
herdrはターミナルのツールとしては珍しく、ペインの分割からワークスペースの作成、設定の変更まで、日常的な操作はほとんどマウスだけで完結します。tmuxでもマウス操作は有効にできますが、herdrはデフォルトでマウスを前提としたUIになっている点が違います。
マウス操作は触ってみて覚えるのが一般的ですが、あらかじめ知っておくと便利な使い方を紹介します。
ワークスペースとworktreeを操作する
サイドバーに並んだワークスペースを右クリックすると、コンテキストメニューが開きます。
注目したいのはNew worktreeです。ブランチ名を入力すると、herdrがGitのworktreeを作り、それを新しいワークスペースとして開いてくれます。作られたworktreeは、元のリポジトリのワークスペースと同じグループにまとめられるので、どれがどのリポジトリの派生なのかがわかります。用が済んだらDelete worktree checkout...から後片付けもできます。
なお、herdrがworktreeを作る場所は設定で変えられます。デフォルトは~/.herdr/worktreesです。
worktreeの作成先を変える
[worktrees]
directory = "~/Projects/worktrees"
New worktreeが役に立つのは、エージェントを複数動かす場面です。同じリポジトリで2つのエージェントに別々の作業をさせると、お互いの変更がぶつかってしまいます。worktreeを用意しておけば作業ディレクトリごと別になるため、並行して走らせても干渉しません。「別のブランチで作業させたい」と思ったときに、ターミナルを移動してコマンドを打つ必要がないわけです。
補足:Gitのworktree
git worktreeは、1つのリポジトリに作業ディレクトリを複数作れるGitの機能です。リポジトリをgit cloneし直すのと違って履歴は共有されるため、ディスクの消費も少なく済みます。「mainでの作業を止めずに、別ブランチの修正も同時に進めたい」といったときにも使います。
worktreeを使った並列開発については、git worktreeとpnpmで作る並列開発環境 | AI時代におさえておきたい開発セットアップも併せて参照してください。
キーボードで操作する
herdrはtmuxと同じプレフィックスキー方式(デフォルトはctrl+b)を採用しています。プレフィックスキーに続けてキーを押すと、対応する操作が実行されます。覚えられなくても、prefix+?を押せば有効なキーバインドの一覧が出ます。
マウスだけでも操作できますが、慣れてくるとキーボードのほうが速い場面も出てきます。
エージェントインテグレーション
ここからは、herdrの最大の特徴であるエージェントインテグレーションを見ていきます。
エージェントの状態とサイドバー
herdrは、各ペインで動いているエージェントの状態を、次の5つに分類します。
| 状態 | 意味 |
|---|---|
blocked |
入力・承認・判断を待っている |
working |
実際に作業している |
done |
作業が終わり、まだこちらが見ていない |
idle |
終わっている、または待機中で、すでに確認済み |
unknown |
herdrが状態を判断しきれない |
これらの状態は、画面左のサイドバーに集約して表示されます。しかも、状態は階層的に伝播します。たとえばあるペインのエージェントがblockedになると、そのペインが属するタブ、さらにワークスペースまで「ブロックあり」として表示されます。
そのため、承認待ちで止まっているエージェントを、サイドバーを見るだけで見つけられます。同様に、workingのエージェントがいるワークスペースは稼働中として示され、doneになったエージェントはこちらが確認するまで表示に残ります。
主要なエージェントの検出は、何も設定しなくても動きます。そのうえで、エージェントごとのインテグレーションを導入すると、状態の判定がより確実になり、後述の自動resumeも使えるようになります。たとえばClaude Codeのインテグレーションは次のように導入します。
Claude Codeのインテグレーションを導入
herdr integration install claude
導入済みのインテグレーションの状態は、次のコマンドで確認できます。
インテグレーションの状態を確認
herdr integration status
エージェントが「作業を始めた」「終わった」といったイベントをherdrへ知らせる仕組み(フック)を持っている場合、herdrはそれを使って状態を判定します。持っていない場合は、画面の出力パターンから状態を推測します。そのため、フックに対応していないエージェントでも、ある程度の状態把握ができます。
エージェントの完了を通知で受け取る
herdrの画面を表示していなくても、バックグラウンドのワークスペースでエージェントが完了したときと入力を待ち始めたときに、通知を出す設定もあります。
通知の出し方は[ui.toast]セクションで指定します。
通知の設定
[ui.toast]
delivery = "system"
delay_seconds = 3
[ui.toast.herdr]
position = "bottom-right"
deliveryには次の4つを指定できます。
| 値 | 挙動 |
|---|---|
off |
ポップアップを出さない(デフォルト) |
herdr |
herdrの画面内にトーストを表示する |
terminal |
外側のターミナルにデスクトップ通知を依頼する。SSH越しでも手元のマシンに通知が出る |
system |
OSの通知サービスを直接呼ぶ(macOSはterminal-notifierかosascript、Linuxはnotify-send) |
herdrの画面を見ているときはherdr、ほかのアプリに移っているときはsystemが向いています。リモートのサーバーにSSHでアタッチして使っている場合は、terminalを選ぶと手元のマシン側に通知が出ます。
delay_secondsは、通知を送る前に待つ秒数です。待っているあいだに状態が変わった場合、herdrは通知しません。エージェントが一瞬だけ止まってすぐ次の処理に移るようなケースで、通知が次々と出てしまうのを防げます。指定できるのは0から3600で、デフォルトは1です。
なお、通知はタブ単位で抑制されます。今まさに開いているタブについては通知が出ないので、「見ているものについて通知される」という煩わしさはありません。
通知は音でも受け取れます。完了(done)と入力待ち(request)で別の音を割り当てられ、エージェントごとに鳴らす/鳴らさないを決められます。
通知音の設定
[ui.sound]
enabled = true
done_path = "sounds/done.mp3" # 完了時の音
request_path = "sounds/request.mp3" # 入力待ちの音
[ui.sound.agents]
claude = "on"
codex = "off"
音のファイルは.mp3で、相対パスはconfig.tomlのあるディレクトリを基準に解決されます。
そして、通知を受け取ったあとの動線も用意されています。herdrの画面内に出たトーストをクリックすると、その通知の発生元のペインへフォーカスが移り、トーストは消えます。キーボードならprefix+oが同じ役割です。「通知が来る → クリック、またはprefix+o → その場で続きを指示する」という流れが、サイドバーを目で探さずに実現できるわけです。
自分のスクリプトから通知を出す
通知の仕組みは、エージェント専用ではありません。herdr notification showコマンドを使えば、任意のスクリプトから同じ通知を出せます。
自分で通知を出す
herdr notification show "ビルド完了" --body "npm run build が成功しました" --sound done
--soundにはnone/done/requestを指定できます。長いテストやデプロイの終わりに鳴らす、といった使い方ができます。同じ処理はソケットAPIのnotification.showとしても呼び出せます。
セッションの自動復元(自動resume)
複数のエージェントを走らせているなら、「マシンを再起動したら、動いていたエージェントとの会話が全部消えてしまった」という事態は避けたいところです。herdrは、対応するエージェントのセッションを自動的に復元(resume)する機能をもっています。
herdrのセッション復元は、大きく次の3つの層で考えると理解しやすいです。
- ライブ永続:
prefix+qを押して通常どおりデタッチした場合、herdrのサーバーは動き続けます。ペインもプロセスもそのまま生き続けるため、再アタッチすればまったく同じ状態から作業を再開できます。もっとも強力な永続化の方法です。 - スナップショット復元: サーバー自体を再起動した場合、herdrはワークスペース・タブ・ペイン・作業ディレクトリ(
cwd)・レイアウト・フォーカスといった「構造」を復元します。ただし、動いていたプロセスそのものは復元されません。 - 画面履歴のリプレイ: サーバーの完全な再起動後にペインの画面内容まで復元する機能もありますが、これはトークンやシークレットが画面に残っている可能性があるため、デフォルトでは無効です。
[experimental]セクションでpane_history = trueとすると有効化できます。
そして、エージェントに関して特に便利なのが自動resumeです。対応するエージェントは、エージェント自身がもつセッションID(会話を識別するID)を保持しており、herdrはそれを使って会話セッションそのものを復元します。この機能はデフォルトで有効です。クライアントがアタッチしたタイミングで、フォーカスされていないペインも含めて自動で再開されます。
自動resumeは多くのエージェントに対応しています。主なものと、内部で使われるコマンドは次のとおりです。
- Claude Code:
claude --resume <id> - Codex:
codex resume <id> - GitHub Copilot CLI:
copilot --resume=<id>
なお、自動resumeを使うには、herdr側のインテグレーションが一定のバージョン以上である必要があります。エージェント本体のバージョンではないので注意してください。導入済みのバージョンはherdr integration statusで確認できます。必要なバージョンと、対応するエージェントの一覧は公式ドキュメントにあります。
この挙動を無効にしたい場合は、設定ファイルの[session]セクションで次のように指定します。
自動resumeを無効にする設定
[session]
resume_agents_on_restore = false
設定ファイルとキーバインド
ここまで断片的に出てきた設定は、すべて同じconfig.tomlにまとめて書きます。場所は次のとおりです。
- macOS/Linux:
~/.config/herdr/config.toml - Windows:
%APPDATA%\herdr\config.toml
キーバインドは[keys]セクションで上書きできます。
キーバインドをカスタマイズする
[keys]
prefix = "ctrl+a" # プレフィックスキーをctrl+aに変更
new_tab = "ctrl+alt+n" # プレフィックスなしのダイレクトなショートカットにする
キーの書き方は2つあり、両者は明確に区別されます。prefix+nのように書くと「プレフィックスキーを押してからn」という意味になり、上のctrl+alt+nのように書くとプレフィックスなしのダイレクトなショートカットになります。
ダイレクトなショートカットに使う修飾キーは、ctrl+altが無難です。ターミナルやデスクトップ環境に取られていないことが多く、公式ドキュメントでも推奨されています。ただしctrl+alt+t(Ubuntu・Fedoraの「ターミナルを起動」)のように、環境によっては奪われている組み合わせもあるため、公式ドキュメントの避けるべきキーの一覧を確認しておくとよいでしょう。
1つの操作に複数のショートカットを割り当てたい場合は、配列で指定します。
1つの操作に複数のキーを割り当てる
[keys]
next_tab = ["prefix+n", "ctrl+alt+]"]
設定を変更したら、次のコマンドで再読み込みできます。ほとんどのUI設定は、ペインを再起動しなくても反映されます。
設定を再読み込みする
herdr server reload-config
カスタムコマンドで一歩進んだ環境に
herdrがおもしろいのは、任意のコマンドをキーに割り当てられるカスタムコマンドがあるところです。これを使うと、よく使うツールをキー一発で呼び出せるようになります。
カスタムコマンドは[[keys.command]]という配列で定義し、typeで開き方を指定します。
type = "popup": 現在のレイアウトを変えずに、モーダルなポップアップウインドウで開く。一時的なツールを呼び出す用途に向くtype = "pane": 一時的なペインで開き、コマンド終了時に閉じる。既存のレイアウトへペインを足したい場合に使うtype = "shell": バックグラウンドでデタッチして実行する。開発サーバーのように起動しっぱなしのプロセスに使うtype = "plugin_action": プラグインが提供するアクションを呼び出す(後述の「プラグイン機能」を参照)
たとえば開発サーバーをバックグラウンドで起動する設定は、次のようになります。
開発サーバーをバックグラウンドで起動する設定
[[keys.command]]
key = "prefix+alt+s"
type = "shell"
command = "npm run dev"
description = "start dev server in background"
lazygitでエージェントの変更をレビューする
定番のlazygitを、ポップアップで開く例です。これはherdrの公式ドキュメントでも紹介されています。
lazygitをポップアップで開く設定
[[keys.command]]
key = "prefix+alt+g"
type = "popup"
command = "lazygit"
description = "run lazygit"
width = "80%"
height = "80%"
prefix+alt+gを押すと、画面の80%のサイズのポップアップでlazygitが開きます。ポップアップはコマンドが終了するまで、すべての入力を受け取ります。
これだけでも便利ですが、エージェントと組み合わせると次のようなワークフローになります。
- エージェントに実装を指示する
- 完了通知を受け取る、あるいはサイドバーで
doneになったことを確認する prefix+alt+gを押して、変更内容をポップアップでレビューする- 問題なければ次の指示へ進む
「エージェントに書かせる → herdrが知らせる → キー一発でレビューする」という流れが、ターミナルの中だけで完結します。エージェントに任せる作業が増えるほど、こうしたレビューへの動線の短さがものを言います。
スクラッチターミナルを開く
ちょっとしたコマンドを試したいときのために、一時的なシェルをポップアップで開く設定も便利です。これも公式ドキュメントで紹介されている例です。
スクラッチターミナルをポップアップで開く設定
[[keys.command]]
key = "prefix+t"
type = "popup"
command = "exec \"${SHELL:-sh}\""
description = "open scratch terminal"
width = "80%"
height = "80%"
なお、カスタムコマンドの中ではHERDR_ACTIVE_PANE_CWD(現在のペインの作業ディレクトリ)などの環境変数が使えます。これを利用すると、「今いるプロジェクトのディレクトリで何かを起動する」といった、文脈に応じたコマンドも組み立てられます。
プラグイン機能
カスタムコマンドは「自分の環境だけで使う設定」ですが、同じような拡張をほかの人と共有できるようにしたのがプラグインです。
公開されているプラグインはプラグインのマーケットプレイスから探せます。すでに多くのプラグインが公開されており、目的に近いものを探して導入できます。
プラグインの導入は次のコマンドです。GitHubのリポジトリをowner/repo形式で受け取り、クローンからビルド、登録まで済ませてくれます。実行前に何が走るかのプレビューが表示されます。
プラグインをインストールする
herdr plugin install owner/repo
導入したプラグインが提供するアクションは、前述のカスタムコマンドでtype = "plugin_action"を指定すると、自分のキーバインドから直接呼び出せます。
マーケットプレイスへの掲載は、公開リポジトリにGitHubのトピックherdr-pluginを付け、herdr-plugin.tomlを置くだけで済みます。公開する側のハードルは低いのですが、その裏返しとしてherdr側でのレビューは行われていません。導入するときは中身を確認し、自己責任で判断する必要があります。
おわりに
herdrの魅力は、エージェントの状態を知っているマルチプレクサだという一点にあります。ペインの中で何が動いているかをツール自身が把握しているので、状態の表示や完了通知、セッションの復元、レビューへの動線が別々の機能ではなく連動して働きます。複数のエージェントを同時に動かす開発スタイルには、そのまま合うはずです。
もちろん、herdrへ乗り換えることだけが答えではありません。tmuxに監視ツールを足して自分の手に合わせていく道もありますし、どちらを選ぶかは、環境そのものに手を入れる時間をどう使いたいかで変わります。
「複数のエージェントを動かすのが少し大変になってきたな」そう感じたときが、環境を見直すタイミングです。herdrのようなツールに乗り換えるのも、いま使っているものを育てるのも、どちらもその一手になります。開発の仕方が変わっていくのに合わせて、環境も少しずつ更新していきましょう。