Хашимото предложил протокол OSC 7501: программа сама сообщает терминалу статус

Митчелл Хашимото написал спецификацию новой escape-последовательности для терминала, OSC 7501, Program Status Protocol (протокол статуса программы). Она позволяет любой программе сообщить терминалу, чем она занята: простаивает, работает, ждёт пользователя, завершила работу или завершилась ошибкой, а также почему. Протокол универсальный и «родной» для терминала: он вырос из работы автора над Superlogical и Ghostty, но в самой спецификации нет ни продуктовых функций, ни продуктовой терминологии.

Проблема в том, что долгая работа в терминале, сборки, деплой, обновление пакетов, обработка данных и всё чаще кодинг-агенты, чередует самостоятельную работу, ожидание пользователя и завершение, а пользователь уходит заниматься другим и хочет узнать, когда работа закончилась или когда нужен он сам. Отдельные решения существовали десятилетиями: терминалы следят за процессом на переднем плане и уведомляют о его смене либо ждут паузы в выводе. По мнению автора, цельного решения, не привязанного к способу взаимодействия и передающего прогресс, блокировку, завершение и деревья задач, не было, а собрать его из существующих последовательностей надёжно нельзя.

Отдельный раздел посвящён «агентным инбоксам» (agentic inbox), инструментам, показывающим в одном окне всех запущенных агентов: кто работает, кто закончил, кто ждёт человека. Herdr, cmux и Agent Deck автор называет несколькими примерами из сотен. Сейчас они решают задачу двумя способами. Первый, эвристики: чтение экрана или заголовка окна и сопоставление с известными шаблонами. В Herdr это TOML-правила; для Claude Code таких правил 16, а первое считает агента «работающим», если заголовок окна начинается с символа-спиннера Брайля или, начиная с версии 2.1.228, с символа-полукруга. История этого файла показывает десять изменений за три месяца только для Claude Code. Автор подчёркивает, что это не критика Herdr: его мейнтейнеры делают максимум возможного с имеющимися средствами. Второй способ, внепроцессные API вроде сокетного API Herdr или cmux notify: программа сама сообщает состояние, но каждую программу приходится интегрировать с каждым инбоксом отдельно, а локальный сокет не работает по SSH и из контейнера без дополнительных мостов. Pty же работает во всех этих случаях.

Устройство OSC 7501. Программа пишет состояние прямо в pty, а формат безопасен для отправки куда угодно: корректные терминалы игнорируют неизвестные OSC. Тело последовательности, пары key=value, разделённые двоеточием. Единственный обязательный ключ, state. Необязательные: app, стабильное машиночитаемое имя программы (например, cargo или claude-code) и msg, одна человекочитаемая строка в base64. Программа, которая делает несколько дел сразу, может сообщать несколько записей с иерархическими идентификаторами: деплой-инструмент работает в корне, пока us-east загружает образ на 40%, а eu-west заблокирован в ожидании подтверждения выкладки в продакшен. Терминал сам решает, что показать. Состояние clear удаляет записи. В примере Terraform сообщает о блокировке: state=blocked, kind=permission, app=terraform и закодированное сообщение «Apply 3 to add, 1 to change, 0 to destroy?».

Интеграция тривиальна: для обёртки над rsync в shell достаточно функции status на printf и base64 и вызовов «status working», «status done», «status error». Не нужны SDK, сокеты, переменные окружения и JSON. Остальное, время жизни записей, определение поддержки, terminfo, ограничения размера и безопасность, описано в полной спецификации, которая короткая и целиком написана автором вручную.

Автор уже реализовал протокол дважды: в libghostty и параллельно в Rex. Кроме того, он сделал proof-of-concept для Terraform, Claude Code, Codex и Homebrew через плагины или форки; каждая реализация заняла не больше дюжины строк. Он говорит, что был на связи с мейнтейнерами многих популярных терминальных программ и эмуляторов, которые помогли проверить и сформировать спецификацию. Тем, кто реализует протокол, предлагается написать автору, чтобы попасть в список поддерживающих. Итог, призыв перестать угадывать, что делают программы, по их экранам и деревьям процессов: программа и так знает свой статус.

