Air traffic control for AI coding

Fleets across machines

Spread a fleet over this machine and cloud sandboxes, route tasks to pools, and change capacity while it runs. Cloud agents never receive your provider key.

  • Pools: local, daytona, modal, local-process.
  • Route tasks by id or file glob; add, drain and resize pools live.
  • A model gateway with a per-agent token and spending cap.
nool code --fleet "…" --pool local:4 --pool daytona:8

Pools

A pool is a place agents run, with a number of slots. List them in placement order with --pool; each task takes the first pool with a free slot, and the fleet is as wide as all pools together. Without --pool, the fleet runs on this machine only.

  • local[:N]: this machine, in try worktrees
  • daytona[:N]: Daytona sandboxes (DAYTONA_API_KEY)
  • modal[:N]: Modal sandboxes (the modal Python package, after modal setup)
  • local-process[:N]: separate processes on this machine, for testing the remote path

What a cloud agent gets

Each cloud agent gets its own machine: Nool installed, the target branch cloned into it from a git bundle, and its own session. When it lands, its work and its history come back as a bundle and merge into your branch; the sandbox is then deleted. Cloud pools need NOOL_SANDBOX_BUILD, a Linux Nool release archive to install there.

export NOOL_SANDBOX_BUILD=~/Downloads/nool-7.23.0-community-x86_64-unknown-linux-musl.tar.gz

Your API key stays here

Cloud agents never receive your model provider key. The fleet runs a model gateway on your machine; each agent gets its own token and a spending cap, and the token is revoked when it finishes. Pick how a cloud pool reaches the gateway with model=:

  • model=tunnel (default): an outbound-only Cloudflare quick tunnel; nothing listens on your network
  • model=hub: the Nool hub relays the calls to your machine, which polls it with your hub token
  • model=url:<url>: a tunnel or proxy of your own

Route tasks to pools

--route pins tasks to a pool by task id or by a glob over their files. Name pools with name= when you use two of one kind. Everything not routed takes the first pool with a free slot.

nool code --fleet "…" --pool local:2 --pool daytona:8,name=big --route "ui/**=local" --route search-index=big

Change capacity while it runs

Add a pool, drain one (its agents finish, no new ones start) or resize it without restarting the fleet. A pool added mid-run is used at once.

nool fleet ctl pool add modal:4
nool fleet ctl pool drain daytona
nool fleet ctl pool resize local 3

Isolation on each provider

On this machine and on Daytona, agents' shell commands run in Nool's jail (filesystem and process isolation; on Daytona it shares the sandbox's network). Modal runs each sandbox under gVisor, which refuses a nested jail, so there the sandbox itself is the boundary; the fleet says so when it starts. Before a cloud agent starts, its machine checks that it can reach the gateway, so a provider that only allows listed hosts fails early with the reason.