cd /news/ai-agents/osc-7501-program-status-how-your-ter… · home › topics › ai-agents › article
[ARTICLE · art-150520] src=stackness.dev ↗ pub= topic=ai-agents verified=true sentiment=· neutral

OSC 7501 program status: how your terminal knows an agent is waiting on you, and what to wire up today

Mitchell Hashimoto published OSC 7501, a terminal escape sequence letting programs report idle, working, blocked, done or error status, on 6 October 2026, and three coding agents shipped support within two days: Pi 1.1.0 on 7 October, plus Claude Code 2.1.295 and Crush 0.98.0 on 8 October. As of 15 October 2026, no released version of Ghostty displays the protocol, kitty has it on master only, and tmux has declined it, while the spec sits at revision 0.4 dated 10 October 2026 after a public review by kitty maintainer Kovid Goyal in kitty issue #10638. The protocol lets a terminal surface a blocked agent — for example a Terraform apply waiting on permission — as a tab badge, sidebar row or desktop notification.

by read10 min views9 publishedOct 15, 2026
OSC 7501 program status: how your terminal knows an agent is waiting on you, and what to wire up today
Image: Stackness (auto-discovered)

OSC 7501, the Program Status Protocol, is a terminal escape sequence that lets a program tell the terminal whether it is idle, working, blocked on the user, done or failed. Mitchell Hashimoto published it on 6 October 2026, and within two days three coding agents shipped it: Pi 1.1.0 on 7 October, Claude Code 2.1.295 and Crush 0.98.0 on 8 October. Terminals are slower to follow: as of 15 October 2026, no released version of Ghostty displays it, kitty has it on master only, and tmux has declined it for now.

What is OSC 7501? #

OSC 7501 is a one-line report a program writes to its own terminal: a state, plus optional keys for what kind of input it wants, a progress percentage, a program name and a message. The terminal keeps the latest report as a record, one per id in each pane (a simple program uses only one), and shows it however it likes, as a tab badge, a sidebar row or a desktop notification. The spec is at revision 0.4, dated 10 October 2026.

There are five states and one command:

State Meaning in the spec Dropped when
idle At rest, waiting for the next instruction Replaced or cleared
working Running, optionally with progress 0-100 The process exits or a new shell prompt starts
blocked Cannot continue until the user acts; kind ispermission ,question orauth Same as working
done Finished, and the user has not looked yet Survives exit; the terminal decides when to hide it
error Failed and stopped Same as done
clear Not a state: removes the record

The spec lives in the docs of Rex, Mitchell's own terminal at Superlogical, but says the protocol "has no Superlogical-specific functionality". It is not a standards-body document, and no licence is published on the spec text. Revision 0.4 came out of a public review by kitty's maintainer, Kovid Goyal, in kitty issue #10638: terminfo was removed, and the probe reply can now list the states and kinds a terminal supports.

One blocked deploy, byte by byte #

A report is ESC ] 7501 ;, a list of key=value pairs joined by colons, then ESC \ or BEL. Free text in msg and title is base64, so nothing needs escaping. This is the spec's own example, a Terraform apply waiting for approval:

ESC ] 7501 ; state=blocked:kind=permission:app=terraform:msg=QXBwbHkgMyB0byBhZGQsIDEgdG8gY2hhbmdlLCAwIHRvIGRlc3Ryb3k/ ESC \

The message decodes to "Apply 3 to add, 1 to change, 0 to destroy?". A program checks for support by sending ESC ] 7501 ; ? ESC \, which a supporting terminal answers with ?. The spec suggests sending a device attributes query ( CSI c) straight after it: every terminal answers that one, so if its reply comes first, there is no support. Sending reports without asking is also allowed, because terminals must ignore OSC codes they do not know.

The spec includes a shell function, which works in any script:

