Install¶
You need:
| Requirement | How to get it |
|---|---|
| macOS or Linux | macOS on Apple silicon or Intel; Linux on x86-64 or arm64 with glibc 2.35 or newer (Ubuntu 22.04+, Debian 12+). Tested on macOS (Apple silicon) with OrbStack and on Ubuntu 24.04 (arm64) with Docker Engine; Docker Desktop and x86-64 are untested |
| Docker with BuildKit, running | macOS: OrbStack or Docker Desktop. Ubuntu: sudo apt install docker.io docker-buildx, then add yourself to the docker group |
curl and tar |
Preinstalled on macOS and most Linux distributions |
| About 10 GB free disk | The images take about 4 GB; the gateway's Rust build inside Docker takes most of the rest |
Then run the installer:
curl -fsSL https://raw.githubusercontent.com/sayre4ux/capscode/main/scripts/install.sh | bash
The installer:
- Checks every requirement above and lists anything missing with the command that fixes it, before it changes anything.
- Downloads the newest release binary for your platform and the matching image build files,
checks both against the release's
SHA256SUMS, and installs the binary as~/.local/bin/capscode(the build files go to~/.capscode/build/<version>/). It tells you if that directory is not on yourPATH. - Builds the container images with
capscode toolchain build. The first build is the slow step: it downloads the base images and every tool. Later runs reuse Docker's cache. No Rust toolchain is needed on your machine; the gateway's broker compiles inside Docker. - Runs
capscode initto set up tools, credentials, provider defaults, and shell completion. - Runs
capscode doctor --quickand prints what to do next.
Install with the installer rather than a browser download. curl sets no macOS quarantine
flag, so Gatekeeper does not block the binary; a browser download is quarantined and blocked.
macOS keychain: one "Always Allow" per CLI update. The macOS binary is ad-hoc signed:
CapsCode has no Apple Developer ID and is not notarized. macOS identifies an ad-hoc signed
program by its exact build, so the first command that reads a stored key after an install or a
CLI update asks for keychain access. Choose Always Allow, in a terminal (an agent's shell
gets no prompt and capscode doctor then reports keychain access denied). Toolchain updates
do not change the binary and do not prompt.
Checking the download yourself. Pass --verify-attestation to also require a GitHub
artifact attestation from this repository's release workflow for the binary and the build
files. It needs the GitHub CLI and fails if the check cannot run:
curl -fsSL https://raw.githubusercontent.com/sayre4ux/capscode/main/scripts/install.sh | bash -s -- --verify-attestation
Useful options (after bash -s -- when piping):
| Option | Effect |
|---|---|
--check |
Only check the requirements; change nothing |
--version <x.y.z> |
Install that release instead of the newest one |
--verify-attestation |
Also verify the GitHub attestation with gh (see above) |
--bin-dir <dir> |
Install the binary somewhere other than ~/.local/bin |
--skip-images |
Skip the image build (run capscode toolchain build later) |
--skip-init |
Skip capscode init (run it later in a terminal) |
--skip-doctor |
Skip the final capscode doctor --quick |
--yes |
Never prompt: runs capscode init --yes --no-completions |
--binary / --from-source |
Choose the install method explicitly (see below) |
Installing with an AI coding agent? Ask it to follow BOOTSTRAP.md. That file tells the agent what it may do on its own and what it must leave to you, such as entering API keys.
Install from source¶
Building from source needs, in addition to Docker: git, Rust 1.98 or newer
(rustup.rs, or rustup update stable), a C compiler (macOS:
xcode-select --install; Debian/Ubuntu: sudo apt install build-essential), and about 15 GB of
free disk. Clone and run the installer from the checkout:
git clone https://github.com/sayre4ux/capscode.git && cd capscode
./scripts/install.sh
Inside a checkout the installer builds the CLI (cargo build --locked --release, under a minute
on a recent Mac), links it to ~/.local/bin/capscode, builds the images with
./scripts/build-images.sh, and then runs capscode init and capscode doctor --quick as above.
Run it again after git pull to update. --from-source forces this method and --binary forces
the download even inside a checkout.
Manual install, without the installer
cargo build --locked --release
mkdir -p "$HOME/.local/bin"
ln -sfn "$PWD/target/release/capscode" "$HOME/.local/bin/capscode"
hash -r
./scripts/build-images.sh
capscode init
After install, capscode init can be re-run at any time. For an unattended setup, use
capscode init --yes; add --no-completions to leave shell startup files alone. For example,
configure Claude and Codex without network credential probes:
capscode init --yes --tool claude --tool codex --no-probe
build-images.sh builds the capsule base, five tool images, the merged all-tools image,
and the gateway image (including its Rust broker build). The merged image includes every tool
plus tmux, Chromium, and playwright-core; it is about 2.4 GB. The first build takes a while.
The script stops with a non-zero exit status if any image fails to build, and it verifies each
tool's npm tarball against the integrity hash pinned in images/toolchain.lock.toml. The CLI
never pulls missing capscode/* images from a registry; it tells you to run
capscode toolchain build instead, which runs this script from your checkout or, for a binary
install, from ~/.capscode/build/<version>/.
Tool images use pinned tool versions, and the merged image tag identifies the full toolchain.
Supply chain. CapsCode publishes no images; you build them from this repository's files
(a binary install downloads them as the release's build context). Base
images are pinned by digest, and each tool by version and tarball hash. A tool's own
dependencies are not pinned one by one: they install with npm install --before=<time>, where
the time is the pin's resolved_before in images/toolchain.lock.toml. bump-tool.sh normally
selects the newest release on that tool's npm dist-tag channel only after it has been published
for at least three days, and gives dependencies the same three-day cooldown. A maintainer can
record a reason with --waive-cooldown; waived dependencies resolve as of the bump time. The
tarball integrity hash is read from the same npm registry for that exact package version. This
does not help if a dependency was already malicious when the pin was set, and Debian packages
float with the Debian index. See the threat model
for what a poisoned package could reach.