Rove

Machines

One Rove watching every computer you code on.

Install Rove on each machine, register the others with rove machine add, and their tasks appear in your sidebar under a row of their own. There is no "switch to that machine" step — every machine is connected at once, and the tree is the answer to what is running where.

What this needs

  • Rove installed on both machines (npm i -g @sma1lboy/rove).
  • SSH access to the remote one, working non-interactively — ssh narwhal true must succeed without a prompt. A Host block in ~/.ssh/config is the usual way; Rove reads it rather than replacing it.

Nothing else. Rove opens no ports and adds no authentication of its own: the remote daemon keeps listening on its private unix socket, and SSH forwards that socket to yours. SSH is the transport and the authentication.

Both machines need a Rove new enough to have machines — an older one reports no PTY socket in rove daemon status, and machine add says so rather than half-connecting.

While a machine's rows are on screen, Rove counts as one attached window on that machine, so its daemon stays up for as long as you are looking at it.

Add a machine

$ rove machine add narwhal
rove machine: contacting narwhal…
rove machine: Nahuels-Mac-mini → narwhal (rove 0.9.185 on Nahuels-Mac-mini.local)

add verifies before it saves: it asks the machine where its daemon listens (rove daemon status --json, starting one there if none is up) and refuses if the host is unreachable, Rove is not installed, or no daemon can be started. Rove never guesses a remote socket path — the remote home may be a different user, and the path may have been shortened to fit the platform's socket-name limit.

The alias is what the sidebar shows. It defaults to the target you typed — rove machine add narwhal gives you a machine called narwhal, because that is the name you already chose for it. A target that is addressing rather than a name (user@host, an explicit port, a bare IP) takes the machine's own hostname instead. Override either with --alias:

$ rove machine add nahuel@mac-mini.local --alias narwhal
OptionWhat it does
--alias <name>Local name for the machine. Default: the target you typed, or the machine's hostname when the target is user@host / has a port / is an IP.
--port <n>SSH port. Default: whatever ssh_config says.
--identity <file>SSH private key. Default: ssh-agent / ssh_config.

The target is [user@]host[:port], usually just an ssh_config Host alias. An IPv6 address with a port needs brackets, exactly as ssh requires: [fe80::1]:2222.

Nothing secret is written to state.json. A key is stored as a path; a password is stored as a keychain reference, never as a password.

What you see

rove                          ← your projects, exactly where they were
  main
  fix/machines
narwhal · v0.9.185            ← a machine
  narwhal:rove                ← its checkout of a repo you also have
    remote probe
  • Two machines, one repo name. A repo called rove on both machines shows as rove here and narwhal:rove there. The local one keeps the bare name — it is the one you are sitting at. Two checkouts of rove on the same machine take the path instead (gihub/rove, i/rove): there the machine name would say nothing.
  • Offline machines keep their rows. A laptop whose lid closed has not stopped having those tasks, so the row stays and greys out instead of vanishing. Rove reconnects in the background and the rows come back to life.
  • Version skew is on the row. narwhal · v0.9.180 next to your own build explains most of what otherwise looks like a bug. A machine whose Rove is too old to talk to yours reads ⚠ v0.9.100 (protocol mismatch) and is the only row affected.

List and remove

$ rove machine list
narwhal  narwhal  Nahuels-Mac-mini.local

$ rove machine remove narwhal
rove machine: removed narwhal. Nothing on that machine was changed — its daemon, tasks and worktrees are untouched.

Registering one machine under two aliases is recognized and reported: Rove compares the remote daemon's hostname, state root and pid, and renders one row either way.

What this release does not do yet

This is the first of three. Today machines are read-only:

  • Opening a remote task's session is not wired up yet — you can see it, not enter it.
  • rove api verbs aimed at a remote task refuse with NOT_YET_SUPPORTED_REMOTE rather than quietly running against your local daemon, where that task id does not exist. Run the command on that machine instead.
  • The file tree and diff panes show on <host> for a remote task. Its worktree path means nothing on your filesystem, and reading it would list whatever happens to sit at the same path here.

Windows can register and list machines, but cannot open the tunnel: OpenSSH on Windows has no unix-socket forwarding. Such a machine's row reads unsupported.

Where things live

PathWhat
state.json → machinesThe registry: host, user, port, auth, learned identity
<home>/.rove/machines/<alias>/daemon.sockLocal end of the forwarded daemon socket
<home>/.rove/machines/<alias>/pty.sockLocal end of the forwarded PTY-host socket
<home>/.rove/machines/<alias>/cmThe shared SSH connection (ControlMaster)

Under a deeply-nested home these move to a short $TMPDIR/rove-m-… directory: a unix socket path cannot exceed ~104 bytes, and <home>/.rove/machines/… overruns that before it starts. The fallback is derived from the home and the alias, so it is the same path every time.

The directory is owner-only (0700); so are the sockets in it. They reach a daemon that runs commands as its owner.

Not the same as rove add --remote

rove add --remote registers a remote project and drives git and the engine over SSH from your daemon — it assumes the far side has no Rove. Machines assume the far side runs Rove and speaks the daemon protocol. Both still exist; they answer different questions.

On this page