Hashimoto proposes OSC 7501, a terminal escape sequence for program status

Mitchell Hashimoto has written a specification for a new terminal escape sequence, OSC 7501, which he calls the Program Status Protocol. It lets any program tell the terminal what it is doing: idle, working, waiting on the user, finished, or failed, and why. His example is Terraform signalling that it is blocked waiting for user input with the message "Apply 3 to add, 1 to change, 0 to destroy?", base64-encoded inside the sequence. The terminal, or any other tool running Terraform, could show that as a notification, an inbox entry, a status icon or something else. Hashimoto says the protocol emerged from his work on Superlogical and Ghostty, but that the specification has no product-specific functionality or language and is meant to feel familiar to any terminal developer.

The problem he describes is long-running work in terminals: builds, deployments, package upgrades, data processing and, increasingly, coding agents. Such programs alternate between working alone, waiting on the user and finishing, while the user goes off to do something else. Older answers include terminals that watch the foreground process or wait for a period of quiet output. Hashimoto says none of them is a cohesive, generic solution that conveys progress, blocking, completion and trees of tasks, and that existing sequences cannot be cobbled together to do it robustly.

He then singles out what he calls the agentic inbox: a single view across every running agent showing which are working, which are done and which are waiting on you. He names Herdr, cmux and Agent Deck as a few examples of hundreds. He says such tools solve the status problem in two ways, both flawed. The first is heuristics: guessing from the screen or the window title. He uses Herdr as the example because it documents its approach openly. Herdr's detection manifests are TOML rules that classify an agent as idle, working or blocked. The post quotes the first of 16 rules for Claude Code, which treats the agent as working if its window title starts with a Braille spinner character or, as of version 2.1.228, a half-circle one. The history of that file shows ten changes in three months for Claude Code alone. Hashimoto stresses this is not a criticism: Herdr's maintainers are doing the best possible job with the tools available.

The second approach is an inbox-specific, out-of-band API, such as Herdr's socket API or cmux notify. It is better in one way, because the program that knows its state reports it. But every program must integrate with every inbox separately, and a local socket does not work over SSH or from inside a container without extra bridging. The pty, he notes, already works across all of that.

OSC 7501 reports state directly over the pty. The format is safe to send everywhere, because well-behaved terminals ignore unknown OSCs. The body is a list of key=value pairs separated by colons. The only required key is state. Optional keys include app, a stable machine-readable program name such as cargo or claude-code, and msg, a single human-readable line encoded as base64. Programs running several things at once can report multiple records using hierarchical ids. A deploy tool can be working at the root while us-east pushes an image at 40% and eu-west is blocked waiting for approval to deploy to production; both are true at once and the terminal decides what to show. A clear state removes records. The full spec also covers record lifetime, feature detection, terminfo, size limits and security.

Hashimoto shows a complete integration for a shell script wrapping rsync: a small status() function that prints the escape sequence with a base64-encoded message, then calls it with working before the sync and done or error after. He sums it up as no SDK, no sockets, no environment variables and no JSON, with no bias toward any GUI presentation or any workload such as AI.

On implementation, he says he has done it twice: one implementation in libghostty and a parallel one in Rex. He has also built proof-of-concept versions in Terraform, Claude Code, Codex and Homebrew, via plugins or forks, each no more than a dozen lines. He says he has been in contact with maintainers of many popular terminal programs and emulators, who helped review and shape the spec. Anyone who implements it is invited to email him to be added to a list of implementing tools. He says he wrote the spec entirely by hand and that it is short.

Key facts

  • OSC 7501, the Program Status Protocol, is a new terminal escape sequence that lets a program report its state (idle, working, waiting on the user, finished or failed, and why) to the terminal.
  • The body is colon-separated key=value pairs; state is the only required key, with optional app and msg (a single base64-encoded human-readable line). Hierarchical ids let one program report several records, and a clear state removes them.
  • Hashimoto says current agent dashboards rely on heuristics or out-of-band APIs; Herdr's Claude Code detection file, with 16 rules in its manifest, has had ten changes in three months.
  • He has implemented the protocol in libghostty and Rex, plus proof-of-concept versions in Terraform, Claude Code, Codex and Homebrew via plugins or forks, each no more than a dozen lines.
  • The sequence is meant to be safe to send everywhere because well-behaved terminals ignore unknown OSCs, and a shell script can emit it with plain POSIX sh.

Why it matters

Terminals have no standard way for a program to say it is waiting on you or has finished. Tools that watch many long-running jobs, especially coding agents, therefore guess from screen text or window titles, or require each program to integrate with each dashboard. Hashimoto's evidence is Herdr's Claude Code detection file, which has changed ten times in three months to keep up with things like new spinner characters. OSC 7501 moves the knowledge to where it already lives, the program itself, and sends it over the pty, which already works across SSH and containers. Hashimoto, who says he has maintained a terminal emulator for many years, wrote the spec to be generic rather than AI-specific.

Who it affects

Terminal emulator developers would parse the sequence and decide how to display it. Authors of command-line programs, build tools, deploy tools and coding agents would emit it. Builders of agentic inbox tools such as Herdr, cmux and Agent Deck could read state from the terminal instead of matching patterns or maintaining separate APIs. Users who run many long jobs or agents at once would get notifications and status views without per-tool setup.

How to use it

For program authors, the integration is a printf of the escape sequence with a state key and optionally app and a base64-encoded msg. Hashimoto's rsync wrapper does it in a small shell function, reporting working before the sync and done or error afterwards. Terminal developers need to parse the body of key=value pairs and decide how to show records; the full spec covers record lifetime, feature detection, terminfo, size limits and security. Anyone who implements it can email Hashimoto to be added to his list of implementing tools. The post does not mention any price or licence.

How solid is it

This is the author's own account of his own specification. He says he has implemented it in libghostty and Rex and reviewed it with maintainers of many popular terminal programs and emulators, but the post names none of them. The Terraform, Claude Code, Codex and Homebrew versions are described as proof-of-concept via plugins or forks, not as merged upstream or endorsed by those projects. No release versions or shipping dates are given for the libghostty or Rex implementations. The claim that there are hundreds of agentic inbox tools is Hashimoto's own statement.

Risks and caveats

A protocol only helps if both sides adopt it: programs must emit the sequence and terminals or inbox tools must consume it. The post does not say which terminals other than Ghostty-based ones support it today. Hashimoto's argument against existing tools rests mainly on one example, Herdr, and he states that it is not a criticism of that project. The safety claim that well-behaved terminals ignore unknown OSCs is his own description. The post itself says the spec covers size limits and security, and the retelling here does not go beyond that.

“I'd like us all to stop guessing what programs are doing by reading their screens or process trees.”

— Mitchell Hashimoto