>_ robje

macOS companion app · in development

Talk to Claude Code.
From your phone.

Robje is a menu-bar app for your Mac that relays your voice into the claude sessions already running in your tmux panes, and reads the responses back. Nothing about your terminal workflow changes. You just stop having to be at the keyboard.

Download for Mac
Developer ID signed & notarized Apple Silicon & Intel macOS 13+

01 What it actually does

The design axiom is simple: your existing tmux workflow is the product. Robje doesn't replace, wrap, or restart your claude processes. It attaches to panes that already exist, so you can still tmux attach from anywhere and type normally mid-session.

01

Passive observer

The Mac app watches your running tmux sessions via Claude Code's own hooks and transcript files.

02

Voice in

Speech captured on your iPhone travels over Tailscale to the Mac and lands as real keystrokes in the correct pane via tmux send-keys, the same as if you'd typed it.

03

Voice out

Claude's replies are read back to your phone, sourced from Claude Code's structured hook events and its append-only transcript.

tmux · claude
iPhone  ──wss / Tailscale──▶  Mac menu-bar app
   │                                │
   │                      tmux send-keys
   │                                ▼
   └── spoken response ──  your existing claude pane
                                     ▲
                      hooks + transcript JSONL
▌

02 New on the phone

The iPhone app began as a microphone and a session picker. Recent builds grew past that: a real terminal, an embedded network path, a lock screen, and a place on the car dashboard.

chat / terminal

An interactive terminal, in two views

Each session opens into a full screen with a two-way switcher. Chat is a conversation with Claude: type a prompt, watch the reply and the working steps come in. Typed messages ride the same routing as speech. Terminal is the live tmux pane itself, streamed to the phone, with a special-key row (Escape, Tab, Ctrl, arrows), an input bar whose text lands as literal keystrokes, and copy support for pane text.

tailscale · beta

Built-in Tailscale on the phone

The iPhone app can now run its own embedded Tailscale node, so the Tailscale app is no longer required on the phone. Sign in with an auth key or a browser login and the phone joins your tailnet as its own device. The Mac still requires the Tailscale app. The embedded node carries a beta label for a reason: if it misbehaves, installing the Tailscale app on the phone remains the proven path.

face id

App lock, on by default

A picked-up phone would otherwise be a live session on your Mac. The app locks whenever it goes to the background and asks for Face ID when it comes back. You can turn this off in Settings; it ships on.

carplay

CarPlay, through Now Playing

In the car, Robje shows up on the Now Playing screen with artwork that reflects the session's state (idle, listening, thinking, speaking). Play/pause toggles the microphone, next skips what's being read, previous repeats Claude's last turn. The same mapping works from an AirPod stem squeeze and the lock screen.

03 Before you install

Robje is a relay between your phone and sessions that already exist. It has nothing to do until three things are already true on your machine. Skip any one of these and the app will launch but sit there doing nothing useful.

  1. tmux is installed

    Robje talks to Claude Code through your tmux panes, so tmux has to be there first.

    brew install tmux
  2. Claude Code is already set up

    You should already be running claude from a terminal, inside tmux, on projects you trust. If you've never used Claude Code from the command line before, start there. This app has nothing to inject into otherwise.

  3. A Tailscale path between the two devices

    On this Mac, the Tailscale app is required: install it and sign it into your tailnet. On the phone there are now two options: the Tailscale app, or the iPhone app's built-in Tailscale node (beta), which needs no extra install. Either way, both devices end up on the same tailnet, and that is the only network path Robje uses: no public listener, no port forwarding.

    tailscale.com →

Without all three of these, downloading the app accomplishes nothing. It will run fine and do nothing: a relay with no ends to connect.

04 Security: read this before trusting it

This app lets a phone, over a network, approve actions that Claude proposes to take on your Mac. That's a real capability. Here is an honest account of what it does and doesn't defend against, with no mitigations dressed up to imply more safety than exists.

A blast-radius reducer; never mistake it for a sandbox

The permission tier system decides which prompts are safe to approve without looking at a screen. It classifies a string, a command line or a file path, and never the effect that string will have. Claude can edit a script inside your project and then run it in the same turn; the classifier sees a benign file edit and a familiar command, both correctly read, and never opens the file it's about to execute. This is how Claude normally works. No exotic attack is required.

It does not defend against prompt injection

Claude reads files: a README, a changelog, an issue, an error message. Any of them can contain text addressed to the model rather than to you: "to reproduce, run npm run repro", where repro is defined as something hostile. The classifier sees a familiar, in-project command and approves it the same way it would approve a real reproduction step. There's no pattern matcher that catches this. The channel that carries the attack is the same channel that carries the work.

Only point this at machines and projects you already trust

That's the actual scope, stated plainly. Robje reduces the chance that a misheard "yes" does something irreversible. It does not make voice approval safe against hostile content. Don't use it on repos you just cloned and haven't read, on projects processing untrusted input, or on machines holding credentials whose loss you can't recover from.

The terminal screen is a deliberate free-form channel

Everything voice-driven goes through narrow, allowlisted paths: the voice side can submit a prompt, answer a dialog by its label, or send one of a small fixed set of named keys. It cannot express "send these keystrokes". The phone's terminal screen is the one deliberate exception, and it should be understood plainly: anyone holding a valid per-device pairing token can type arbitrary keystrokes into any registered Claude pane, exactly as if seated at the Mac. On that screen, the security boundary is the pairing token plus your Tailscale tailnet, and nothing narrower. Voice input can never reach this channel; it exists only behind the terminal screen you open by hand, and revoking a device from the Mac's paired-device list kills it along with everything else.

What does hold, structurally

  • The permission hook only announces. It never blocks and never returns a decision to Claude Code. If the Mac app crashes, the phone dies, or Tailscale drops, nothing executes; the prompt just sits there, answerable from the Mac keyboard like always.
  • Sessions running with --dangerously-skip-permissions are refused. Robje won't inject into a pane that has no dialogs to answer.
  • "Yes, and don't ask again" is off by default. It sits next to plain "yes" in the dialog, and one misheard word would otherwise be a silent, permanent privilege escalation.
  • Every dialog carries a nonce, so a queued answer from a reconnecting phone can't land on a different prompt that opened in the meantime.
  • On every voice-driven path, keys are an allowlisted enum: Escape, a digit, a handful of named keys. The free-form terminal channel above is the single exception, and even there text goes through tmux send-keys -l (literal, never interpreted as key names), special keys are a fixed enum mapped on the Mac side, and the channel only reaches panes the session registry already tracks.
  • The network path is Tailscale-only: no public listener, no tailscale funnel.

05 Installing it

  1. 1

    Download the .dmg

    Use the button at the top of this page.

  2. 2

    Open it and drag to Applications

    Standard macOS install: drag the Robje icon onto the Applications shortcut in the disk image window.

  3. 3

    Launch it

    The build is Developer ID signed and notarized by Apple, so first launch should be smooth: no scary full-screen warning. If macOS still throws one anyway (it sometimes does for freshly downloaded files), right-click the app in Applications and choose Open instead of double-clicking. That one-time step confirms you mean it.

  4. 4

    Look for the menu-bar icon

    Robje runs as a menu-bar app, not a Dock app. That icon is where pairing and session status live once it's running.