52 comments

This is important (and TIL OSC 3008, how do we all keep up?!), but I want something adjacent to this... perhaps people can point me in a direction.

This OSC 7501 pushes state from Program to Terminal; with an explicit running/idle/fubar "state" field but also K/V data. Then Terminal can provide interactions thereof, such as display it.

What I want is for the Program to push the terminal some map of "key:command" which is available for the terminal to provide interactions thereof. Maybe that can come through just as a key in this?

Here's the motivation: when using a TUI on a phone or tablet, the keyboarding experience is horrible (unless you have a physical keyboard). It takes up too much real estate and most of the time there's only three keys action you want to hit.

An obvious solution is to put up HTML buttons and other chrome for users to tap. Personally, I've handled that bespoke at the library+application level, where the Golang and HTML+JS container work together. There's some reusability because it can just take a BubbleTea Help Model (holds keybindings), but it is limited.

In the last few weeks, I've started seeing Claude do this unasked for me (creating parallel Web/TUI interfaces), but it was actually building more complicated Web scaffolding, rather than it being deterministically rendered from a specification by the harness.

The “progress” should include an estimate of total time or time remaining.

For example, dd or rsync would be quite simple to enable with this.

The problem `OSC 7501` addresses would slot almost perfectly into [UAPI.15 OSC 3008](https://uapi-group.org/specifications/specs/osc_context/#met...).

It's already implemented by `systemd` and is available in Ubuntu 26.04.

I'd rather see `OSC 3008` being extended.

JdeBP
Or its specification fixed.

Something that reads 'ASCII byte range > 0x7f' in the second paragraph of its syntax description has not started well. ASCII has no codes above DEL, and allowing the C1 controls is useless and actually leads to problems of command sequences and control sequences inside command strings, since CSI, SOS, and the like are C1 controls.

The BSDs have had a version of this for many, many years. If you hit ^T on the terminal, you deliver a SIGINFO to the application you're waiting for. By default, you get the program name, what its blocked on, and info about real/user/sys time and memory use.

Starting an emacs window in the fg:

% emacs ^T load: 0.32 cmd: emacs-31.1 64938 [select] 2.89r 0.75u 0.06s 6% 122404k

Darwin also supports it
Darwin is a BSD.
Not exactly tho, Darwin is a BSD derivative
Technically true but not informative
It would be much better if we adopted SIGINFO + env variable where to respond.

This way, anyone who needs AI agent status can just send SIGINFO signal and wait for the response.

alberth
Could this be a Pull vs Push issue?

^T is a Pull

OSC7591 is a Push

What’s the difference? SIGINFO asks the program what it’s doing and displays it. Anyone is welcome to put a layer on top of that which polls (with SIGINFO) in the background and displays any changes.

As long as the signal is built, like any good interrupt code, to only do message passing instead of blocking work then there won’t be any performance issues. We’re polling between a handful of local processes that are in the order of human-computer interaction, not polling remotely in a large scale way.

I like the idea, but we already have the terminal bell. In my setup, when an agent is done or needs something, it emits a bell. Based on config, this results in a desktop notification if I’m not in the terminal, or a toast from my multiplexer if I’m in the terminal. The terminal pane gets a colored “bell” icon in its title that is cleared when I attach to it.

The total lack of mention of the terminal bell in the article is weird. I think it needs to be addressed for the protocol to be taken seriously. More granular info sounds nice, but also nice is the simplicity of the bell.

Did you read the section on "Relationship to other sequences?"

https://www.superlogical.com/rex/docs/build/program-status#r...

Also - definitely a mention of the terminal bell on https://www.superlogical.com/rex/docs/automate/shell-scripti...

  rex events -s work --json |
  jq -r 'select(.payload.event.payload.name == "bell")
         | .payload.event.payload.block_id'
The terminall bell is just the representation of ascii for 7 (decimal) or Ctrl+G. I believe all terminal do support it, although most emulators allows to make it a visual effect instead of a sound. And they usually send a notification to the desktop environment or windows manager.
Wuff, Wuff!!
Cool to see this, I've been toying around with custom notification OSCs through zellij and ghostty.

Totally going to extend this for myself with a custom key that encodes a reverse route on each hop so I can easily jump to the window/tab/pane that emitted it, or send back custom actions into a given pane like a permission approve/deny.

I've been using a poor mans version of this for decades.

My iTerm2 is configured to show activity, new-output and visual bell in the tab. On Linux I have an approximation for WezTerm.

I have a bell command that I can use in a pipeline or sequence to produce the bell on events I'm interested in. Trivial case is when a program finishes.

I have a fancy alias that can be used in a shell command sequence and which produces different sounds depending on the exit status of the preceding command in addition to sending the terminal bell.

Brings back to mind the old IBM 3270 terminal status line (everything old is new again :). Actually think this is quite a good idea.
> Actually think this is quite a good idea.

That's what I thought in the beginning. Once I read the spec to the end, it's clear to me that it's overly specific to one use-case — TUI AI agents.

E.g. `kind := permission | question | auth` doesn't make much sense anywhere outside of that use case. The list goes on...

I also found comms around it super muddy, AI agent use case is mentioned but deceivingly watered down with other use-cases.

Overall, that spec is no where close to Kitty/Kovid's level. It's super sad, since mitchellh's work is usually super high quality.

I hope the community will push back and the spec will get better.

A cli asking for a password is a pretty normal thing, I think?
hinkley
As a frequent internal tool writer, I’d say it’s a fact of life but an undesirable one. I’m always trying to avoid pausing for credentials in the middle of a run, either by doing them right at the beginning or by using some sort of durable credentials system like ssh keys.

There’s always two people at every company who refuse to set up auth automation though, so you end up handling it. They are very stubborn. Even when it trips them up in front of observers while executing an urgent task, I’ve only occasionally convinced them to agree to set up trust instead of typing a password every single time.

Which is to say, I have to support password prompts even though they drive me up the wall.

Yes, but a CLI can ask for literally anything. We'll end up adding things there and with a zoo of hard-to-support implementation of that _protocol_.

CLI can also _blank_, do we want to support it as well?

Let's say I'm upgrading a large software enterprise application. I start the upgrade process. After 5 minutes, the process determines that the upgrade will require an extra 1.5GB of storage and asks me if I would like to continue with the upgrade. After 15 minutes, I'm presented with a username / password prompt to enter credentials to retrieve a package from an external resource needed for the upgrade. After another 5 minutes, the upgrade process has detected that there are a number of derelict files detected and asks for permission to remove these files.
Isn’t that why the bell is for?
It's a product of the scope limited interface granted to agents. They get a terminal stream so everything goes into the stream. Piling on more in-band signaling is just going to become a security nightmare. It would be better to have a safe way to query process state that can be locked down as needed.
danudey
As someone who works on a lot of CLI tools at work I actually like the idea of implementing this in some of our long-running tooling, completely independent of the AI agent use case.

I actually created a separate golang library with something like this in mind: https://github.com/danudey/ansipants

The original idea I had being that CI environments, or anywhere that shows terminal output, could use a streaming ANSI parsing library to detect when a program sent a 'change window title' OSC event and then start a new collapsable section in its output. This would let programs update the actual terminal window title with its current state when running locally and update the CI interface when running in CI.

Adding in the ability to specify the program's current status and (optionally) progress could be extremely useful in CI environments as well. Imagine, for example, a long-running analysis task which uses OSC 7501 to say that it's currently running and is 75% of the way done. CI could expose that in the UI to provide useful information to the end-user without having to print a progress bar or multiple progress lines to the fake terminal it's being run in.

long-running analysis task can use osc9;4 for progress reporting

spec: https://ghostty.org/docs/vt/osc/conemu

JLO64
I just found out about this an hour ago while browsing the Pi docs. I'm really excited to use this as an alternative to the herdr pi extension as I prefer minimizing the number of extensions I have. Also, this could be great to use with a CI tracker (though I'd need one that works with Forgejo).

https://pi.dev/docs/latest/terminal-setup#program-status