A Terminal Protocol for Program Status (OSC 7501)

27 points by lalitm a day ago on lobsters | 22 comments

tstack | 22 hours ago

no JSON

I find this really frustrating.

There's always going to be new escape sequences on the horizon. Each one having their own custom serialization format is just going to slow down adoption and be a source of bugs. Using an established serialization format that just works and is readily available is not an unreasonable ask. It doesn't have to be JSON. But, at this point, it has basically won. Every single example program mentioned in the spec is already dealing with JSON. Every shell environment that has base64 most likely has jq. What is supposedly being saved by not using it and instead making tool authors do something custom? It just adds more stops in integration hell.

mitchellh | 21 hours ago

I can explain (I wrote the spec).

I've had the opportunity to implement many terminal specs over the past few years... in fact, almost all of them! The format here was chosen explicitly because it is very very similar to the Kitty protocols, which many applications already implement in various forms. So it should be familiar. I can't think of a single terminal spec off the top of my head that uses JSON in any form. For the terminal side (Ghostty), I was able to go so far as to reuse the helpers we have for our Kitty protocols.

I've also had the opportunity to implement many terminal specs from the application side, though not as many (since the number in practical use is a small subset over the number of historical specs). The key/value format is printf friendly, and in most cases with this spec you'll just use printf.

So, to sum it up simply: it is very familiar and aligns better with terminal norms. At least, modern ones.

tstack | 17 hours ago

I've had the opportunity to implement many terminal specs over the past few years...

And, I have spent much time running into bugs in terminal libraries and having to fix/workaround them. I recently had to debug an issue with tmux's palette handling. I am also frustrated by how long it takes to interrogate the terminal on startup. Having to individually ask for each color/capability/whatever is really slow and a lot of processing. What this all has in common is the overly complex protocol between the app and the terminal.

uses JSON in any form

I bring up JSON because of its ubiquity and it is plenty performant in this day and age. Having a well-defined and well-implemented serialization format makes everything else easier. Terminal escape-sequence serialization is a nightmare of everyone going their own way and custom implementations. For example, you use colons to separate key/value pairs and iTerm uses semi-colons. If we could move toward using OSC blah; /ST for framing and then putting some sane serialization format in-between, that would address a few of the problems I run into. Want to find out the terminal's capabilities? Send one request and get a big blob of hierarchical data in response. That would be faster and simpler all around.

The key/value format is printf friendly

No, it isn't. From your spec, the id parameter has a restricted character set. And, from the examples, there are IDs like us-west and eu-west. Those IDs are getting plumbed down from other parts of the program and it is highly likely people will do exactly as you said and just pass it directly to printf without scrubbing it first. It's a design that sets people up to fail. But... if it was just JSON in there, most folks would just do JSON.stringify() and it would never be an issue.

fuzzypixelz | 14 hours ago

I can't think of a single terminal spec off the top of my head that uses JSON in any form

Not a proper spec indeed, but kitty remote control uses DCS ESC P @ kitty-cmd <json> ESC \ in requests and responses. I understand that this is not meant to be widely implemented and is specific to kitty. But it shows that JSON has its place in this particular case, seemingly because responses such as window lists are large nested objects.

spc476 | 4 hours ago

But, at this point, [JSON] has basically won.

Twenty years ago, XML won. XML was everywhere. I wouldn't be surprised if twenty years from now, something else has replaced JSON as a serialization format because of its annoying aspects.

kolja | 14 hours ago

Speaking as someone who basically lives in a terminal, I'm not sure if I'm a fan of this "browserification" of terminals. There are already ways to interact with a desktop session, and placing too much functionality in the terminal could lead to fewer neat ideas of what is possible by, you know, executing programs in it.

If I want to direct my attention to something, I'm very happy with choosing between a notify-send, spd-say or curl ntfy.shor whatever. Just add a call this to "call" me option to your elevenhundredth agent harness if you so require.

mitchellh | 8 hours ago

I think here we'd have philosophical differences.

I've gone on record many times actually praising browsers as a model terminals should strive for (but, explicitly, at a much smaller surface area). I think browsers have gone too far on the spectrum towards OVER-THE-TOP application platform and terminals have gone too far on the spectrum towards STAGNANT application platform.

