Agent 検出
MadoHub が実行中の AI Agent を識別し、その状態を追跡する方法。
MadoHub はターミナル出力をリアルタイムで監視し、どの AI Agent が実行中か、そして現在どの状態にあるかを検出します。これにより、タイルのタイトルバーに表示される視覚的インジケーターや、ルーティング接続のトリガーが機能します。
対応している Agent
Claude Code
ターミナル出力中の Unicode マーカーで検出します。
| マーカー | 意味 |
|---|---|
| ❯ (U+2770) | Claude Code のプロンプト |
| ✽ (U+273D) | Thinking / スピナー |
| ⏺ (U+23FA) | ツール使用インジケーター |
また、出力中の文字列 "Claude Code" にも一致します。
OpenAI Codex CLI
次のパターンで検出します。
OpenAI Codex— ブランド行codex>— TUI プロンプトopenai/codex— パッケージ参照codex v[0-9]— バージョン文字列> _ OpenAI Codex— 起動バナーcodex --dangerously— サンドボックス回避フラグ(大文字小文字を区別しない)codex...fast— 高速モデル呼び出し(大文字小文字を区別しない)gpt-[0-9.]+ x?high— モデル情報
Amp と OpenCode
Amp と OpenCode も Agent の種類として認識されますが、上記のフロントエンドのターミナルテキスト検出器では認識されません。この検出器が分類できるのは Claude Code、Codex、汎用シェルのみです。Amp と OpenCode のセッションは別の仕組み、つまりバックエンドのプロセスツリースキャンによって識別されます。これはターミナルの子孫プロセスを走査し、それぞれの実行ファイルを探すというものです。
汎用シェル
Agent のマーカーが検出されない場合、端末は標準的なシェルセッションとして扱われます。
Agent の状態
MadoHub は各ターミナルについて 7 つの状態を追跡します。
| 状態 | 検出条件 | 視覚表示 |
|---|---|---|
| Working | ステータスバーに "esc to interrupt" がある、または ✽/⏺ に省略記号が付く | 緑の点滅枠 |
| Idle | ステータスバーに "? for shortcuts" がある | インジケーターなし |
| Waiting | "Allow once" / "Allow always" / "Deny" / "Do you want to proceed?" / "(y/n)" / "requires approval" のダイアログ | オレンジの枠 |
| Stopped | ターミナルのスクレイピングで完了キーワードを検出(あいまい — タスクが成功して終わったのか、そうでないのかは分からない) | 赤いインジケーター |
| Completed | 成功終了を確定。Agent 自身の JSONL/DB セッションログから解析(例: Codex の task_complete) | 緑のインジケーター |
| Failed | 失敗を確定。Agent 自身の JSONL/DB セッションログから解析(例: Codex の turn_aborted / error) | 赤いインジケーター |
| Exited | 背後の PTY プロセスが消滅している(終端状態) | グレー/暗いインジケーター |
各状態には pty-scrape か jsonl-watcher のいずれかの stateSource タグが付与されており、UI(および任意のルーティングロジック)が「ターミナルのリアルタイムスクレイピングによる推測」と「Agent 自身のセッショントランスクリプトを読んで確定した判定」を区別できるようになっています。"Stopped" は常に pty-scrape であり、本質的にあいまいです。一方 "Completed" と "Failed" は jsonl-watcher に由来し、確定的なものとして扱われます。
完了検出
MadoHub は、固定された単語リストではなく 形状(shape) の一致によって、Agent がタスクを完了したことを検出します。行頭のスピナー記号に続いて、大文字で始まる過去形の動詞、続けて " for " と時間の長さが来る、というパターンです。
正規表現パターン:
/(?:^\s*[✶✽✳✢·∗*]\s*([A-Z][a-zé]+(?:ed|t))|\b(Saut[ée]*d|Cogitated))\s+for\s+(?:\d+\s*[hm]\s*)*\d+\s*[hms]\b/Claude Code はリリースごとに動詞をローテーションさせます(Worked、Churned、Sautéed、Cogitated など)。そのため動詞自体は意図的に列挙可能なものとはされておらず、代わりに形状によってマッチングを行います。実際に一致する例は次のようになります。
✽ Worked for 2m 30s行頭の記号アンカー(✶✽✳✢·∗* のいずれか)こそが、"Retried for 3s" のような通常の文章を誤検出しないための決め手です。Sautéed と Cogitated がこのパターンに残っているのは、記号アンカー方式より前の古い CLI 出力に対応するための、記号を伴わないレガシーなフォールバックとしてのみです。
完了が検出されると、Agent の状態は "stopped" に変わり、接続されたルーティングトリガーが発火する場合があります。