status() {
  printf '\e]7501;state=%s:msg=%s\e\\' "$1" "$(printf '%s' "$2" | base64 | tr -d '\n')"
}
status working "Syncing photos"
rsync -a ~/Photos backup:/photos && status done "Photos synced" || status error "rsync failed"

In tuios, a terminal multiplexer that shipped support on 8 October, a blocked report moves the pane to the top of its agents list:

The program status clip from the tuios 0.9.0 release, 8 October 2026: the blocked deploy moves to the top of the list. Screenshot of the tuios v0.9.0 release by Gaurav Gosain.

OSC 7501 replaces screen scraping, not notifications #

OSC 7501 replaces the guesswork agent dashboards do today: reading the window title, hashing the screen or watching the process tree to decide whether an agent is busy. Mitchell quotes the detection rules of Herdr, which change with Claude Code's spinner glyphs and were edited ten times in three months for Claude Code alone. On X he wrote that he found over 250 agent orchestrators, each detecting agent state with its own heuristic.

The older sequences each carry part of the answer:

  • OSC 9, 99 and 777 raise a desktop notification. It is a one-off event, so the terminal cannot tell later that the program is still waiting or that it recovered.
  • OSC 9;4 draws a progress bar. It says busy, a percentage or error, but cannot say the program is waiting on you or why.
  • OSC 133 comes from the shell, so it knows a command is running or finished, not whether it is stuck.
  • The window title is one free-form string that agents overload with spinner characters.

Notifications do not go away: the spec lets a terminal raise one when a record changes, and asks it to rate-limit them. The protocol has critics. In tmux issue #5713 the maintainer called it "premature" and said pane titles, OSC 9 progress and OSC 133 cover enough for now. On Hacker News, one commenter called the kind values specific to AI agents, and another found it odd that the post never mentions the terminal bell.

The agent notification slot has three layers #

Getting a ping when an agent needs you is a slot in a coding agent stack, and three layers can fill it. Harness hooks run your command when the agent hits an event. External watchers read state from outside, through hooks or the screen. OSC 7501 is the in-band layer: the agent writes to its own pty, so the report also works over SSH and inside a container, where a local socket needs a bridge.

Layer Example Knows "blocked" because Breaks when
Harness hook Claude Code Notification hook,Codexnotify , anOpenCode plugin onsession.idle The harness fires the event You run a harness without the hook configured
External watcher Coucou , Herdr A hook relays to it, or it reads the screen The screen layout or hook format changes
Terminal status OSC 7501 The program says so The terminal or a multiplexer in between ignores it