Ключевые факты

  • OSC 7501 (Program Status Protocol), новая escape-последовательность: программа сообщает терминалу состояние (простой, работа, ожидание пользователя, завершение, ошибка) и причину.
  • Тело, пары key=value через двоеточие; обязателен только ключ state, необязательны app (имя программы) и msg (строка в base64); для параллельных задач есть иерархические id, состояние clear удаляет записи.
  • Сейчас «агентные инбоксы» угадывают статус по заголовку окна (у Herdr 16 правил для Claude Code, десять правок файла за три месяца) или через отдельные API, не работающие по SSH и из контейнеров без мостов.
  • Автор реализовал протокол в libghostty и Rex, а также как proof-of-concept в Terraform, Claude Code, Codex и Homebrew через плагины или форки, не больше дюжины строк на каждый.
  • Для shell-скриптов хватает одной функции на printf и base64: без SDK, сокетов, переменных окружения и JSON.

Почему это важно

ИИ-агенты, сборки и деплои работают в терминале подолгу, а пользователю нужно знать, когда они закончили или ждут его. Сегодня инструменты-«инбоксы» вынуждены гадать по заголовку окна: на примере Herdr видно, что для одного Claude Code файл правил менялся десять раз за три месяца, например, из-за смены символа спиннера в версии 2.1.228. Единый протокол, по замыслу автора, заменил бы эти догадки сообщением самой программы, которая знает своё состояние. Работает ли это на практике, зависит от того, примут ли протокол авторы терминалов и программ.

Кому это важно

Разработчикам терминальных эмуляторов и авторам инструментов-инбоксов для агентов (Herdr, cmux, Agent Deck): им предлагается читать статус из одного места вместо эвристик и отдельных API. Авторам CLI-программ и агентов: сообщить статус можно парой строк. Пользователям, которые запускают много долгих задач и агентов параллельно и хотят видеть, какая закончила или ждёт ответа.

Как это применить

Для скрипта достаточно функции вроде status() { printf '\e]7501;state=%s:msg=%s\e\' "$1" "$(printf '%s' "$2" | base64 | tr -d ' ')"; } и вызовов «status working», «status done», «status error» вокруг долгой команды, например rsync. Авторы терминалов могут разбирать последовательность и показывать её как уведомление, элемент инбокса или значок статуса. Полные правила, время жизни записей, определение поддержки, terminfo, ограничения размера, безопасность, в самой спецификации. Автор просит присылать сведения о реализациях по почте, чтобы добавить их в список.

Можно ли доверять

Источник, личный пост автора спецификации, поэтому описание проблемы и достоинств протокола отражает его точку зрения. Утверждения о реализациях и о том, что мейнтейнеры помогали формировать спецификацию, слова самого автора; в тексте не названы ни конкретные мейнтейнеры, ни другие поддерживающие, ни реакция компаний вроде Anthropic или OpenAI. Реализации для Terraform, Claude Code, Codex и Homebrew описаны как proof-of-concept через плагины или форки, а не как принятые в основные проекты. Цифры про Herdr (16 правил, десять изменений за три месяца) взяты из этого же поста.

Риски и подводные камни

Протокол новый, и ценность его определяется принятием: в тексте не сказано, какие терминалы, кроме основанных на Ghostty, его уже поддерживают, и не названы версии или сроки выхода реализаций в libghostty и Rex. Пока поддержки мало, программам придётся отправлять последовательность вслепую; автор указывает, что это безопасно, так как корректные терминалы игнорируют неизвестные OSC. Инбоксам, вероятно, ещё потребуется сохранять эвристики для программ, которые протокол не используют. Детали ограничений и безопасности находятся в спецификации, которую пост пересказывает лишь в общих чертах.

«Я хотел бы, чтобы мы все перестали угадывать, что делают программы, читая их экраны или деревья процессов. Программа уже знает. Давайте дадим ей способ нам об этом сказать!»

— Митчелл Хашимото, из поста об OSC 7501