herdrのプラグイン機構
herdr本体はターミナルマルチプレクサとしての役割に絞られており、周辺機能はプラグインとして外に出す設計になっている。herdr-browserやherdr plusはいずれもこの機構の上に乗っている。
プラグインの実体は、herdr-plugin.tomlというマニフェストと、herdrが起動できるコマンドを置いたディレクトリ。herdrはそれを別プロセスとして起動するだけなので、Bash・JavaScript・Lua・Rust・PowerShellなど、マシンで実行できるものなら言語は問わない。
SDKが無い — CLIそのものがAPI
この機構の一番の特徴。専用のプラグインSDKは存在せず、
The entire Herdr CLI is the plugin API: every command in the CLI reference is available to a plugin, and anything you can run as
herdr ...yourself a plugin can run too.
という方針になっている。プラグインは環境変数HERDR_BIN_PATHが指すherdrバイナリを呼び戻すことでherdrを操作する。Unixドメインソケットと Windows の名前付きパイプの差をherdr側が吸収してくれるため、プラグインの移植性はCLI経由の方が高い。
ホスト側(herdr)が責任を持つのは、インストール・マニフェスト検証・キーバインド・ペイン・イベント・呼び出しコンテキスト・ソケットアクセスといった土台の部分。
マニフェストと拡張ポイント
id = "example.layout"
name = "Layout"
version = "0.1.0"
min_herdr_version = "0.7.0"
description = "Apply project layouts"
platforms = ["linux", "macos", "windows"]
[[build]]
command = ["npm", "ci"]
[[startup]]
command = ["node", "dist/restore.js"]
[[actions]]
id = "apply"
title = "Apply layout"
contexts = ["workspace"]
command = ["node", "dist/apply.js"]
[[events]]
on = "worktree.created"
command = ["herdr", "workspace", "list"]
[[panes]]
id = "board"
title = "Project board"
placement = "overlay"
command = ["herdr-board"]
[[link_handlers]]
id = "github-issue"
title = "Open GitHub issue"
pattern = "^https://github\\.com/[^/]+/[^/]+/(issues|pull)/[0-9]+$"
action = "apply"
必須フィールドはid / name / version / min_herdr_version。拡張ポイントは5種類。
[[startup]]— セッション復元後に一度だけ走る初期化フック。常駐サービスの供給ではない(監視・再起動はされない)[[actions]]— キーバインドやUIから呼べるコマンド。herdr plugin action invokeで叩ける。config側からはtype = "plugin_action"でキーに割り当てる[[events]]— herdrのイベントに反応するフック。on = "worktree.created"のように書く。herdr plusがworktree作成時にレイアウトを流し込んでいるのはこれ[[panes]]— ペインとして開くTUI。placementにoverlay/popup/split/tab/zoomedを指定できる[[link_handlers]]— ターミナル内のURLへの修飾クリックを正規表現でマッチさせ、アクションにルーティングする
[[build]]はインストール時に走るビルドコマンド。platformsで対象OSを絞れる。
文脈は環境変数で渡ってくる
プラグインのコマンドには、herdrから実行時の文脈が環境変数として注入される。
| 変数 | 内容 |
|---|---|
HERDR_BIN_PATH |
呼び戻すherdrバイナリ |
HERDR_SOCKET_PATH |
ソケットAPIのパス |
HERDR_ENV=1 |
herdr配下で動いている印 |
HERDR_PLUGIN_ID / HERDR_PLUGIN_ROOT |
自分のIDとチェックアウト先 |
HERDR_PLUGIN_CONFIG_DIR / HERDR_PLUGIN_STATE_DIR |
設定と状態の置き場 |
HERDR_PLUGIN_CONTEXT_JSON |
呼び出し文脈のJSON |
HERDR_WORKSPACE_ID / HERDR_TAB_ID / HERDR_PANE_ID |
取れる場合のみ |
ほかに、アクションにはHERDR_PLUGIN_ACTION_ID、イベントフックにはHERDR_PLUGIN_EVENTとHERDR_PLUGIN_EVENT_JSON、ペインにはHERDR_PLUGIN_ENTRYPOINT_IDが渡る。
下位レイヤとしてのソケットAPI
CLIの下には、稼働中のherdrを直接叩くソケットAPIがある。改行区切りJSON(ndjson)で1行1リクエスト、レスポンスは同じidを返す。
{"id":"req_1","method":"ping","params":{}}
{"id":"req_1","result":{"type":"pong"}}
トランスポートはUnixではドメインソケット、Windowsでは名前付きパイプ。デフォルトは~/.config/herdr/herdr.sockで、名前付きセッションは~/.config/herdr/sessions/<name>/herdr.sock。
ドキュメントは「ほとんどの自動化はCLIラッパーから始めるべきで、生のソケットAPIはリクエスト/レスポンスを直接制御したい場合や、長寿命のイベント購読が必要な場合にだけ使う」としている。さらに上のレイヤとして、エージェントにherdrの操作方法を教えるagent skillファイルがある。
インストールと開発
# GitHubから入れる。リポジトリに複数プラグインがあればサブディレクトリまで指定
herdr plugin install owner/repository
herdr plugin install owner/repository/subdir
# ローカル開発用。ビルドコマンドをスキップする
herdr plugin link /path/to/plugin
インストールはクローン → プレビュー表示 → ビルドコマンド実行 → 登録、という流れ。これらのCLIはherdrサーバーが起動していなくてもレジストリに書き込み、次回起動時に読み込まれる。
躓きやすい点。
- コマンドはargv配列で、シェル展開は行われない
- 自動更新の仕組みが無い。更新したければ入れ直す
- 認証情報はチェックアウト先ではなく
HERDR_PLUGIN_CONFIG_DIRに置く。GitHubからの再インストールでチェックアウトは置き換わるため
サンドボックスは無い
プラグインは自分の権限でそのまま動く普通のコードで、herdr CLIの全機能を呼べる。ドキュメントも「herdrはプラグインが何をするかをレビューもサンドボックス化もしない。サードパーティのプラグインは作者から来るものであってherdrから来るものではないので、各自で検証し、自己責任で動かすこと」と明言している。エディタ拡張やシェルスクリプトと同じ姿勢で読んでから入れるべき、という位置づけ。
出典
- Plugins | herdr
- Socket API | herdr
- herdr/docs/…/plugins.mdx - GitHub
- A practical guide to Herdr plugins - Flavio Copes