Inyon lets me watch, answer and steer the coding agents running in tmux on all my machines, from my phone or any browser. It works with Claude Code, Codex, Gemini CLI, OpenCode, GitHub Copilot and Antigravity, and it's open source, at version 0.17.3 after 28 releases.

Inyon's overview on a desktop browser, a tablet and a phone: agent sessions grouped by machine, a Codex permission prompt with Yes, Always and No buttons, and the plan limits
The overview on a desktop, a tablet and a phone. The sessions are a demo world, not my machines.

What it is

A remote control for agents you already run. Each agent keeps working in its tmux pane on its own machine. Inyon reads what it's doing and shows it as a chat, with the model, context, cost and plan limits beside it. When an agent asks something, the answers arrive as buttons.

Nothing changes at the keyboard. I can walk away from the laptop, answer from my phone, and sit back down to the same terminal.

A recording of the desktop overview: a Codex session asks to run bun test, the Yes button is pressed, and the session goes back to work
Answering a permission prompt from the overview, without opening the session

Why I built it

I run agents on a laptop, a home server and a company server, and each is signed in to a different account. On the company machine I only have the CLI. The built-in remote features follow one account at a time, so moving between machines meant moving between accounts.

Inyon never signs in to anything. It drives the CLI that's already running, so every machine keeps its own account, subscription or API key.

What I built

I designed and built all of it alone: the hub, the web app, the Android app and the inyon program that runs on each computer.

  • The hub (Bun, TypeScript) reads tmux through a read-only control client, plus each agent's own records: Claude Code and Codex session files, Gemini CLI's chat recordings, Copilot's event logs, Antigravity's transcripts and OpenCode's local server. Answers go back with tmux send-keys, exactly as if I'd typed them.

  • The app (React, Vite) shows each session as a chat with tool calls, diffs, plans and to-dos, and the real terminal one tap away. Inside a session it takes on that agent's colours and reply font; everywhere else it stays ink on silver.

  • The Android app (Capacitor with Kotlin plugins) runs the same core on the phone, so the phone is its own hub. It can also reach a bare server over SSH through ConnectBot's sshlib.

  • inyon is one compiled binary for Linux, macOS and Windows (through psmux). The install script checks it against the release's SHA256SUMS before it runs.

The phone or browser talks to one hub over HTTPS. The hub reads its own machine directly, laptops dial out to it by running inyon, and servers are reached over SSH. The Android app can do the same without a hub.
One hub, and each machine reached its own way: directly, by dialling out, or over SSH

What was hard

Agents don't publish their questions. Each one draws its prompts differently, and the layout shifts between versions. So the hub reads the pane's screen with a parser per agent, tested against fixtures captured from real sessions. I wanted hooks for every agent, but Codex runs its hooks inside a background daemon where TMUX_PANE points at the wrong pane, so Codex stays on screen reading.

A Codex prompt in a tmux pane with three numbered answers is captured by the hub, turned into a Needs-you card with Yes, Always and No buttons, and the tap goes back to the pane as tmux send-keys
The question on the pane's screen becomes buttons, and the tap is typed back into the pane

A laptop sits behind NAT, and I didn't want to host a server for anyone. inyon opens a free Cloudflare quick tunnel, signs its current address with its own key and publishes it with pkarr. The phone checks that signature, then the two run a Noise IK handshake, so the tunnel only ever carries ciphertext. The trade-off is that quick tunnels come with no uptime promise. On Tailscale, NetBird, ZeroTier or WireGuard, the Android app races that address against the tunnel and keeps whichever answers first.

The computer running inyon publishes a signed pkarr record of its address, the phone checks it after scanning the QR code, connects through a Cloudflare quick tunnel, and the two finish a Noise IK handshake with X25519 and ChaCha20-Poly1305
Pairing: a signed address, a free tunnel, and a handshake the tunnel can't read

Notifications had the same constraint. Browsers get standard Web Push: each computer encrypts the alert itself (RFC 8291) and sends it straight to the browser's push service. The Android app has no Firebase, so it keeps a small ongoing notification to stay connected. A fully closed Android app gets no alerts yet. That's the price of not running a push server.

Where it landed

Inyon is public on GitHub under the MIT licence. Every release ships checked binaries for five platforms and an Android APK, and the downloads page is at inyon.abhashchakraborty.tech.

agent CLIs
6
releases
27
commits
313
tests
1,093
Three phones: the overview with a prompt waiting, a Claude Code session as a chat with a to-do list, and the machines list with an offline server
Overview, a session and the machines list on a phone
The terminal view in dark mode: Claude Code fixing a flaky checkout test, with the diff of cart.ts in a side panel and a row of terminal keys
The real terminal, one tap from the chat
A recording on a phone: opening a running session and following its replies as they arrive
Following a session on the phone

Some parts are still young. The Gemini, OpenCode and Copilot readers are in beta, the iOS app isn't built, and on Windows the terminal shows only what's on screen, without scrollback.