forty terminals
The terminal is fine. The problem is the fortieth one — and the protocol layer that would fix it cannot describe a layer between the shell and the screen.
I have forty terminals open. If you have been running agents for more than a week, so do you. Six of them are doing something. Two are waiting on me and I do not know which two. Every tab is labelled node.
That is the problem. Not the terminal. The fortieth terminal.
There is no word for this
I went looking for the name of the thing I wanted and there is not one. “Integrated Terminal Environment” — ITE — returns nothing as a category name. Four different search formulations, zero uses. The acronym is already spoken for by Integrated Test Environment and the US Army’s Integrated Training Environment. Worse, “integrated terminal” already means something specific in software: the terminal pane inside your IDE. The exact inversion of what I am reaching for.
One name does exist, and a vendor minted it to describe its own product. Warp shipped “Warp 2.0: the Agentic Development Environment” on 24 June 2025 and stopped calling itself a terminal — what is needed, they wrote, is “a product native to the agentic workflow; one primarily designed for prompting, multi-threading, agent management, and human-agent collaboration,” as opposed to everyone else, who “bolt agents onto code editors through chat panels and bury them in CLI apps.” Warp 2.0 has four modules: Code, Agents, Terminal, Drive. Terminal is third.
When the only available name for a category was coined by one of the companies competing in it, that is not a naming problem. That is a vacuum.
What actually exists
Before proposing anything, the report. The word “terminal” is currently doing at least four separate jobs, and they get argued about as though they were one movement.
Terminal as IDE. Panes as a workspace, inline preview, blocks instead of scrollback. Warp, Wave, Zellij. Real and shipping.
Structured shell. The stream stops being bytes and becomes typed data. PowerShell has been doing this since 2006; Nushell does it now; TermKit proposed it in 2011. Twenty years of track record and low adoption outside Windows. The recurring objection in community threads is not aesthetic — it is that a non-standard shell is an implicit runtime dependency, and teams that will happily take one for an application language will not take one for a script.
The protocol layer. OSC 133 marks where a prompt starts and where output ends. The Kitty graphics protocol puts pictures in the grid. OSC 8 makes text clickable. libghostty is being carved out as “a cross-platform, minimal dependency library that exposes a C API so feature-rich, correct, and fast terminal functionality can be embedded by any application anywhere.”
The terminal as agent host. Newest strand. Agent Client Protocol gives an agent a terminal by handle — create, read output, wait for exit, kill, release — with the client owning the execution environment. The agent never holds a pty.
Warp is the first and the fourth. Nushell is the second. Ghostty is adjacent to the third and disclaims the rest — its stated goals are speed, feature completeness, native feel and a clean library core, and its own documentation makes no platform claim at all. Reading Ghostty’s popularity as demand for a richer terminal is a misread of the source.
While I am being honest about sources: there is no survey, no telemetry set, no usage study showing that developers want a richer terminal. Every instance of that claim I encountered was written by somebody selling one.
The closest thing to a count comes from Homebrew, which publishes its cask-install numbers with an exact window. In the year to 28 August 2026, out of 25,314,657 cask installs: Ghostty 366,077. iTerm2 328,000. Warp 154,552. Wave 11,999. Hyper 3,397. That is macOS only, opt-out, counting install events rather than people, inflated by reinstalls and CI, and blind to the direct downloads that both Warp and Ghostty also ship. It ranks; it does not measure a market. But it is the only non-vendor number in the entire file, and what it says is that the two most-installed terminals on the list make no ITE claim at all.
Pin one more pair up next to every star count you will ever read in a post like this one. Hyper has 44,708 GitHub stars and 3,397 installs in a year. Ghostty has 60,388 stars and 366,077.
The fifth thing
Those four are all about what one terminal can do. Mine is about what happens when there are forty.
The unit of work is the project, not the window. Sessions live inside projects and carry context — which project, which customer, what happened in the last session. Tabs are not the wrong shape for this. Tabs are the wrong idea, and tab titles are a worse idea, and I will come back to why.
For about a week I believed everybody who had built this had built it as a wrapper — a shell script over a multiplexer, or a pile of git worktrees with a dashboard bolted on.
There is certainly a lot of that. sesh and tmux-sessionizer fuzzy-find your repos and open each as a named session. Claude Squad — 8,400 stars — “manages multiple Claude Code, Codex, Gemini (and other local agents including Aider) in separate workspaces,” and it does it with tmux plus git worktrees. Conductor, Crystal, Vibe Kanban: parallel agents over worktrees, dashboard on top.
But “it is always a wrapper” is wrong, and it was the best line I had. Zellij does project layouts natively — a KDL file declaring panes and tabs, each with its own working directory, command, arguments and name — and it serialises your session by default, preserving layout, tab order and the command running in each pane, with a “Press ENTER to run…” guard so a resurrected session does not re-execute an rm -rf at you on the way back. That is inside the multiplexer, not strapped to the outside of one. And ai-agent-session-center watches every Claude Code and Codex session from a single localhost dashboard using shell hooks and a JSONL event queue, touching no multiplexer at all.
So the honest version is narrower and duller than the one I wanted. Nothing I could find combines all three of: sessions scoped to a project and a customer, memory that survives across sessions, and a layer that watches without acting. The pieces are all built. Nobody has put those three in one place.
Including the incumbent. Warp issue #9382, opened 29 April 2026 and still open, is a user asking for “workspace-style project tabs [supporting] multiple independent terminal sessions inside one top-level tab” — a coding agent in one session, a local server and some shells in the others, without splitting the project across top-level tabs. The Agentic Development Environment does not have this yet either.
The thing the protocol will not say
I assumed the answer was cultural. Terminal people are conservative, tmux is old, nobody wants to move. That answer is wrong and I am glad I checked before writing it.
tmux does not resist the semantic layer. When someone asked for OSC 133 support in 2022, the maintainer’s reply — within nine minutes — was that it had been on the todo list for ages and “if you want to have a go, that would be great :-)”. tmux tracks the sequences natively today: prompt jumping in copy mode, prompt and output positions available through capture-pane.
What tmux declines is forwarding them outward, to the terminal it is running inside. The maintainer gave the reason on 19 June 2026:
The sequences are not powerful enough to let tmux express everything it would need to — they are meant for shells, not full screen programs.
And two days earlier, concretely: if tmux writes a prompt at row 10, column 10, and you drag that pane so it is now at 15,15, there is no way for tmux to tell the outer terminal that the prompt moved. If the pane occupies only part of the window width, there is no way to say the prompt covers columns 30 to 40.
OSC 133 describes when something happened in a byte stream. It says nothing about where it sits on a screen that somebody else is laying out. A multiplexer is a compositor, and the protocol handed it nothing to recompose.
A layer between the shell and the screen is not merely unimplemented. It is unrepresentable in the vocabulary the terminal has.
I assumed that generalised — that the whole capability layer was broken the same way and for the same reason. It does not generalise. It inverts. Line the protocols up by how much cell geometry each one carries and they sort perfectly:
OSC 8 binds a URI to a range of cells. It is an attribute, like colour. tmux adopted it in release 3.4 and closed the request in a day, and unreleased 3.8 adds a link= style attribute making hyperlinks first-class in tmux’s own format layer.
The Kitty graphics protocol addresses image placements to cells. tmux is compositing it right now, in an open pull request, by splitting the screen into per-row “spans” and emitting the sub-rectangle of the image in each stripe — “we treat the image just exactly like characters on the screen. They can be scrolled up into the copy buffer, moved around on the screen in floating panes, and partially obscured.” Why that is even possible, in the author’s words: “Each of those special unicode characters carries with it which piece of which puzzle belongs on top of that character.”
Sixel is a framebuffer dump with no addressing at all. tmux has shipped it since 3.4, opt-in at build time — and deletes Sixel images before reflow. It cannot re-express where the picture goes, so it throws the picture away.
OSC 133 has no spatial extent whatsoever. Tracked internally. Forwarding refused.
The capability layer is not uniformly broken. It works exactly as far as the protocol was willing to carry coordinates, and stops dead the moment it was not. A contributor on that Kitty thread put the mechanism better than I can: “Sixel was designed to be dumped onto the terminal’s framebuffer, while Kitty intentionally decouples images from text, so combining them into a single model is difficult whatever you do.”
That ordering is mine and not the maintainer’s, and I am flagging it because it is the load-bearing argument in this piece and it is an argument. Every rung is checkable in about a minute. The ladder is a claim. (And the Kitty pull request is open, with unresolved scroll races and cursor desync in its own thread. tmux does not support Kitty graphics today. It is trying to.)
Worth noting how tmux resolved the OSC 133 request instead. The passthrough issue was closed as completed on 6 August 2026, not by forwarding anything but by implementing command-level state natively: pane_command_running, pane_command_duration, a pane-command-finished hook, set-hook -TB monitors. That is in master. The latest release is 3.7c, from 17 August 2026, and it is not in that. So “tell me which of my forty panes is still working” is partly solved in the incumbent substrate already — for anyone willing to build from source.
Nobody owns the spec
Here is what every one of those terminals is implementing.
A file called semantic-prompts.md, start date 11 May 2019, in a proposals/ directory in one person’s personal namespace repo on freedesktop’s GitLab. Per Bothner, who wrote DomTerm — an implementer, not a neutral body. The document still carries unresolved inline notes marked **Issue**:. Its own provenance line says it extends the protocol first implemented by FinalTerm, and FinalTerm is archived, self-described “NO LONGER MAINTAINED,” last pushed 3 September 2015.
Two unrelated terminals point at that file as the reference: Contour’s documentation, and WezTerm’s own shell-integration docs, which link it by URL and by name. Not a copy of the spec, not a mirror in a standards namespace — that file, in that person’s personal repo. I read it on 28 August 2026. The URL now serves a bot-challenge page instead of the document, which is its own small comment on the state of the foundations.
The closest thing to an authority is terminfo.dev, which says plainly that it is a community compatibility matrix inspired by Web Baseline, not a standards body. There are at least three mutually incompatible ways to put a picture in a terminal. There is no successor to VT100. There is terminfo, $TERM, and vibes.
Invented by a project that died in 2015. Extended in 2019 by a single interested implementer in a personal repo. Still carrying open design questions. Universally adopted.
The graveyard, and the one thing that crawled out
In May 2011 Steven Wittens announced TermKit and asked why he was telling pixels to draw him a computer terminal from the eighties. His design was right: streams prefixed with MIME-like headers, and the principle underneath it — “by separating the ‘data’ part from the ‘human’ part. Then we can use messy text for humans, and pure data for the machines.”
Last commit, December 2011. README still reading “Nothing works yet.” By April 2012 a stranger on a thread was writing that it looked like the author had abandoned it. I could not find Wittens’ own account of why, and the confident explanations floating around search results do not appear in anything he wrote, so I am not going to repeat them.
FinalTerm, Extraterm, DomTerm, XMLterm, GraphTerm, TermKit. I wanted to call that a graveyard. It is not one, and checking took a single command.
Two of the six are alive in 2026. Extraterm was last pushed in June, DomTerm in August — by Per Bothner, the man who wrote the proposal. Fig, from the generation after, was not abandoned either; it was bought, and withfig/autocomplete now carries the line “Amazon Q Developer CLI, formerly known as Fig, is open source.” Only two of them actually ended: TermKit’s last commit was 15 December 2011, and FinalTerm was archived in September 2015.
Died, absorbed, ignored. Three outcomes, and the third is by far the most common one. DomTerm has 395 stars after eleven years of continuous maintenance. The ambitious terminals mostly did not die. They stayed small.
And out of all of them, exactly one thing propagated to every terminal you can install today. An escape sequence.
The hypothesis, and I will hold it loosely: the terminal does not adopt environments. It adopts sequences. Small sample, and survivorship reasoning is precisely the kind that flatters itself, and Warp is a live counter-case still running. But it is the only pattern in the record, and it has a mechanism — a sequence degrades. A dumb terminal that does not understand OSC 133 ignores it and keeps working. An environment does not degrade. You are in it or you are not.
Worth noticing that Acme went the other direction entirely. Rob Pike’s answer to integration in 1994 was to make everything plainer — a hybrid of window system, shell and editor where any text anywhere may be a command. It did not spread either, but it is the road not taken that actually worked.
What it should have
Everything above this line is sourced. Everything below it is argument. I am proposing a class of tool that does not exist, and the honest version of that is a list of requirements, not a product.
First, the question the whole piece turns on, answered badly. Should this exist — does anybody besides me want it? My evidence is two GitHub issues and an inference. Three passes turned up nothing better — no survey, no study, no telemetry. Two issues and an inference is not demand, and I am not going to dress it up as one.
Projects as the container. Sessions as the unit. Not windows, not tabs. A session belongs to a project and carries its context forward — what this is, whose it is, what happened last time.
A state channel with an owner. The terminal title is a single mutable string with no ownership protocol, written concurrently by the agent, the shell, the multiplexer and the editor. That is my inference, but the symptoms are all over public trackers: titles rewritten every 960 milliseconds, a busy glyph pinned on under every multiplexer, titles blanked on exit and corrupting tmux-resurrect saves, editor tab titles that never refresh, and no way at all to express “this one is waiting for you.” Four processes writing one string is not a display bug. It is a missing protocol.
Geometry in the protocol. Not a nice-to-have. The sort order above says it is the entire admission criterion: OSC 8 carries a cell range and was adopted in a release; OSC 133 carries no position and gets tracked internally and forwarded nowhere. The tmux maintainer’s objection is not an opinion to route around. It is the specification defect, and any proposal that does not fix it produces one more thing that cannot describe itself to the layer above.
Capability negotiation. The terminal should be able to say what it can do and the application should be able to ask. The browser has this. The terminal has $TERM.
Dual-channel output. TermKit’s insight, fifteen years early. One command, two products: a render for the human, a payload for the machine. What changed since 2011 is not the rendering. It is that the machine is now a real consumer with real requirements, sitting in the other half of your forty terminals.
Graceful degradation to a dumb terminal. Non-negotiable, and the requirement that kills most proposals — including, arguably, TermKit.
An observer that does not act. A model layer that watches sessions, summarises them, plans against them, answers “what is the state of this project” — and touches nothing.
I thought this was the new part. It is not, and I am glad I checked twice, because the first search came back empty and the second one found it immediately. In March 2026 Mateusz Jakubczak published a working version: a hook reads Claude Code session transcripts, a model writes two or three sentences on what each agent is doing, and it renders into a two-line tmux status bar. It summarises. It runs nothing. The implementation is in the post. Five months before I sat down to write this.
What is left is smaller, and I think still real. His version is per-session, status-bar-sized, and reads one agent’s transcript format. The novelty was never the watching. It is the remembering — scoped to a project and a customer, carried across sessions, so that “what is the state of this” has an answer longer than the pane in front of you.
Adjacent but not the same thing: FOCAL does multi-agent filter, plan and log to produce task-organised session summaries, but over desktop screenshots rather than terminal sessions. TraceLab published around 4,300 real coding-agent sessions and 350,000 model steps, and characterises the workload as long autonomous loops, long contexts with short outputs, and human-paced gaps. The shape of the work is documented. The thing that remembers it across sessions is not.
The part I actually believe
The record does not quite say the product form dies. It says something worse for anyone hoping to build one: the product form stays small. TermKit stopped, FinalTerm was archived, Fig got bought, and Extraterm and DomTerm are a decade in and still counted in hundreds. The thing that made it into every terminal you can install was an escape sequence a machine from 1978 can safely throw away.
And the sort order on the capability layer tells you which sequences get in. Carry coordinates and you get composited, expensively, by people who did not ask for the work. Refuse to carry them and you get tracked internally and forwarded nowhere.
So if this class of tool is going to exist, it should not arrive as an environment. It should arrive as sequences — geometry, ownership, session identity — that a dumb terminal ignores and a smart one composes. Name it afterwards.
The environments stay small. The sequences travel.