The three layers are used together. Coucou, the Mac notch companion with 5,240 GitHub stars on 15 October, watches Claude Code, Codex, Gemini CLI and others through hooks that report over a Unix socket, and its README never mentions 7501. The inboxes that adopted 7501 rank it against hooks: termio and diri let a live 7501 record override hook reports (#713, #737), while tuios ranks a hook in the same pane above it. Hooks keep one thing 7501 lacks: a session id that survives /clear and /resume, which Claude Code's SessionStart hook reports. bigarrow, from a Show HN with 419 points, covers the opposite direction: an agent draws an arrow over the macOS button it needs you to click.

Claude Code, Pi and Crush ship it; the Ghostty app does not yet #

Coding agents that send OSC 7501 are ahead of the terminals that show it. Three agents shipped it in tagged releases within two days of Mitchell's post, and Codex merged it to main on 9 October. On the receiving side, tuios 0.9.0, termio 0.56.0 and diri 0.9.6 are tagged releases that read it. Rex shows it in a macOS beta, and kitty and libghostty-vt have it on their main branches only.

Tool Side Status on 15 October 2026
Claude Code Sends Shipped in 2.1.295 ; the npmstable tag is still 2.1.292
Pi Sends Shipped in 1.1.0 ;PI_PROGRAM_STATUS=0 turns it off
Crush Sends Shipped in 0.98.0
Codex Sends Merged ( #52725 ,#54114 ); stable 0.162.1 predates it
OpenCode Sends Merged 13 October, removed 14 October with a reverted TUI library upgrade
Gemini CLI Sends Requested in issue #29710
tuios Shows Shipped in 0.9.0, 8 October
termio, diri Show Shipped in termio 0.56.0 and diri 0.9.6, 9 October
Rex Shows macOS beta, invite only
kitty Shows On master, listed for 0.50.0; latest release 0.49.2
Ghostty Shows In libghostty-vt on main; the app ignores reports ; latest release 1.3.1
cmux Shows Documented on main as a sidebar status row
tmux Passes through Declined for now; it drops the sequence

Claude Code's terminal docs say there is nothing to turn on, and list why no status may appear: a version before 2.1.295, a session inside tmux (Claude Code asks tmux, not your terminal, and allow-passthrough does not change that), a background session, or CLAUDE_CODE_DISABLE_TERMINAL_TITLE=1. A sender can also get it wrong. Atomic, an agent built on Pi, reported done while a workflow run was still working or waiting at an approval gate, for up to 22 minutes (issue #3556), because its reporter followed only the main session.

Who needs OSC 7501 and who can skip it #

OSC 7501 matters most to people running several agent sessions side by side who need to know which one is waiting, and to the people building inboxes and multiplexers who maintain detection rules today. It also helps over SSH, since the report rides the pty. With one agent in one tab, a notification hook already covers it.

You can skip it for now if you:

  • live in tmux, which drops the sequence, or use the Ghostty app, which does not display it yet
  • run Claude Code from the stable channel, which is still on 2.1.292
  • already get a desktop notification from preferredNotifChannel or a hook, and run one session at a time

On Stackness, as of 15 October 2026, 8 public profiles list Claude Code and 2 list iTerm2, while no real profile lists Ghostty, kitty or tmux once bot accounts are removed (data sources). The sample is small, but terminal emulators are barely listed, and they are the part this protocol depends on. The terminal and shell tools developers list are where to check what yours supports.

Where to start with OSC 7501 #

Check your terminal first, then pick the layer that works today. The probe below is adapted from the tmux issue, not taken from the spec. It prints the raw reply, and if only the 033 [ ? device attributes reply comes back, your terminal does not support 7501:

stty -echo -icanon min 0 time 10
printf '\e]7501;?\e\\\e[c'
IFS= read -r -d c reply
stty sane
printf '%s\n' "$reply" | od -c

If the terminal answers, update Claude Code to 2.1.295 or later (or Pi to 1.1.0) and run it outside tmux. If it does not, use a hook. Claude Code's hooks guide gives this macOS notification, which fires whenever Claude Code is waiting for input or permission:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

A hook cannot send 7501 itself. Hooks run without a terminal, and the terminalSequence field that passes an escape sequence through accepts only OSC 0, 1, 2, 9, 99, 777 and BEL (hooks reference). Codex's equivalent is notify = ["python3", "/path/to/notify.py"] in config.toml, which runs on agent-turn-complete (Codex config). For long-running scripts of your own, the status() function above is harmless on terminals that ignore it. The multi-agent workspace post covers the inboxes that will read it.

OSC 7501 in brief #

  • Licence: none is published on the spec. The post is © Mitchell Hashimoto.
  • Limits: a whole report is at most 4,096 bytes, and a terminal must hold at least 64 records per pane.
  • Security: a report is untrusted input. The only bytes a terminal sends back are the probe reply, so a program cannot read another program's records.
  • Governance: a reader suggested the UAPI group host the spec; Mitchellsaid he likes an independent owner, with no decision as of 15 October.

Which of these do you use? #

Nobody on Stackness runs Crush yet. Tick what you use and be the first.

Play Lonny Eagle Amateur Skater 4A pixel art skateboarding game. Signing up opens it straight away.Sign up to play

── more in #ai-agents 4 stories · sorted by recency
── more on @mitchell hashimoto 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/osc-7501-program-sta…] indexed:0 read:10min 2026-10-15 · —