Install
Curl one line, get the zeno CLI on your PATH.
Zeno's runtime is Docker-only. The host needs the CLI (zeno), Docker, and a recent Node — that's it.
Prerequisites
gitdocker(Engine running; the CLI talks to the Docker socket directly)- Node.js 24 LTS
- macOS or Linux. WSL2 on Windows works; native Windows does not.
Run the installer
The installer clones the repo to ~/.zeno/zeno-agent/ and symlinks the zeno binary into ~/.local/bin/zeno. The clone path is fixed — there is no ZENO_HOME override.
curl -fsSL https://zeno-agent.dev/install.sh | shThat writes four things:
~/.zeno/zeno-agent/— the cloned repo, checked out at the resolved ref~/.zeno/zeno-agent/.installed-from— single line in the formatkind:value@sharecording the install origin (read byzeno --versionandzeno upgradeso they know how the clone was bootstrapped)~/.zeno/state.db— host-side SQLite holding profile metadata (chmod 600, owner-only)~/.local/bin/zeno— symlink to the built CLI
Make sure ~/.local/bin is on your PATH. Most distros ship that already; if not, add it to your shell rc.
Default behaviour
With no flag, the installer resolves the target through this fallback chain, in order:
GET /repos/ribeirogab/zeno-agent/releases/latest— the latest stable release tag.GET /repos/ribeirogab/zeno-agent/releases?per_page=1— the most recent prerelease, if no stable release exists yet.mainHEAD — only when the repo has no releases at all.
The .installed-from line records which step the installer landed on (tag:v…@sha, or unstable:@sha for the main fallback). zeno upgrade (no flags, non-TTY) follows the same chain so installer and upgrader behave identically.
Target flags
The installer accepts four mutually-exclusive target flags. Pass at most one — combining any two prints an error and exits 1.
curl -fsSL https://zeno-agent.dev/install.sh | sh # latest stable (default fallback chain)
curl -fsSL https://zeno-agent.dev/install.sh | sh -s -- --unstable # main HEAD — explicitly untrusted
curl -fsSL https://zeno-agent.dev/install.sh | sh -s -- --version v2026.5.7 # pin to a release tag
curl -fsSL https://zeno-agent.dev/install.sh | sh -s -- --branch feat/foo # arbitrary branch (testing)
curl -fsSL https://zeno-agent.dev/install.sh | sh -s -- --pr 123 # pull request branch (testing)| Flag | What it installs | .installed-from line |
|---|---|---|
| (none) | Latest stable → fallback prerelease → fallback main | tag:<resolved>@<sha> or unstable:@<sha> |
--unstable | main HEAD | unstable:@<sha> |
--version <tag> | The named release tag (validated via REST before clone) | tag:<value>@<sha> |
--branch <name> | The named branch | branch:<name>@<sha> |
--pr <number> | pull/<n>/head (works for fork PRs) | pr:<n>@<sha> |
--unstable is the explicitly-untrusted channel. It pulls main HEAD with no CI gate; breaking changes land there before they ship to a tag. Only use it when you need an unreleased fix, and expect things to break.
--version, --branch, and --pr are intended for testing-in-place — pinning to a known release, reproducing a bug on a feature branch, or trying out a contributor's PR before review. Routine version moves go through zeno upgrade instead; see Daily ops and the CLI reference.
Verify
zeno --helpIf you see the subcommand list, you're done. Next up: create your first profile.