Skip to content

July 15, 2026 · ai-agents · product · essay

We built an interrupt inbox for AI agents — here's why chat transcripts don't scale past two agents

Here’s a scene we lived every day for six months. Three Claude Code sessions running in three git worktrees. One is refactoring auth. One is chewing through a test migration. One is doing something in a second project entirely. You step away to make coffee, come back, and start the ritual: cmd-tab, scroll, read. Cmd-tab, scroll, read. Two of them have been blocked on a permission prompt for eleven minutes. The third finished and has been sitting on a diff, waiting for a human who was reading the other two transcripts.

We were the bottleneck. Not because we were slow — because the interface made us poll.

Chat is the right UI for one agent

Let’s be fair to the transcript. A chat window is a genuinely good interface for a single agent session. It’s a full-fidelity view: you see the reasoning, the tool calls, the wrong turns. Anthropic’s Remote Control for Claude Code is a good product for exactly this reason — it takes that one session and puts the whole thing in your pocket. You can read along, steer, answer. For one agent, a window into the session is precisely what you want.

The problem is not chat. The problem is chat times N.

The N-transcript problem

Run three to five agents — worktrees, subagents, a couple of projects — and the transcript model inverts on you. Each transcript is a window you have to look through to learn whether anything behind it needs you. Most of the time the answer is no. The agent is grinding through tokens and doing fine. But you can’t know that without looking, so you look. Again. And again.

That’s polling. You’re a human while loop doing check(agent_1); check(agent_2); check(agent_3); sleep(anxiety).

And polling has the failure mode polling always has: you either poll too often and burn your attention on sessions that don’t need you, or you poll too rarely and an agent sits blocked for twenty minutes on a yes/no question. Transcripts are pull. What a fleet needs is push.

What actually blocks throughput

Here’s the observation that changed our design. Watch what actually stops an agent fleet, and it’s almost never a lack of information flowing to the human. It’s a small set of pending decisions:

  • “Can I run rm -rf node_modules && npm ci?”
  • “The API returns 403 on staging — should I mock it or wait?”
  • “Done. 14 files changed, +212/−87. Ship it?”

Each one is small. Each one is structured — it has a kind, a subject, a finite set of sane responses. And each one is answerable in seconds, if it arrives with enough context to answer it. The agent doesn’t need you to read its transcript. It needs a verdict. Everything else in the transcript is logs.

Once you see it that way, the design question stops being “how do we stream N sessions to a phone?” and becomes “how do we route decisions to a human and route verdicts back?”

The right primitive is an interrupt

Operating systems solved this problem decades ago, in silicon. Early systems polled devices: is the disk done yet? Is the keyboard pressed yet? It wasted cycles and it added latency, so hardware grew interrupt lines. The device signals when it needs service, with a vector that says what kind of service, and the CPU handles it and returns to what it was doing.

An agent blocked on a permission prompt is a process blocked on I/O. It has issued a syscall to the slowest peripheral in the system — you — and it cannot proceed until the syscall returns. You are the scheduler for the fleet. A scheduler that discovers blocked processes by reading every process’s stdout is not a scheduler. It’s tail -f with legs.

The ops version of the same argument: nobody runs on-call by watching log streams from every service. You run on-call with alerts — typed, prioritized, actionable, routed to a pager. Logs are for when you’re already investigating. The transcript is the log. What was missing was the pager.

So that’s what we built. Vyber is an interrupt inbox for coding agents: an iPhone app plus a Mac companion. Your agents raise interrupts; your phone catches them; your verdict resumes the agent. The transcript stays on your Mac, where it belongs.

Anatomy of an interrupt you can resolve in ten seconds

“Push a notification” is not the design. Anyone can forward a bell. The bar we set: an interrupt must be resolvable in under ten seconds, from a lock screen, without opening a terminal. That forces five properties:

  1. A kind. Permission, question, review, or stuck. You triage differently depending on which — a permission prompt from a trusted repo is a half-second glance; a finished diff deserves a minute.
  2. A context card. What the agent wants and why — the exact command it’s asking to run, the question in its own words, the diff summary with files and line counts. Enough to decide, no more.
  3. One-tap actions. Approve. Deny. Reply. If resolving an interrupt requires typing a paragraph, we’ve failed; typing should be the escape hatch, not the path.
  4. A queue, ranked. Five agents can interrupt at once. You should see the blocking-longest and highest-stakes items first, not a chronological pile. That’s the fleet board: every agent, its state, its pending interrupt, at a glance. Live Activities keep the count on your Dynamic Island so you don’t even unlock for the quiet stretches.
  5. Instant resume. The verdict has to hit the agent immediately. An interrupt inbox with a slow return path is just email.

Reviews get their own treatment — mobile diff review that’s actually readable on a phone — and we track token burn per agent, because “should I let this thing keep going?” is also a decision, and it needs the meter in view.

Under the hood, this rides on Claude Code’s hooks system today — hooks fire on permission requests and lifecycle events, the companion turns them into interrupts, your response flows back and the session resumes. Adapters for Codex and Gemini CLI are on the roadmap; the interrupt shape doesn’t care which agent raised it.

What we deliberately did not build

No terminal emulation. No raw token streaming to your phone. No SSH.

This wasn’t a shortcut — it’s the position. Syncing state changes is a fundamentally better deal than syncing streams. A decision is a few kilobytes; a session is millions of tokens you were never going to read on a train. It’s cheaper on battery and bandwidth. It’s more private: your code stays on your Mac, and only the diffs you explicitly open for review ever sync, over TLS. And it matches the actual job. The job on your phone is not “operate a terminal with your thumbs.” It’s “unblock the fleet.”

The pairing reflects the same bias: npm i -g vyber-companion, vyber connect, scan a QR code. The companion makes outbound-only connections. No SSH, no inbound ports, nothing listening on your Mac for the internet to find.

The honest limits

Interrupts don’t replace deep sessions. When you’re at your desk doing real work with an agent — reading its reasoning, course-correcting mid-task — the transcript is the right tool and we don’t pretend otherwise. Vyber is for the other hours: lunch, the commute, the school pickup, the times your agents are working and you aren’t watching.

And “stuck” detection is heuristic. Permission prompts and questions are explicit — the hooks hand them to us. But an agent that’s confidently looping on a bad approach looks, from the outside, a lot like an agent that’s thinking. We catch a decent share with timing and repetition signals. We miss some. We’ll say so when we do.

The bet

For one agent, a window. For a fleet, an inbox. That’s the whole thesis. If your agents already outnumber your monitors, we think you’ll recognize the problem in about four seconds.

Waitlist is open at vybercode.net.