終端機新增 OSC 7501,讓程式直接回報 idle、working、blocked 狀態
Mitchell Hashimoto · 2026-10-09(規格 0.3 版,2026-10-06 公布)
終端機多工工具過去靠猜視窗標題裡的 spinner 字元來判斷 AI agent 在跑還是在等人,OSC 7501(Program Status Protocol)改成讓程式自己用一行 escape sequence 說明狀態。規格由 Mitchell Hashimoto 提出,libghostty 的實作 PR #14560 已在 2026-10-06 併入 main(commit a4aacd9)。
Ghostty 應用本身目前還會忽略這類回報,PR 說明也寫明尚未加進 terminfo。
原本的問題
build、部署、AI agent 這類長時間工作會在「執行中」「等你回答」「做完了」之間切換,而使用者早已切到別的視窗。終端機沒有標準方式得知這些狀態,只能看前景行程,或等輸出安靜下來。
作者列出 agentic inbox 類工具(Herdr、cmux、Agent Deck)目前的兩種做法。一是啟發式判斷,例如讀畫面或視窗標題,Herdr 對 Claude Code 的偵測規則就是比對標題裡的 spinner 字元,而且短時間內改了很多次。二是走終端機以外的管道,如 socket 或通知指令,這要逐一整合各個工具,在 SSH 或容器裡也不好用。
規格細節
回報格式是 OSC 7501 ; pairs ST,body 是以冒號分隔的 key=value。規格只要求一個必填欄位 state,缺少或值不認得,整筆回報會被忽略。
idle:閒置,等待下一個指令。working:執行中,可附progress(整數 0–100,沒寫代表不確定進度)。done:已完成,使用者還沒看過結果。blocked:需要使用者動作,搭配kind(permission、question、auth)與msg。error:失敗並停止;clear:移除該紀錄及其所有子孫。
其他欄位有 app(程式名稱,如 cargo)、title 與 msg。後兩者是 UTF-8 的 base64,所以值不會出現 : 或 ;,不需要跳脫。每筆回報會完整取代該紀錄,沒重複寫的欄位就消失,因此 app 與 title 每次都要帶。
# 範例:以 id=deploy/eu 回報「需要使用者確認」(msg 為 "Apply?" 的 base64)
printf '\033]7501;id=deploy/eu:state=blocked:kind=permission:app=terraform:msg=QXBwbHk/\033\\'id 以 / 表示階層,build/test 是 build 的子紀錄,所以根任務可以 working,各區域的子任務各自有狀態。沒寫 id 就是根紀錄。
紀錄的生命週期與安全
規格不設 heartbeat,終端機不得要求程式定期重送。行程結束或新的 shell prompt 開始(OSC 133 A)時,終端機必須丟掉 working 與 blocked,done 與 error 則保留,讓使用者回來後還看得到結果。使用者中斷時,程式應回報 idle。
硬上限包括整段序列 4096 bytes、msg 解碼後 2048 bytes、每個終端機最多 256 筆紀錄(至少須支援 64 筆,滿了就移除最久沒更新的)。decoded 的 msg 或 title 若含控制字元,整筆回報作廢;終端機不得把它們當 markup,也不會回寫任何內容,唯一的回應是對 OSC 7501 ; ? 查詢的固定回覆。
偵測支援度的方式是送出該查詢,再接著送 CSI c,若先收到 CSI c 的回覆就代表不支援。不查詢直接送也安全,因為終端機必須忽略不認得的 OSC。
影響範圍
寫 TUI、CLI 或 agent 工具的人可以在要等使用者時送出 state=blocked,不用再維護各家終端機的整合。作者的文章稱 Terraform、Claude Code、Codex、Homebrew 都有各約十來行的 proof-of-concept。要小心的是 done 與 error:程式若在完成後立刻退出,應先回報這兩者,否則狀態會隨行程結束被丟掉。
終端機與 agent 管理工具的作者要自己實作紀錄儲存。libghostty 的做法是只負責解析,由嵌入方(embedder)按一個 id 一筆紀錄來存放並套用生命週期規則,全域重設(RIS)時回報清除全部紀錄。若終端機把 OSC 9;4 對應到根紀錄,收到 OSC 7501 之後應停止這個對應,否則會蓋掉真正回報的 kind 與 msg。
另一點是跨終端的來源識別:規格要求顯示紀錄時標示來源終端機,避免程式冒充另一個終端機。目前實作只見於 libghostty 與 Rex,規格仍是 0.3 版,作者正向應用與終端機開發者徵求回饋,欄位仍可能變動。