My explicit goal with my terminal projects from the beginning has been to push that forward. I think my original talk I ever gave on Ghostty 3 years ago I said something like: browsers ship hundreds of features per year, I'd like terminals to ship like 10.

Of course, I'm sure some people will disagree. And that's fine, stay away from my projects and use something like xterm (which is fantastic and is our ground truth for historical specs).

kolja | 7 hours ago

Sure, to each their own. I'm also not criticizing your work, I'm just saying "I don't want this."

I think browsers suffer because their features are not user-driven, and competition is very hard because of the huge surface area that needs to be implemented. I don't want terminals to suffer the same fate, or go down a heavily feature-fragmented route. They are by design meant to interact with an environment where this type of feature coverage can be implemented by combining tools (think UNIX philosophy), defining "the one true way" in the terminal is antithetical to that.

Just look at the many "this only works in Chrome" sites. That is not the path we should go down here.

I'd like terminals to ship like 10.

Speaking personally: please don't. But if you insist, I think better a11y would actually benefit a good number of humans significantly.

mitchellh | 5 hours ago

I have another comment on here about a11y... please see my comments for that full context. EDIT: Here it is https://lobste.rs/s/ifbdw1/text_mode_lie_why_modern_tuis_are#c_awixrd

The best way to fix a11y is to ship MORE terminal specifications that are higher level. Right now one of the reasons a11y is so bad/hard in terminals is because a grid of opaque non-semantic cells is very difficult or impossible to reliably map to the semantic needs of a11y tooling.

If we can ship more specifications that help elevate semantic state -- such as program status! -- but also things like semantic prompts (OSC133, not my spec), hyperlinks (OSC8, not my spec), progress (OSC9;4, not my spec), buttons, designated input areas, etc. Then we can start clearly mapping this to a11y state.

Background on this one: I spent a day (just one day, but a full one at least) with the UW HCI lab that was doing a project on terminal a11y and we were able to brainstorm a lot of the shortcomings here based mostly on their far more experienced background. They were experts on a11y technologies and I was the terminal expert.

linkdd | 10 hours ago

Isn't that why we have both stdout and stderr ?

pta2002 | 7 hours ago

Not really, consider the use case of a TUI-ish application showing some progress bar. Having both stdout and stderr doesn't solve the use case of wanting the terminal to know when it's done. (in fact using both only makes the problem worse for the user by garbling the text!)

mitchellh | 4 hours ago

Ignoring the fact stdout/stderr are already too widely used to force an in-band protocol on top of them, also consider a TUI-ish application that itself spawns 4 other applications that themselves have their own concept of progress. (Directed at linkdd, but piggybacking on agreeing with parents comment)

geocar | 16 hours ago

This looks like almost the same thing as iTerm's status notification.

That's more low level, STATUS is for example useful if output is hung and the user wants to see what is happening. This is for if the user isn't looking at the particular terminal but the title/tab/notification wants to reflect an overall status.

thisalex | 12 hours ago

so, kinda a different route to the same info?

Why couldn't the terminal just run the termios STATUS and use that to update the title/tab/notification? Linux doesn't completely support STATUS, but it does exist. I'm not sure about other platforms.

ianloic | 5 hours ago

How is the done (results user hasn't seen ) state supposed to work? Do terminals these days send a sequence to indicate that the user has brought the terminal into the foreground/switched to the tab/etc?

tstack | 4 hours ago

Do terminals these days send a sequence to indicate that the user has brought the terminal into the foreground/switched to the tab/etc?

Focus in/out reporting has been around for almost 20 years.

panekj | 15 hours ago

The spec mentions this explicitly:

Existing sequences cover only slices of this. OSC 9;4 progress can say busy or not busy, but not that a program is waiting on the user or what it is working on.

Nice!

For the agent usecase, I didn't want to use one of the tabbed harnesses, and so resorted to writing an agent harness plugin to infer this status, and then route that status from my server to my laptop, and if my agent session name and niri workspace names match, then the notification takes me to the right workspace.

This is a gross hack that I'd prefer to just have my agent harness and terminal do out the box.