Putting work where it fits
--on NAME starts a session on the machine you name. --in names what it needs instead, and Alto picks the machine:
alto new --in 'os:windows has:claude' -- claudewin 4It asks every machine you reach what it is, and picks one that matches every word, is answering, isn’t drained and isn’t full; then the least busy. It prints the machine and the session’s id, so win:4 is the new session.
When nothing fits it says what came closest, and what each lacks:
no device fits `os:windows has:codex`: pc has no codex; win has no codexSelectors
Section titled “Selectors”| Word | Matches a machine that |
|---|---|
os:windows, os:macos, os:linux |
runs that (also win, mac) |
arch:aarch64, arch:x86_64 |
has that processor (also arm64, x64) |
has:claude, has:docker, has:git |
can run it in a session: the agents Alto knows, git, docker, xcode, wsl, and anything in tools = [...] in its settings |
tag:build |
carries that Tailscale tag |
kind:vm, kind:container, kind:phone, kind:computer |
is one (a computer is none of the others) |
gpu |
has a GPU |
pool:NAME |
is in that pool (below) |
| a name | is that machine |
Case doesn’t matter. alto devices shows what each machine says about itself, so you can see why one matches or not.
The same words, with status:, agent: and repo: for sessions, narrow alto ls: see Every session, every machine.
A pool is a selector with a name, and optionally a limit on the sessions across the machines it matches. In settings.toml:
[pools.win]match = "os:windows has:claude"max = 6
[pools.gpu]match = "tag:gpu"alto new --in pool:win -- claudealto new --in 'pool:gpu has:docker' -- ./train.shA pool past its max takes no more until one of its sessions ends.
Profiles that place their tabs
Section titled “Profiles that place their tabs”A profile with in opens its tabs wherever fits, from the menu beside + too:
[profiles.Windows]in = "pool:win"command = "claude"Your code goes with it
Section titled “Your code goes with it”--repo starts the session in a checkout of the repository you’re in, at your current commit, on a branch of its own (alto/<machine>-<id>):
alto new --in 'os:windows has:claude' --repo -- claudealto fetch win:4 # bring its branch back here, its commits and allCommits the machine can’t fetch from your remote are sent along with it. Changes you haven’t committed aren’t sent: Alto says so, so you can commit them first. Each machine keeps its own copy of the repository, so the next session there fetches instead of cloning.
How much each machine takes
Section titled “How much each machine takes”On a machine, in its settings.toml:
max_sessions = 8 # full at 8 running sessions: --in looks elsewheretools = ["terraform"] # look for these too, for has:terraformalto settings drain on # take no new work: --in and placed profiles go elsewherealto settings drain off # take it againA drained machine’s sessions go on running, and --on still reaches it, for when you mean that one.