iBoB kit
iBoB kit
Section titled “iBoB kit”
bob ibob checkgrades 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.)
The kit file
Section titled “The kit file”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
Section titled “bob ibob check”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
Section titled “bob ibob attach”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.
Remote Control
Section titled “Remote Control”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.