Claude CodeのOSC 7501対応 — 端末に作業中・入力待ち・完了を伝える
v2.1.295でClaude CodeがProgram Status Protocol(OSC 7501)に対応しました。端末が状態を表示できる仕組みと、設定が要らない理由、hookから送れない点をまとめます。
OSC 7501は、プログラムが自分の状態を端末に直接伝える仕組み
Claude Code v2.1.295のchangelogに、Program Status Protocol(OSC 7501)への対応が入りました。記載は1行で、実装した端末はClaude Codeが作業中か、ユーザーの入力待ちか、完了したかを表示できる、という内容です。
OSC 7501は、端末のエスケープシーケンスの一つです。実行中のプログラムが「いま何をしているか」を、擬似端末(pty)経由で端末エミュレーターに送ります。仕様は2026年10月6日にMitchell Hashimoto氏が公開しました。同氏はGhosttyの作者です。
Claude Code側で必要な設定は、公式ドキュメントのどのページにも書かれていません。つまり、対応した端末を使っていれば何かが表示される、という位置づけです。この記事では、仕様から読み取れる範囲で「何が送られ、何が端末側の仕事なのか」をまとめます。
送られる内容は状態名とメッセージ
仕様では、本体はkey=valueを:でつないだ形です。必須なのはstateだけで、値は次の5種類と、記録を消すclearです。
| state | 意味 |
|---|---|
idle | 意味待機中。次の指示を待っている |
working | 意味実行中。進捗率を付けられる |
done | 意味作業が終わり、結果をまだユーザーが見ていない |
blocked | 意味ユーザーが何かするまで進めない |
error | 意味失敗して止まった |
blockedにはkindが付き、permission(許可)、question(質問への回答)、auth(認証)のどれかを示します。appにはプログラムを表す安定した名前を入れる決まりで、仕様の例にはclaude-codeも出てきます。msgは人間が読む1行で、UTF-8をbase64にしたものです。
送信の見た目は次のとおりです。これは仕様に載っているTerraformの例で、承認待ちを表します。
ESC ] 7501 ; state=blocked:kind=permission:app=terraform:msg=<base64> ESC \changelogの「作業中・入力待ち・完了」は、working、blocked(またはidle)、doneに対応するように読めます。ただしClaude Codeがどの場面でどのstateやkindを送るかは、changelogにも公式ドキュメントにも記載がありません。
端末が対応しているかは問い合わせで分かる
対応の有無を知る方法は、仕様上ひとつです。プログラムがOSC 7501 ; ?を送り、対応する端末が同じ本体?を返します。返事がなければ非対応として扱います。
手元の端末で試すなら、次の1行で状態を送れます。仕様に載っているシェル関数をそのまま使った形です。対応端末なら、working、続いてdoneの状態が端末に記録されます。
status() {
printf '\e]7501;state=%s:msg=%s\e\\' "$1" \
"$(printf '%s' "$2" | base64 | tr -d '\n')"
}
status working "Syncing photos"; sleep 5; status done "Done"仕様は、未対応の端末は未知のOSCを無視するよう求めています。そのため、対応していない端末で実行しても画面は乱れないのが想定です。ただし各端末の実際の挙動は、端末ごとの実装次第です。
表示のしかたは端末の仕事
OSC 7501は、状態を共有するだけの取り決めです。通知にするか、タブのアイコンにするか、一覧に並べるかは仕様の対象外で、端末が決めます。仕様は「notification」や「focus」といったGUI由来の語を意図的に避けています。
実装の状況は次のとおりです。
- 仕様の作者はlibghosttyとRexに実装し、Terraform、Claude Code、Codex、Homebrewへは、プラグインかフォークによる試作を作ったと書いています
- Ghosttyの本体にマージされたpull requestはlibghostty-vtへの対応で、説明には「Ghosttyアプリは今のところこの報告を無視する」とあります
- 別の端末プロジェクトでも、対応を検討するissueが立ち始めています
つまり、Ghosttyアプリに限っては、Claude Code側が送っても画面に何も出ない可能性が高い、という読み方になります。表示まで含めて試せる端末は限られるので、手元の端末が対応するかは、上のコマンドとその端末のドキュメントで確かめるのが確実です。
従来の通知設定とは役割が違う
Claude Codeにはすでに通知の仕組みがあります。端末設定のページによると、既定でデスクトップ通知を送るのはGhostty、Kitty、iTerm2だけで、ほかの端末ではpreferredNotifChannelを"terminal_bell"にするか、Notificationフックを使います。詳しい手順はWezTermでの通知設定にまとめています。
OSC 7501との違いは、通知が「1回の出来事」であるのに対し、7501は「いまの状態の記録」を端末に残す点です。仕様は、通知では「プログラムが待ち続けていること」や「回復したこと」を端末が知れないと説明しています。複数のセッションを並べて見るツールが、画面の文字やウィンドウタイトルを推測せずに済むのが狙いです。
スマートフォンへの完了通知が目的なら、別の仕組みになります。こちらはPushNotificationの設定の記事が扱っています。
hookから7501を送ることはできない
自分で状態を送りたくなる場面もありますが、ここには制約があります。フックの出力にterminalSequenceを返すと、Claude Codeが代わりに端末へ書き込んでくれます。ただしそのフィールドが受け付けるのは許可リストの方式で、中身はウィンドウタイトル(OSC 0・1・2)、OSC 9、OSC 99、OSC 777、BELです。
リストにOSC 7501は含まれていません。許可リスト外のシーケンスは、フィールド全体が無視されます。つまり、Notificationフックなどから7501を差し込む運用は、ドキュメントの記載どおりなら成立しません。Claude Code自身の送信に頼る形になります。
フックは制御端末を持たないため、/dev/ttyへ直接書く方法も使えません。この点は同じドキュメントに書かれています。
tmuxやSSHで使うときの注意
仕様は、端末の記録はptyに紐づくと定めています。SSH越しでも、ptyが通れば届く設計です。一方、tmuxのような多重化ソフトが未知のOSCを通すかどうかは、仕様の外です。通知を届ける場合にpassthroughを有効にする必要があるのと同じ話になるかもしれませんが、7501での挙動は公式の記載がなく、断定できません。
仕様の側は、terminfoのPstという拡張機能で対応を広告できるとしています。ただしPstが無くても非対応とは判断しない、問い合わせの返事が最終的な判定、という立場です。
記録はいつ消えるか
端末側の記録の寿命も、仕様で決まっています。
workingとblockedは、プロセスの終了か次のシェルプロンプトで消えるdoneとerrorは、プロセスが終わってもプロンプトが出ても残る。ユーザーが端末に戻ってキーを押した時点などで消すのは端末の判断- ユーザーが中断した場合、プログラムは
idleを報告する
「完了したのに見ていない」状態が残るので、席を外している間に終わった作業を端末側が拾えます。
既存のシーケンスでは足りなかった点
仕様は、近い役割の既存シーケンスとの違いも書いています。
- OSC 9;4(進捗表示): 忙しいか、何パーセントか、エラーかしか言えません。ユーザー待ちかどうか、何を求めているかは伝えられず、メッセージも識別子も持ちません。仕様は、端末がこれを7501のルート記録に対応づけてよいとしています
- OSC 9・99・777(デスクトップ通知): 1回きりの出来事です。表示した後に端末は何も覚えていないため、まだ待っているのか、回復したのかを判断できません
- OSC 133(シェル統合): プロンプトやコマンドの区切りを示しますが、出すのはシェルです。コマンドが走っている、終わったという情報までで、そのプログラムが止まっているかは分かりません
- OSC 0・2(ウィンドウタイトル): 自由文字列なので、スピナー文字などを混ぜて状態を表すしかなく、機械が確実に読める形式ではありません
Claude Codeのように、実行中に許可を求めてしばしば止まるプログラムは、blockedとkind=permissionを持てる7501と相性が良い、というのが仕様の考え方です。
これまでの状態表示がなぜ不安定だったか
仕様の作者は、複数のエージェントを並べて見る「エージェントの受信箱」型ツールが、画面の文字やウィンドウタイトルの推測に頼っていると指摘しています。例に挙がるのはHerdrで、Claude Codeを作業中と判定する規則の1つは、ウィンドウタイトルの先頭が点字のスピナー、またはv2.1.228以降の半円のスピナーかどうかを見ます。このClaude Code用の定義ファイルは、3か月で10回変更されたと書かれています。
別のやり方として、各ツール独自のソケットAPIで状態を報告する方法もあります。ただしツールごとに個別の連携が要り、SSHやコンテナ越しには追加の橋渡しが必要になります。ptyはどちらも最初から通っているので、そこに載せるのがOSC 7501の発想です。
複数の記録とサイズの上限
Claude Codeの1行の対応には現れませんが、仕様は並列の作業も扱えます。idにbuild/testのようにスラッシュ区切りの階層を付けると、親子関係のある複数の記録を同時に持てます。ルートがworkingのまま、子の1つだけがblockedという状態も成り立ちます。
安全面の取り決めもあります。msgとtitleに制御文字が含まれる報告は丸ごと破棄され、端末が書き戻すのは対応を示す固定の返信だけです。サイズにも上限があります。
| 項目 | 上限 |
|---|---|
| 1回の送信全体 | 上限4096バイト |
msg | 上限エンコード後2732バイト、デコード後2048バイト |
title | 上限エンコード後256バイト |
| 端末ごとの記録数 | 上限256(端末は最低64件に対応) |
上限を超えた報告は、一部だけ反映されることなく全体が捨てられます。
まとめ
v2.1.295のOSC 7501対応は、Claude Codeの状態をptyにそのまま流すだけの変更です。設定項目はなく、効果は対応端末の表示次第です。いま使っている端末が対応しているなら、端末のドキュメントで表示方法を確かめる。対応していないなら、これまでの通知設定を続ける。それで足ります。Ghosttyのアプリ自体はまだ状態を表示しないので、期待しすぎないほうが無難です。
詳しくは、リリース全体の変更点をv2.1.295のリリースノートで確認できます。