Skip to content

iBoB kit

bob ibob check grades the declared phone setup against every machine it targets, read-only. bob ibob attach <machine> lists the live warp and cdfork sessions there with the command to type on the phone. The steps are in Set Up the iBoB Terminal Kit. (Back to reference index.)

Operator data at config/ibob-kit.json in the operator repo (#2270), reached through operatorPath('ibob-kit.json'), validated by schemas/ibob-kit.schema.json and graded by check-operator.js. The product ships the schema and a template, templates/ibob/ibob-kit.json. No key material is stored: a key is named and fingerprinted only.

Field Meaning
tailscale.app, tailscale.docs The tailnet client on the phone. Every target is reached over the tailnet (decision #1773).
client.name, client.transports, client.docs The SSH/mosh app and what it speaks, in preference order. With mosh first, the check requires mosh-server on every target and attach prints a mosh command.
remote_control.supported, remote_control.docs Claude’s own Remote Control for driving a Claude Code session from the Claude iOS app. BoB builds no replacement.
devices[].id, label One entry per phone or tablet.
devices[].key.name, fingerprint, comment The device’s key. The SHA256: fingerprint (as ssh-keygen -lf prints it) is matched against each target’s authorized_keys; without one, the comment (else the name) is.
devices[].key.inventory_id The credential in secrets-inventory.json that declares the key.
devices[].authorized_on machines.json ids whose authorized_keys must hold the key.
attach.default_targets machines.json ids probed and offered first.
attach.user The login user on the targets, when it is not the client’s default.
bob ibob check [--machine <id>] [--json]

Declaration rows (no network): the kit file exists and is schema-valid; each target is a machines.json id; each device key is a credential in secrets-inventory.json with an ssh-key location, and a secrets[] entry of operator.json with the same inventory_id — so bob secrets check reports it.

Per machine, in order, stopping at the first gate that fails:

Check Pass when Fix named on failure
tailnet tailscale status --json lists the machine online install Tailscale here / wake the machine / fix its tailscale_name
ssh one SSH call through scripts/fleet/audit.js sshRun succeeds macOS: turn on Remote Login (reported, never enabled); Linux: start sshd; a refused key: authorize this machine’s key
key:<device> the device key’s fingerprint is in ~/.ssh/authorized_keys append the device’s public key
mosh mosh-server is on PATH (graded only when the client prefers mosh) brew install mosh / sudo apt install mosh
tmux tmux is on PATH brew install tmux / sudo apt install tmux

The same SSH call lists the live tmux sessions with seg-windows.js list on the target (the one session parser), filtered to BoB’s: warp-* (including warp-seg-*) and cdfork-*. Sessions are listed, never graded. A target without BoB deployed, or on a BoB older than seg-windows.js list, is noted (with “deploy” as the fix), not failed and never shown as “none live”.

The machine running the check is probed locally when SSH refuses this machine’s own key: “Permission denied” already proves the SSH server is up (Remote Login on), and the phone authenticates with its own key, so the authorized_keys, mosh-server, tmux and session probes read this machine directly. On any other machine a refused key is an ssh failure.

--json prints one ibob-kit/1 document: kit {path, source, exists}, ok, declaration[] {check, subject, ok, detail, fix}, and machines[] {id, tailscale_name, os, checks[] {check, ok, detail, fix}, sessions[], ok}.

Exit Meaning
0 converged — every declaration row and every machine check passes
1 drift — a missing or invalid kit, an undeclared key, or a failed check
2 usage — an unknown flag, or --machine that is not a kit target
bob ibob attach <machine> [--json]

Lists the live warp and cdfork sessions on one machine, each with the command to type in the phone client: mosh <host> -- tmux attach -t <session> when the client prefers mosh, else ssh -t <host> tmux attach -t <session> (<host> is the machine’s tailscale_name, prefixed by attach.user@ when declared). --json prints ibob-attach/1: machine, ok, sessions[] {session, command}, error, fix. Exit 0 when at least one session is listed, 1 when none is live or the machine cannot be reached (the fix is printed), 2 on usage.

Driving a Claude Code session from the phone is Claude Remote Control: claude --remote-control (or /rc in a running session) on the machine, then the session in the Claude iOS app. It needs a claude.ai login on a Pro, Max, Team or Enterprise plan. The kit records it as the supported route; BoB adds nothing to it.

tests/test-ibob-kit.js drives bin/bob ibob in a throwaway HOME and operator repo with tailscale and ssh stubbed: converged, every drift with its fix, an offline peer, an absent and an invalid kit, usage exits, and attach. It also stages each failure the Run BoB from Your iPhone tutorial quotes and asserts every quoted line is what the check really prints.