Skip to content

The Surfaces BoB Talks On

Where the conversation happens. Every BoB run is a Claude Code session on some machine. What changes is where you are when it needs you: at the desk, across the room, out for the afternoon, or asleep while the farm works. This page explains the six surfaces BoB uses to reach you, what each one carries, and why the choice depends on your situation rather than on the task. The Where BoB Talks to You tutorial tries each surface once, and takes every command below from this page.

A BoB run always lives in exactly one place: a claude process in a project directory on one machine. The surfaces are windows onto that process, or channels out of it. None of them is a second copy of the run.

Surface What it is Where the session runs
Terminal claude in a shell, through BoB’s shell wrapper The machine you typed it on
tmux (with iTerm2) The same claude, inside a tmux session that outlives your terminal Any machine, including farm-01 over SSH
Desktop app The Claude desktop app’s Code tab: a graphical window on a session the app starts Your Mac, or a machine the app reaches over an SSH connection
Telegram The remote decision bridge: decisions and notices from a running session Wherever the session runs; only messages leave it
claude.ai / Claude iOS Remote Control: the full session, driven from a browser or the phone app Still the machine that started it
iBoB BoB’s own phone surface: a terminal kit for attaching from the phone (tutorial), and a web app (#2293) The kit attaches to the machine running the session; until the web app ships, bob viz on the tailnet stands in

Because the run stays in one place, the rules are simple. Closing a window never moves the run. Stopping the process ends it everywhere. A surface you are not looking at still receives whatever is sent to it.

The terminal is the one surface every other one depends on. BoB’s shell wrapper (bin/bob-shell.zsh) reads three flags before it hands over to Claude Code: -a1 to -a4 set the automation level, -rdb turns the Telegram bridge on, and --kit <name> applies a session kit as a provision overlay. Each one prints a BoB: line first, so you can see what it did.

Terminal window
cd ~/projects/hello-bob
claude -a2 --kit review
/automation
Terminal window
bob provision overlay status
bob provision overlay restore

/exit (or Ctrl-D) leaves the session. The level and the RDB setting stay in the project’s .claude/settings.local.json until you change them. A kit overlay stays until bob provision overlay restore removes it.

A run in a plain terminal dies with the terminal. bob warp start puts the run in a detached tmux session named warp-<stem>[-<scope>] instead, and prints the line to attach to it. On a Mac running iTerm2, tmux -CC attach opens it in control mode: each tmux window becomes a native iTerm2 tab. The rule that matters is the one people get wrong: closing a tab kills that tmux window, and with it the run. To leave, detach the client. The tmux cheatsheet has every key binding.

Terminal window
bob warp start --level 2 --rdb --session hello-bob-run
tmux ls
bob warp attach hello-bob --cc
Terminal window
tmux detach-client -s hello-bob-run
bob warp status

bob warp attach follows the run across segments: when a long run hands off to a fresh warp-seg-* session, the attached terminal moves with it, so there is no segment number to look up.

The desktop app: the same session, a friendlier window

Section titled “The desktop app: the same session, a friendlier window”

The Claude desktop app shows a Claude Code session with rendered diffs, files and plans. A session it starts runs in the environment you pick: Local, a folder on the Mac the app is installed on, or an SSH connection to another machine, where the app installs its own copy of Claude Code the first time it connects. So it suits work on a laptop checkout, and it can start a new session in a project that lives only on farm-01. It lists only the sessions it started: a run that bob warp start put in tmux is not in its sidebar. claude --desktop opens the app on the current folder, and --continue hands that folder’s last terminal session over to it.

Terminal window
cd ~/projects/hello-bob
claude --desktop
/what-next
Terminal window
claude --desktop --continue

BoB’s hooks, skills and commands load in the app exactly as they do in the terminal, because the app runs the same Claude Code against the same ~/.claude. The shell wrapper does not: set the level and RDB from the terminal first, or with /automation and /rdb inside the app.

Telegram: decisions and notices while you are away

Section titled “Telegram: decisions and notices while you are away”

The remote decision bridge (handbook §7.6) is an MCP server, remote-decision-bridge, with two tools. ask_remote sends a question to Telegram and waits for your answer. notify_remote sends a one-way notice. /rdb on (or claude -rdb, or telling Claude you are stepping away) flips the session to use ask_remote for every decision it would otherwise ask in the terminal. From a shell with no session at all, bob notify sends the same kind of notice through the bridge’s HTTP endpoint.

/rdb status
/rdb on
Terminal window
bob notify "hello from BoB"

A Level 2 run asks “Continue to next task?” at the end of every requirement. With RDB on, that question goes to Telegram, which makes it the easiest real decision to answer from the phone.

claude.ai and the Claude iOS app: the whole session, remotely

Section titled “claude.ai and the Claude iOS app: the whole session, remotely”

Remote Control is Claude Code’s own remote surface. A session started with --remote-control registers itself with your claude.ai account, and appears in the Code section of claude.ai and of the Claude iOS app. There you see the full transcript and can type into it, as if you were at the terminal. The session still runs on the machine that started it. Close the laptop lid or kill the process, and the remote view disconnects.

Terminal window
cd ~/projects/hello-bob
claude -a2 --remote-control hello-bob
Run bob warp status and tell me the phase in one line.

The difference from Telegram is scope. Telegram carries the questions and notices BoB chooses to send. Remote Control carries the whole conversation, but only for a session that has it on: started with --remote-control, switched on from inside with /remote-control, or on for every session through the remoteControlAtStartup setting in ~/.claude/settings.json.

iBoB is the planned phone surface for BoB itself: the fleet, the runs and your handoffs, in a view built for a phone, with actions (#2293). Its terminal kit already ships: Run BoB from Your iPhone attaches the phone to a live run. Until the web app ships, the phone’s view of BoB is bob viz served on the tailnet. Its tiles and the handoff banners already fit a 390-pixel-wide screen.

Terminal window
bob viz --tailnet

The six surfaces above are windows onto one session. BoB Control (#3812) is the page over all of them: every project, every running session on every fleet machine, and the things waiting on you. bob control opens it. It is one frame on the dashboard server, the same page in a browser and in the desktop app, with these screens:

Screen What it shows
Now What needs you: the asks that block work, five at most, with one Do it each; the rest are folded. bob control opens on it.
Projects Every registered, active project by name, the ones with a live session or an open ask first.
Fleet The fleet’s notices, reports and briefings, as bob viz shows them, without its project tiles.
Costs The GitHub quota line, without project tiles; each project’s cost and churn row is on its own page.
Project One project’s own page: a one-line summary, then its asks, the sessions running for it, its actions and its plan, activity, files and CI on tabs, beside the project’s terminal.
Session One running state machine (a warp-drive, decompose or do run): what it is doing, and a dispatch box that reaches that session only.
Ask One ask with its steps. It is opened from an ask on the Now page or the Project screen.

Control owns no state. A project, a session and an ask live where they did before it existed: in issues, tmux, state files and the fleet feed. Control reads them and acts through the same bob commands a shell runs, so stopping its server loses nothing, and a run is still in exactly one place. BoB Control explains the frame, its addresses and each screen.

The task never decides the surface; where you will be does. The questions are whether you are watching, whether you can answer, and for how long. So the choice is keyed by your situation:

Your situation Surface Start it with What reaches you there
At the desk and watching Terminal (or the desktop app on a Mac) claude -a2 Everything: each decision, each permission prompt, the diffs as they happen
At the desk, working on something else tmux bob warp start --level 3 Nothing interrupts you. The run asks in its own window, and a push reaches the Claude app only when it stops for you
Away for an hour tmux, with Telegram bob warp start --level 3 --rdb Every decision in Telegram, a notice per phase, and the push when it stops for you
Away for a day tmux on farm-01, with Telegram bob warp start --flightplan <N> --level 3 --rdb Telegram notices, and a todo for anything only you can do. Next morning, read it with /status
On the phone only claude.ai / Claude iOS claude -a2 --remote-control <name> The whole conversation, typed and read from the phone
Several loops at once tmux, one window per loop bob fork fork --from-issues 3 Each loop in its own iTerm2 tab, and all of them on bob viz

Two rules sit under the table. Turn the surface on before you leave: a session with neither Remote Control nor RDB on cannot be reached from the phone. Both can be switched on in a running session (/remote-control, /rdb on), but only from a window that already reaches it. And a run you want to outlive the window always goes in tmux, whichever surface you then watch it from.

BoB sends three kinds of message. Each goes to a fixed place:

Message Sent by Reaches
A decision, RDB off AskUserQuestion in the session The session’s own window: terminal, tmux, desktop app, or Remote Control
A decision, RDB on ask_remote in the session Telegram only. The session waits for your reply there
A phase notice notify_remote in the session, RDB on Telegram
A notice with no session bob notify from a shell (the farm’s tick, bob brief --send, a release) Telegram, or printed to the shell with exit 3 when no bridge is configured
“BoB needs you” the handoff record, when a run stops for you A push through the Claude app from a session, or through bob notify from a shell, plus the banner on bob viz and bob warp viz

What never leaves the terminal: the output of commands you run in your own shell, and the transcript and permission prompts of any session that does not have Remote Control on. A decision goes to exactly one place, never two. With RDB on, the terminal does not ask it as well, so nobody at the desk can answer it there.

Each surface fails in its own way, and each failure has one check and one fix:

/rdb status
/mcp
Terminal window
bob notify "bridge test"
Terminal window
tmux ls
bob warp status
bob warp start --level 2 --rdb --session hello-bob-run
Terminal window
ls ~/projects/hello-bob
bob doctor
Terminal window
tmux new -s hello-bob-rc -d 'cd ~/projects/hello-bob && claude --remote-control hello-bob'
tmux ls