Install
Layover is a single binary called layover. It needs no runtime — not Rust, not Node.
macOS and Linux
brew install KotkaZ/tap/layover
A tap rather than brew install layover, because homebrew-core does
not accept prebuilt binaries from third parties. You register nothing — taps are built into
Homebrew, and the homebrew- prefix is elided in the install expression.
Without Homebrew:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/KotkaZ/layover-project/releases/latest/download/layover-cli-installer.sh | sh
Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/KotkaZ/layover-project/releases/latest/download/layover-cli-installer.ps1 | iex"
Both installers pick the right build for your platform, unpack it, and put layover on your
PATH.
What they do and do not check
Be aware of exactly how much verification you are getting, because it is less than you might assume:
layover-cli-installer.sh | Carries the expected SHA-256 for each archive and checks it — but only if sha256sum is on the machine. If it is not, the installer prints skipping sha256 checksum verification and carries on successfully. Stock macOS ships shasum, not sha256sum, so on a clean Mac the check is usually skipped. |
layover-cli-installer.ps1 | Does no checksum verification at all. |
| The npm package | Downloads the archive without verifying it. |
Both installers are generated by dist rather than
written here, so this is upstream behaviour rather than a local choice — but it is our
documentation's job to say so rather than let you assume otherwise.
They are also not short: the shell installer is around 1,600 lines and the PowerShell one around 630. Reading one before running it is sound instinct, and a bigger job than it sounds.
Installing with verification you can see
If the above matters to you, skip the installers and do it by hand. This is fail-closed: a mismatch stops it.
TARGET=x86_64-unknown-linux-gnu
BASE=https://github.com/KotkaZ/layover-project/releases/latest/download # or releases/download/v1.7.0
curl -fsSLO "$BASE/layover-cli-$TARGET.tar.xz"
curl -fsSLO "$BASE/layover-cli-$TARGET.tar.xz.sha256"
# shasum on macOS, sha256sum on Linux -- use whichever you have, and do not skip it
shasum -a 256 -c "layover-cli-$TARGET.tar.xz.sha256" || sha256sum -c "layover-cli-$TARGET.tar.xz.sha256"
tar -xf "layover-cli-$TARGET.tar.xz"
$target = 'x86_64-pc-windows-msvc'
$base = 'https://github.com/KotkaZ/layover-project/releases/latest/download' # or releases/download/v1.7.0
Invoke-WebRequest "$base/layover-cli-$target.zip" -OutFile layover.zip
$expected = (Invoke-WebRequest "$base/layover-cli-$target.zip.sha256").Content.Split(' ')[0]
$actual = (Get-FileHash layover.zip -Algorithm SHA256).Hash
if ($actual -ine $expected) { throw "checksum mismatch: got $actual, expected $expected" }
Expand-Archive layover.zip -DestinationPath .
sha256.sum on the release covers every artifact, if you would rather check them together.
A checksum published beside the file it describes proves the download was not corrupted, not who produced it. For that, every artifact carries a build-provenance attestation: proof that it was built from this repository by its release workflow, which the GitHub CLI checks.
gh attestation verify "layover-cli-$TARGET.tar.xz" --repo KotkaZ/layover-project
The binaries are not code-signed — no Authenticode on Windows and no notarization on macOS — so the
operating system may still warn the first time one runs. Why provenance came first is in
docs/first-release.md.
With npm
Worth knowing about, because if you are using Layover you almost certainly already have Node: the agent CLIs it supervises all ship as npm packages.
npm i -g https://github.com/KotkaZ/layover-project/releases/latest/download/layover-cli-npm-package.tar.gz
The package downloads the right prebuilt binary for your platform; nothing is compiled. It is not on the public registry yet, so the tarball URL is the install path for now.
Manual download
Every release attaches an archive per platform with a .sha256 beside it:
| Platform | Archive |
|---|---|
| Linux x86-64 | layover-cli-x86_64-unknown-linux-gnu.tar.xz |
| Linux ARM64 | layover-cli-aarch64-unknown-linux-gnu.tar.xz |
| macOS Intel | layover-cli-x86_64-apple-darwin.tar.xz |
| macOS Apple silicon | layover-cli-aarch64-apple-darwin.tar.xz |
| Windows x86-64 | layover-cli-x86_64-pc-windows-msvc.zip |
Unpack it and put layover somewhere on your PATH. A sha256.sum covering every artifact is
attached to the release too.
With Cargo
cargo install layover-cli # from crates.io
cargo install --path crates/layover-cli # from a checkout
Do not run
cargo install layover. That name belongs to an unrelated SSH tunnelling crate whose binary is also calledlayover, so the mistake is silent: the install succeeds, the command exists, and nothing on yourPATHis the tool you wanted.
The crate is layover-cli; the binary it installs is layover.
From source
git clone https://github.com/KotkaZ/layover-project
cd layover-project
cargo install --path crates/layover-cli
Checking it worked
layover --version
Agent CLIs
Layover supervises other tools; it does not replace them. Install whichever runners your factory names, and make sure each works on its own before pointing Layover at it:
| Runner | Install | Check |
|---|---|---|
| Claude Code | npm i -g @anthropic-ai/claude-code | claude --version |
| GitHub Copilot CLI | npm i -g @github/copilot | copilot --version |
| OpenAI Codex CLI | npm i -g @openai/codex | codex --version |
Credentials reach child CLIs through the environment. Never put an API key in layover.toml —
it is a file people commit.
Starting with the computer
A lights-out factory that stops at every reboot is not lights-out.
layover autostart # writes the file
layover autostart --show # print it instead, to read first
That generates your platform's own artefact — a Scheduled Task on Windows, a launchd agent on macOS, a systemd user unit on Linux — and prints the single command that registers it. It does not register it for you: that touches the machine, and you should see what is being installed.
It also refuses to write anything if the factory does not load, because a service that fails at every logon is worse than no service.
What it starts is layover serve on the factory you pointed it at: the Tower, which fires its
schedules and runs its queue, and the dashboard beside it.
All three run as you, never elevated and never machine-wide. Layover spawns agents that use your provider credentials, your git identity and your workspace; a system service would have none of them, or would run as root with all of them.
Verify your setup
layover validate --config layover.toml --strict
This exits non-zero if anything would stop the factory starting. It is worth running in CI over your factory definition: an unattended factory that discovers a typo three agents deep has already spent money to find out.
Why not Docker
Layover spawns agent CLIs as child processes, runs them in your workspace, and relies on your provider credentials and MCP configuration. A container would have to be handed all three, at which point it has your filesystem and your secrets and has bought you nothing. It is a local-first supervisor; run it locally.
Cutting a release
Releases are built by dist, configured in
dist-workspace.toml. Tagging is the whole process:
git tag vX.Y.Z # must match the workspace version in Cargo.toml
git push origin vX.Y.Z
That builds all five targets, generates the installers, checksums everything and publishes a
GitHub Release. .github/workflows/release.yml is generated — change dist-workspace.toml
and run dist init, never edit the workflow by hand.
Check the configuration without releasing anything:
dist plan