Every terminal shell is quietly interrogating whatever's attached to it. Cursor position, terminal theme, device attributes — a shell fires off an ANSI escape sequence, waits, and expects exactly one reply. Answer twice and a build script chokes on garbage in its input stream. Answer never and a Windows shell spawn can hang outright. Influxx hides terminal tabs to save memory, which means the pane that would normally field these questions frequently isn't even mounted — so something else has to answer, correctly, once, every time.
The Query Nobody Notices Until It Breaks
Terminal query escape sequences are one of the more invisible parts of how a shell and its host cooperate. A cursor-position request lets a prompt figure out how much of the line it can safely redraw. A device-attributes request lets a shell or TUI figure out what kind of terminal it's actually talking to, so it can decide whether to use certain rendering tricks. A background-color or theme query lets tools like `fzf` or a status bar pick text colors that won't disappear against a dark or light background. These aren't exotic edge cases — any reasonably modern CLI tool sends at least one of them during startup, and interactive shells send them continuously.
The protocol assumption baked into all of this is simple and rigid: one question, one answer, from whatever process is sitting at the other end of the pseudo-terminal. Nothing in the escape-sequence protocol accounts for "the terminal that's supposed to answer this doesn't currently exist as a rendered object." That's a UI-layer problem, and it's the one Influxx has to solve every time it tears down a tab to save memory.
Why Influxx Hides Tabs in the First Place
Influxx runs real git worktrees per agent, and a single project can easily have a dozen or more terminal tabs open across different agents and branches at once. Keeping every one of those panes fully mounted and rendering in the DOM all the time is wasteful — most of them aren't visible, and the user isn't looking at their output right now. So Influxx unmounts the renderer-side view for tabs that aren't currently in focus, while the underlying PTY session keeps running (that's the same background daemon that keeps sessions alive across app restarts doing its job).
The problem is that the shell inside that PTY doesn't know or care whether its tab is visible. It keeps sending cursor-position and device-attributes queries on whatever schedule the program running in it decides on. Somebody has to answer those queries, and it has to be exactly one somebody — not the daemon, not two different processes racing each other, and not nobody.
The Contract: Whoever Writes the Chunk, Answers the Query
Influxx's rule for who answers is deceptively simple to state and considerably harder to get right in practice: the party that actually writes a given chunk of terminal output into a live terminal is the party responsible for answering any query embedded in it. That single invariant covers every delivery path in the system:
- Visible panes keep authority. If a renderer tab is mounted and actively displaying output, or a remote view (mobile, web, remote desktop) is subscribed and receiving it live, that view answers the query itself. It's the terminal emulator instance actually rendering the bytes, so it's the one with a legitimate answer.
- Hidden-delivery-gated chunks get a headless answer. When a tab is hidden and its output is dropped by Influxx's hidden-delivery gating rather than sent to a mounted view, a headless terminal model in the main process answers the query exactly once, on the hidden pane's behalf.
- Replayed, seeded, or snapshot bytes get no answer at all. When Influxx replays scrollback, seeds a buffer from a saved snapshot, or otherwise pushes bytes that aren't a live delivery, nothing answers. Those bytes already happened; answering them now would be answering a question the shell isn't actually waiting on anymore.
That third rule is easy to underestimate but it's what keeps replay and snapshot restoration from turning into a source of duplicate or stale replies. A query embedded in scrollback isn't a live question — the shell that asked it either already got an answer the first time around, or it's not actually blocked waiting for anything from this replay pass.
"The instinct when you first look at this is to just always answer, because an unanswered query feels riskier than a wrong one. It's backwards. A wrong or duplicate answer corrupts whatever the shell does next, sometimes visibly and sometimes not until three commands later when someone's `git log` output looks like it has stray characters in it. We had to be much stricter about who's allowed to reply than felt natural at first."
— Priya Nakamura, Senior Engineer, Terminal Platform at ETAPX
Why the Daemon Is Permanently Banned From Answering
One detail in that contract is non-negotiable and isn't gated behind any setting: the background daemon's terminal emulator never answers a query, under any configuration, ever. This isn't a default that a power user can flip — it's a hard rule enforced by an automated regression test that runs specifically to catch a regression here.
The reason is a real bug from Influxx's own history. Before this rule existed, the daemon's terminal emulator would sometimes answer a background-color query with a hardcoded default value — and it would do it ahead of the actual renderer, which was still starting up or hadn't attached yet. The shell got an answer, just the wrong one, sourced from a process that had no idea what theme the user was actually running. By the time the renderer came up and tried to answer the same query correctly, the shell had already consumed a reply and moved on, so the renderer's more accurate answer either arrived too late to matter or, worse, became a second reply to a question that had already been answered once.
That's the double-reply failure mode in miniature, and it's why the fix wasn't "make the daemon smarter about themes." It was "the daemon doesn't get an opinion on this, period." The daemon's job is keeping the PTY session alive across app restarts and SSH disconnects — it has no business rendering terminal state, and giving it default-value answers to hand out was a design mistake that the current architecture closes permanently.
A Headless Emulator Built to Match the Real One
For the hidden-pane case — the one this whole problem centers on — Influxx runs a second terminal emulator instance in the main process, headless, with no DOM to render into. This is the thing that answers queries for chunks dropped by hidden-delivery gating, and it's the piece that makes the once-and-only-once contract actually hold for tabs that aren't mounted.
The trick that makes its answers trustworthy is deliberately unglamorous: it runs the exact same terminal-emulation library version, with equivalent options, as the visible renderer pane uses. For a class of queries that are purely a function of terminal state rather than of anything visual — cursor position, device attributes, terminal-mode reports — that means the headless emulator's replies are structurally identical to what the renderer would have said, by construction, not by coincidence. There's no separate reimplementation to drift out of sync with the real one over time; it's the same emulation core processing the same byte stream, just without a screen attached.
The One Thing the Headless Core Can't Answer
Theme and palette queries are the exception, and they're an instructive one. A headless terminal emulator core has no theme service — there's no concept of "what color is the background" in a process that never renders pixels. So those queries route through a separate handler, fed from a terminal-view-attributes snapshot that the renderer pushes over to the main process.
Crucially, that handler stays silent until the very first snapshot push arrives. It does not fall back to a default color and answer early. That silence is a direct, deliberate echo of the daemon bug: the whole reason the old bug happened was a component answering with a plausible-looking default before it actually knew the real value. The theme handler is built to refuse to make that same mistake — no answer is safer than a guessed one.
The Windows Problem: A Blocking Wait, Not Just a Cosmetic Glitch
On macOS and Linux, an unanswered query is annoying — a tool might sit waiting a beat longer than it should, or fall back to conservative defaults. On Windows it can be worse. Windows' terminal subsystem, ConPTY, actually blocks waiting for a device-attributes reply starting in version 1.22 and later. That's not a UI stall; that's the pseudo-terminal machinery itself refusing to proceed until it gets an answer.
That turns a missing reply into a real hang risk at the exact moment a hidden pane is spawning — a shell that never gets its device-attributes answer can leave the whole PTY spawn stuck. The fix has to happen before the race can even occur, which is why Influxx marks a PTY as "hidden at spawn" before its very first byte is written. There's no window where the PTY exists, sends its opening query, and only then discovers whether anyone's watching — the hidden/visible status is decided and attached before spawn, so the headless responder is already positioned to answer from byte one.
Remote Viewers Take Priority, With One Bounded Exception
Influxx's mobile and web companions, along with remote-desktop views, can subscribe to a terminal session live. When one of those remote subscribers is attached, it owns the replies for that terminal, and the desktop app goes quiet — it doesn't also answer, even if the desktop pane happens to be hidden and would otherwise route through the headless responder.
The one documented exception is a driver handoff: the brief moment where control of a session is transferring from the desktop app to a mobile client (or vice versa). During that handoff window there's a bounded period where a double reply is possible — it's a known, deliberately scoped trade-off rather than an accidental gap, and it only exists during the handoff itself, not during normal remote viewing.
"I run six or seven agents at once on a laptop with 16 gigs of RAM, most of them in tabs I've got backgrounded because I'm only actively watching one or two. Before I'd occasionally get a shell that looked frozen for a second when I switched into it, or weird junk characters at the start of a prompt. I haven't seen either of those in months now — I genuinely didn't know this was a solved problem until I read about the mechanism."
— Marcus Webb, DevOps lead at a logistics platform, Influxx user
Shipped, Behind a Kill Switch
This isn't a proposal or a design doc — it's shipped code, running by default. The implementation is split cleanly into a terminal-model-query-authority module, which enforces the once-and-only-once contract and decides which party gets to answer a given chunk, and a terminal-view-attribute responder, which handles the theme and palette side fed by renderer-pushed snapshots. It ships behind a kill switch that defaults on, which is the standard pattern for anything touching core terminal correctness at Influxx — the capability is live for everyone, with an escape hatch available if something unexpected turns up in the field.
This query-answering work is one phase of a six-phase terminal architecture effort. It builds directly on the hidden-delivery gating that decides which output chunks get dropped for unmounted tabs in the first place, and it's an instance of a broader rule the team calls "side-effect authority" — a general principle about which component is allowed to originate a given terminal side effect, applied here specifically to query replies.
"People notice the visible parts of Influxx — the worktrees, the agent tabs, the mobile pairing. Nobody notices when a cursor-position query gets answered correctly, and that's exactly the point. The moment a developer has to think about which process replied to an escape sequence, we've already failed. This is the kind of correctness work that only shows up in what doesn't happen: no hangs, no garbled prompts, no double replies."
— Sofia Reyes, VP of Engineering at ETAPX
Frequently Asked Questions
Does this affect how fast hidden tabs respond when I switch back to them?
No — the headless responder only answers protocol-level queries embedded in output, not the tab's actual rendering. The visible content is drawn fresh from the terminal's state the moment the tab is remounted, independent of query handling.
Can I turn this off if I want the old behavior?
The feature ships behind a kill switch that defaults on. The one part that isn't optional is the daemon's permanent ban on answering queries — that's enforced regardless of the switch, since it closes a real historical bug.
What happens if two remote clients are watching the same session at once?
The documented priority model gives remote subscribers ownership of replies over the desktop app; the only known window where a double reply can occur is during a desktop-to-mobile driver handoff, which is bounded and intentional rather than an open-ended race condition.
Why can't the headless emulator just answer theme queries the way it answers cursor-position queries?
Because it has no theme service — it's a headless instance of the same terminal-emulation library the renderer uses, but it never renders pixels, so it has no concept of what background color is actually on screen. Theme queries wait for a renderer-pushed snapshot instead.
Is this specific to macOS, or does it matter more on other platforms?
The core answer-ownership contract applies everywhere, but the stakes are highest on Windows, where ConPTY 1.22+ actually blocks a PTY spawn while waiting for a device-attributes reply — an unanswered query there risks a hang, not just a rendering glitch.
Does replaying scrollback or restoring a saved session ever trigger duplicate replies?
No — replayed, seeded, and snapshot-restored bytes are explicitly excluded from the answering contract. Nothing replies to a query embedded in bytes that weren't delivered live, which avoids re-answering a question the shell already got a response to the first time.
Is this the whole terminal reliability story, or is there more coming?
This query-answering mechanism is one phase of a larger six-phase terminal architecture effort, built on top of the hidden-delivery gating that governs which output gets dropped for unmounted tabs, and following a broader side-effect authority rule for terminal behavior generally.
The interesting part of this design isn't the headless emulator or the Windows fix in isolation — it's that "who answers" turned out to need the same rigor as "what gets displayed." A terminal that looks idle from a hidden tab is still a live process asking real questions, and getting that answer wrong once, in either direction, is enough to hang a shell or corrupt its next line of output.

