任意のコマンドの状況をHerdrのagents欄に表示するためのコマンドラッパー

#juneboku > topics > 任意のコマンドの状況をHerdrのagents欄に表示するためのコマンドラッパー
created: 2026-08-17 / updated: 2026-08-17
juneboku Claude Code
Written by juneboku with assistance from Claude Code.

ターミナル・マルチプレクサとしてHerdrを使っている。複数のCoding Agentを並行で走らせていても、agents欄を見れば「誰がworkingで、誰がidleで、誰がblockedか」が一覧できる。これがとても快適。

快適になってくると、欲が出てくる。エージェント以外の動き、たとえば「デプロイ進行中」みたいな状態も、同じように把握したくなってきた。デプロイってけっこう時間がかかるので、走らせている間は別の作業をしていて、完了したことに気づかない…ということがよくある。完了したら知りたいですよね。


Herdrに最初から生えていた口

調べてみたら、Herdrにそのものずばりの口があった。

herdr pane report-agent <pane_id> --source ID --agent LABEL --state idle|working|blocked|unknown [--custom-status TEXT] [--seq N]

任意のpaneについて「このpaneでは LABEL というエージェントが、いまこういう状態です」と外部から報告できるAPIだ。--agent のラベルは自由な文字列なので、ここに「jbt deploy」と書けば、デプロイ作業がagents欄に並ぶことになる。

ちなみにこれは裏口ではない。Claude Codeの公式Herdr連携も、フックから同じ系統の公開API (pane.report_agent_session) を叩いて状態を報告している。つまり外部プロセスが状態を報告するための正面玄関で、うちのデプロイもそこから堂々と入場すればいい。「デプロイを任されたエージェント」と広義に捉えれば、意味論的にもまあ通るでしょう。

つくったもの: hw

というわけで、コマンドラッパー hw (Herdr Watch) をつくった。使い方はこう。

hw <ラベル> -- <コマンド...>
$ hw "jbt deploy" -- kamal deploy
$ hw "CI #123" -- gh run watch 123

第1引数がagents欄に表示される名前になって、-- より後ろが実際に実行されるコマンド。実行中はagents欄に「working / 実行中」と出て、成功すれば「done / ✅ (経過時間)」、失敗すれば「blocked / ❌ exit=N」に変わる。完了時にはトースト通知と音も出る。

CIのような手元で走らないタスクも、gh run watch みたいな「見張り役コマンド」を包めば同じ枠に乗るのがポイント。

スクリプト全文

bash + jq で70行ほど。~/.dotfiles/bin/hw に置いてある。

#!/bin/bash
# hw (Herdr Watch) — 長時間コマンドをHerdrのagent listに「擬似エージェント」として映すwrapper
#
# Usage: hw <ラベル> -- <コマンド...>
#   例: hw "jbt deploy" -- kamal deploy
#       hw "CI #123" -- gh run watch 123
#
# 実行中は state=working、成功で done (✅ + 経過時間)、失敗で blocked (❌ + exit code)。
# 完了/失敗時は herdr notification でトーストも出す (config.tomlのui.toast有効時)。
set -u

usage() {
  echo "usage: hw <label> -- <command...>" >&2
  exit 2
}

[ $# -ge 3 ] || usage
label="$1"
shift
[ "$1" = "--" ] || usage
shift
[ $# -ge 1 ] || usage

pane_id=$(herdr pane current 2>/dev/null | jq -r '.result.pane.pane_id // empty')
if [ -z "$pane_id" ]; then
  echo "hw: Herdrのpaneを特定できへんかったので、そのまま実行します" >&2
  exec "$@"
fi

source_id="hwatch-$$"
seq=0

report() { # report <state> <custom-status>
  seq=$((seq + 1))
  herdr pane report-agent "$pane_id" \
    --source "$source_id" --agent "$label" \
    --state "$1" --custom-status "$2" --seq "$seq" >/dev/null 2>&1
}

elapsed() {
  local s=$(($(date +%s) - start))
  if [ "$s" -ge 60 ]; then
    echo "$((s / 60))m$((s % 60))s"
  else
    echo "${s}s"
  fi
}

on_interrupt() {
  report blocked "⚠ 中断 ($(elapsed))"
  exit 130
}
trap on_interrupt INT TERM

start=$(date +%s)
report working "実行中"

"$@"
status=$?
trap - INT TERM

if [ "$status" -eq 0 ]; then
  report idle "✅ $(elapsed)"
  herdr notification show "$label 完了" --body "$(elapsed) で完了" --sound done >/dev/null 2>&1
else
  report blocked "❌ exit=$status $(elapsed)"
  herdr notification show "$label 失敗" --body "exit=$status ($(elapsed))" --sound request >/dev/null 2>&1
fi

exit "$status"

トーストはHerdrのデフォルト設定では無効なので、~/.config/herdr/config.toml に設定を足す必要がある。

[ui.toast]
delivery = "herdr"

使ってみて副次的に気づいたこと

さっそく使ってみて、想定していなかったうれしさがあった。ラベルが「コマンドへのコメント」として機能する。

デプロイコマンドって、複数のプロジェクトで npm run deploy みたいに共通だったりする。素で実行しているとシェル履歴上はどれも同じ文字列で、履歴検索から「あのプロジェクトのデプロイ」を引き当てられない。それが hw "○○ deploy" -- npm run deploy と打つ習慣になると、プロジェクト名で履歴検索してそのまま実行できる。コマンドに意図の注釈が付いて、それが検索キーになる。

もうひとつ、herdr wait agent-status <pane_id> --status done というコマンドを使うと「デプロイの完了を待ってから次をやる」というのもできる。エージェントに「隣のpaneのデプロイが終わったら確認して」と頼む、みたいな連携もできるっぽい。

おまけ

これやりたい
https://jnbk.app/topics/任意のコマンドの状況をHerdrのagents欄に表示するためのコマンドラッパー.md

をお手元のエージェントに投げつけてもらえたら導入できると思います。

Mentioned in days

In 2026-08-17 Mon Read full day →

任意のコマンドの状況をHerdrのagents欄に表示するためのコマンドラッパーのページをつくった。

このページを公開するに当たり、日記ページとトピックページのURLの末尾に .md をつけてアクセスしたらもとのMarkdownにアクセスできるようにした。エージェント用にね。

Archives : 2,609 days