docs/book/src/setup/windows.md
Install, update, run as a Windows scheduled task, and uninstall on Windows 10 / 11.
If you're running WSL2, you can follow the Linux setup instead; install.sh runs unchanged under WSL.
Note on
setup.bat. The#6118hard-stop failures (the 32-bitset /adisk-space overflow and the unescaped-parensif/elseparse error) were fixed in #6137 and ship in v0.7.4 and later. Current releases complete normally. One caveat remains:setup.bat --prebuiltstill checks forcargobefore reaching the prebuilt branch, so the manual prebuilt path (Option 1 below) is the true no-Rust install. Building from source (Option 3) also works.
Download the latest Windows release zip, extract zeroclaw.exe, and put it on your PATH.
From a PowerShell prompt:
# Idempotent: re-running this block is a no-op when zeroclaw is already
# installed at the latest release and on the user PATH. After a release
# bumps, the version check fails and the install side runs again.
$ver = (Invoke-RestMethod 'https://api.github.com/repos/zeroclaw-labs/zeroclaw/releases/latest').tag_name.TrimStart('v')
$dst = "$env:USERPROFILE\.zeroclaw\bin"
$exe = "$dst\zeroclaw.exe"
$current = if (Test-Path $exe) {
((& $exe --version 2>$null) | Select-String -Pattern '\d+\.\d+\.\d+').Matches.Value
} else { '' }
if ($current -ne $ver) {
$url = "https://github.com/zeroclaw-labs/zeroclaw/releases/download/v$ver/zeroclaw-x86_64-pc-windows-msvc.zip"
New-Item -ItemType Directory -Force -Path $dst | Out-Null
Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\zeroclaw.zip" -UseBasicParsing
Expand-Archive -Force -Path "$env:TEMP\zeroclaw.zip" -DestinationPath $dst
}
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($userPath -split ';') -notcontains $dst) {
[Environment]::SetEnvironmentVariable('Path', "$dst;$userPath", 'User')
}
if (($env:Path -split ';') -notcontains $dst) {
$env:Path = "$dst;$env:Path"
}
& $exe quickstart
The zip ships a self-contained binary, with no Rust toolchain, no Visual Studio Build Tools needed.
After install, verify:
zeroclaw --version # matches the latest release
setup.bat (from a release)setup.bat --prebuilt
Flags:
| Flag | Behaviour |
|---|---|
--prebuilt | Download prebuilt binary from GitHub Releases (fastest once reached; current script still checks for cargo first) |
--minimal | Build core only (no channels, no hardware) |
--standard | Build with common channels (Telegram, Discord, Slack, Matrix) |
--full | Build everything |
⚠️ Known issue (current).
setup.bat --prebuiltstill checks forcargobefore it reaches the prebuilt branch, so Option 2 does not honor a no-Rust promise. If you don't have a Rust toolchain, use Option 1 above.Historical (pre-
v0.7.4). Earlier releases had two hard-stop failures and an onboarding-command mismatch reported in #6118: a 32-bitset /adisk-space overflow (Invalid number. Numbers are limited to 32-bits of precision.), an unescaped-parensif/elseparse error (.[0m was unexpected at this time.), and a finalzeroclaw initprompt. All were fixed in #6137 (v0.7.4 / 0.7.5 / 0.8.0); current releases printzeroclaw quickstartand complete normally.
Requires Rust (rustup) and Visual Studio Build Tools:
git clone https://github.com/zeroclaw-labs/zeroclaw
cd zeroclaw
cargo install --locked --path .
zeroclaw quickstart
⚠️ The Scoop manifest in the repo is pinned to v0.5.9 (23 patch releases behind master). Until a release-time CI hook bumps it, prefer Option 1 or 3. If you do use Scoop and hit issues, please open a PR against
dist/scoop/zeroclaw.json.
scoop install zeroclaw # currently installs an older release; see warning above
zeroclaw quickstart
ZeroClaw publishes a Linux container image at ghcr.io/zeroclaw-labs/zeroclaw:latest (and :vX.Y.Z for tagged releases). On Windows, run it via Docker Desktop or via sudo apt install docker.io inside a WSL distro; both work, and the container behaviour is identical.
Quick start:
# Persistent volume for config + workspace; ZeroClaw's data dir inside the container is /zeroclaw-data
docker run -d --name zeroclaw `
--restart=unless-stopped `
-p 42617:42617 `
-v zeroclaw-data:/zeroclaw-data `
ghcr.io/zeroclaw-labs/zeroclaw:latest
# Watch the first-run logs
docker logs -f zeroclaw
# Health check (no auth required)
curl http://localhost:42617/health
# (Optional) pair a client. NOTE: the published image defaults to
# `require_pairing = false`, so by default no pairing code is emitted
# and `/api/*` accepts requests without auth. To enable pairing,
# override the config (set `require_pairing = true` in
# /zeroclaw-data/.zeroclaw/config.toml inside the container) and restart;
# a one-time code is then printed to stdout on first start, after which
# clients POST it to `/pair`:
curl -X POST http://localhost:42617/pair -H 'X-Pairing-Code: <code-from-logs>'
Image facts (verified against ghcr.io/zeroclaw-labs/zeroclaw:latest):
gcr.io/distroless/cc-debian13:nonroot (release stage; the dev stage is debian:trixie-slim)ENTRYPOINT ["zeroclaw"], CMD ["daemon"]: running with no args starts the daemon and gatewayEXPOSE 42617: both the daemon and gateway listen on this port/zeroclaw-data (config: /zeroclaw-data/.zeroclaw/config.toml, workspace: /zeroclaw-data/workspace). Mount a named volume or bind here for persistence; note this is not /root/.zeroclaw.require_pairing = false, so /api/* accepts requests without authentication out-of-the-box. When pairing is enabled (set require_pairing = true in /zeroclaw-data/.zeroclaw/config.toml and restart), the daemon prints a one-time code to stdout on first start, and clients then POST it to /pair with the X-Pairing-Code header before any authenticated endpoint will respond.gateway.web_dist_dir = "/usr/share/zeroclawlabs/web/dist" and includes the built frontend there, so the gateway serves the SPA fallback out-of-the-box. The assets live outside the /zeroclaw-data mount point so a -v …:/zeroclaw-data volume mount cannot shadow them (ref #6400).Build from source against the bundled Dockerfile:
git clone https://github.com/zeroclaw-labs/zeroclaw
cd zeroclaw
docker build -t zeroclaw:local -f Dockerfile.debian .
Verified on Windows + Docker:
ghcr.io/zeroclaw-labs/zeroclaw:latest in WSL Debian on Windows 11 build 26200.8313. Image starts cleanly, gateway listens on :42617, /health returns valid JSON. With require_pairing = true set in config and the container restarted, the pairing-code flow on /pair also works as documented.wsl --install to enable WSL2, then sudo apt install docker.io inside the WSL distro, gives you the daemon directly; verified to pull and runs the published image without modification.Host-side best practices: general Docker + WSL2 guidance, not zeroclaw-specific runtime claims. Sourced from Microsoft Learn and Docker's own docs where applicable:
-v C:/Users/...:/zeroclaw-data) into a Linux container crosses the WSL2 ⇄ Windows filesystem boundary; Microsoft documents the layout and the cross-OS path implications in the WSL file systems reference. Prefer Docker named volumes (-v zeroclaw-data:/zeroclaw-data) or store the workspace inside the WSL filesystem (\\wsl$\Debian\home\...) for near-native performance.localhost:<port> after -p forwarding (verified on Windows 11 + WSL2). If you need to reach the container from another box on the LAN, or run multi-container setups where intra-container DNS matters, switch to mirrored mode per Microsoft's Mirrored mode networking reference, by adding to %USERPROFILE%\.wslconfig:
[wsl2]
networkingMode=mirrored
--restart=unless-stopped as in the example above, for daemon-mode startup. The published image runs as PID 1 / nonroot user; the container is the service; don't run zeroclaw service install inside it.# PowerShell / cmd.exe: use a single leading slash.
# Git Bash / MINGW: use //var/run/docker.sock to bypass MSYS path rewriting.
-v /var/run/docker.sock:/var/run/docker.sock
\\.\pipe\docker_engine; the bind-mount syntax above translates correctly. The pattern is general; it has not been benchmarked specifically against zeroclaw's skill sandbox in this doc.%USERPROFILE%\.wslconfig, which defaults to half host RAM. The full configuration surface is documented in Microsoft's Advanced settings configuration in WSL reference. A reasonable starting envelope for a single-user ZeroClaw deployment is:
[wsl2]
memory=8GB
processors=4
Windows builds use the MSVC toolchain. To build from source you need:
rustup)If you're using Option 1, you don't need the Rust toolchain; the binary is self-contained. Option 2 (setup.bat --prebuilt) is intended to use the same binary path, but the current script still checks for cargo before it reaches the prebuilt branch; see the known issue above.
On Windows, ZeroClaw installs as a user-scoped scheduled task named ZeroClaw Daemon. There is no Windows Service / LocalSystem option in the current release; the underlying code path always installs a scheduled task, regardless of whether zeroclaw service install is run from an elevated or non-elevated shell.
zeroclaw service install
zeroclaw service start
This creates a task in Task Scheduler (taskschd.msc) under your user account that starts on login. Manage it via:
zeroclaw service status
zeroclaw service restart
zeroclaw service stop
zeroclaw service logs
About
--service-init. The CLI exposes a--service-init [auto|systemd|openrc]flag for cross-platform consistency, but on Windows it is a no-op; the scheduled-task path is always used.
Logs go to %USERPROFILE%\.zeroclaw\logs\ (specifically, <config_dir>/logs/ where <config_dir> defaults to %USERPROFILE%\.zeroclaw\). The scheduled-task wrapper itself, however, lives next to the config file at %USERPROFILE%\.zeroclaw\zeroclaw-daemon.cmd. Only the daemon output files (daemon.stdout.log / daemon.stderr.log) are written under logs\.
Server / multi-user installs. Native Windows Service / LocalSystem support is on the roadmap but not yet implemented. For now, on a server box, install ZeroClaw under the account that the agent should run as; the scheduled-task path will start it on that user's login. If you need it to start before any user logs in, use Task Scheduler → ZeroClaw Daemon → Properties → General → "Run whether user is logged on or not."
Re-run the PowerShell install block from Option 1 with the new $ver. The new zip overwrites the existing zeroclaw.exe in place. Then:
zeroclaw service restart
setup.batRe-download the latest release and re-run setup.bat --prebuilt (or whichever flag you used originally). Then:
zeroclaw service restart
scoop update zeroclaw # subject to the staleness caveat above
zeroclaw service restart
cd C:\path\to\zeroclaw
git pull
cargo install --locked --path . --force
zeroclaw service restart
Stop and remove the scheduled task:
zeroclaw service stop
zeroclaw service uninstall
Remove the binary:
:: Option 1 (manual prebuilt) or setup.bat
rmdir /s /q "%USERPROFILE%\.zeroclaw\bin"
:: Option 3 (cargo install)
del "%USERPROFILE%\.cargo\bin\zeroclaw.exe"
:: Option 4 (Scoop)
scoop uninstall zeroclaw
Remove config, workspace, and logs (optional; this deletes conversation history):
rmdir /s /q "%USERPROFILE%\.zeroclaw"
The previous version of this doc referenced
%LOCALAPPDATA%\ZeroClaw\; that path is not used by the current release; only%USERPROFILE%\.zeroclaw\is.
Long paths. Some Windows file systems still cap path lengths at 260 characters. Enable long path support if you hit path too long errors during a source build:
reg add HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v LongPathsEnabled /t REG_DWORD /d 1 /f
SmartScreen. The unsigned binary may trip SmartScreen on first launch from Explorer (double-click). Right-click → Properties → "Unblock" is the standard workaround until we add a signed MSI. Launching from PowerShell or cmd.exe typically does not trigger SmartScreen.
Task Scheduler stop-at-idle / battery. By default Windows may terminate scheduled tasks on idle or battery. The installed ZeroClaw Daemon task disables these conditions, but if you've installed via an older release you can verify under Task Scheduler → ZeroClaw Daemon → Properties → Conditions:
OpenSSH password auth. If you're driving Windows over SSH and pubkey isn't accepted, drop your key into C:\Users\<user>\.ssh\authorized_keys (regular user) or C:\ProgramData\ssh\administrators_authorized_keys (when logged in as a member of Administrators).