macOS and Linux (arm64 or x86_64):
curl -fsSL https://chanto.sh/install.sh | sh
# Pin a release or change the install prefix (binary goes in PREFIX/bin):
curl -fsSL https://chanto.sh/install.sh | sh -s -- --version v0.1.4 --prefix "$HOME/.local"Windows x64, in PowerShell:
irm https://chanto.sh/install.ps1 | iex
# For options, download install.ps1, then:
./install.ps1 -Version v0.1.4 -Prefix "$env:LOCALAPPDATA/chanto"The shell installer defaults to ~/.local/bin; PowerShell defaults to
$env:LOCALAPPDATA/chanto/bin. Add that directory to PATH as advised.
Both check the release signature (see Verifying a release)
and then the archive against the release's SHA256SUMS before replacing the
binary. The shell installer supports curl or wget and requires tar and either
sha256sum or shasum. Linux binaries use static musl. Windows uses ZIP archives;
macOS and Linux use chanto-vX.Y.Z-<target>.tar.gz. Each v* tag publishes them,
with SHA256SUMS, as a GitHub release;
https://chanto.sh/releases/download/<version>/<file> redirects there, and the
download page links them. Release archives also
carry build provenance attestations (gh attestation verify <file> -R chanto-sh/chanto).
Container image
Releases after v0.1.5 also publish a container image for linux/amd64 and
linux/arm64 to GitHub's registry, as ghcr.io/chanto-sh/chanto:<version>
(for example 0.1.6) and :latest. It isn't a separate build: it holds the
release's own static Linux binary, checked against the signed SHA256SUMS
first, on Debian stable-slim with git, ripgrep, bash, coreutils and CA
certificates. It runs as the non-root user chanto (uid 1000) in /work,
and its entrypoint is chanto:
# A print run on the current directory
docker run --rm -it -v "$PWD:/work" -e OPENAI_API_KEY ghcr.io/chanto-sh/chanto -p "fix the failing test"
# The TUI, keeping config, sessions and memory in a volume between runs
docker run --rm -it -v "$PWD:/work" -v chanto-home:/home/chanto/.chanto \
-e ANTHROPIC_API_KEY ghcr.io/chanto-sh/chantoOnly what you pass reaches the container: forward provider keys with -e,
and without a volume at /home/chanto/.chanto each --rm run starts with no
config or sessions. On Linux, files written into /work belong to uid 1000;
if that isn't your uid, add --user "$(id -u):$(id -g)" -e HOME=/tmp. The
update check is off in the image (CHANTO_NO_UPDATE_CHECK=1): pull a newer
tag rather than running chanto upgrade. To add a project's toolchain, build
FROM ghcr.io/chanto-sh/chanto:<version> and install it as root, then switch
back with USER chanto.
The sandbox inside a container. On Linux the OS sandbox is Landlock (see
Sandbox), and in a container it may be limited or missing: it
needs the host kernel to support Landlock (5.13+, ABI v4 for
network = "deny" or "allowlist") and the engine's seccomp profile to allow
its system calls. Where it can't be applied, Chanto warns at startup and runs
commands unsandboxed (a deny or allowlist network setting fails closed
instead), so the container itself is the boundary: mount only the project and
give it only the keys and network it needs. To run Chanto on the host and
only its commands in a container, see Container isolation.
Verifying the image. Each image carries build provenance and a keyless
cosign signature, both made by the release
workflow for a v* tag:
gh attestation verify oci://ghcr.io/chanto-sh/chanto:0.1.6 --owner chanto-sh
cosign verify ghcr.io/chanto-sh/chanto:0.1.6 \
--certificate-identity-regexp '^https://github\.com/chanto-sh/chanto/\.github/workflows/release\.yml@refs/tags/v' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comBoth check the image's digest; pin ghcr.io/chanto-sh/chanto@sha256:<digest>
to keep using exactly the one you verified. The Dockerfile is
packaging/docker/Dockerfile.
Verifying a release
From v0.1.2 on, every release's SHA256SUMS is signed with the project's
Ed25519 release key, and the signature is published next to it as
SHA256SUMS.sig (base64). From v0.1.5 on, the same key's signature is also
published in SSH form as SHA256SUMS.sshsig, which ssh-keygen can check
where no OpenSSL 3 is installed (stock macOS ships LibreSSL, which can't verify
Ed25519; Windows ships the OpenSSH client). chanto upgrade refuses a release
whose signature is missing or doesn't verify. The install scripts check the
signature before they use anything in SHA256SUMS, including the version
"latest" names: with OpenSSL 3 if there is one (on macOS, also Homebrew's
openssl@3; on Windows, also the one in Git for Windows), otherwise with
ssh-keygen (OpenSSH 8.1+). They stop if the signature is missing or wrong, or
if neither tool is there; on stock macOS or Windows without OpenSSL 3, that
means releases before v0.1.5, which have no SHA256SUMS.sshsig, can't be
installed by script. Releases before v0.1.2 aren't signed and can't be
installed by script at all. A signature can't show that a release is the
newest, so the scripts also refuse a "latest" older than the floor they carry
(currently v0.1.6, raised with each security release), in case the download
host serves an old release; an older release asked for with --version /
-Version still installs, with a warning. The public key is
packaging/release-signing-key.pub:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAHk8ypq/plTuzCUZ4P9+bmwesZLkwM18CBO7AcUQLGd0=
-----END PUBLIC KEY-----and, for ssh-keygen, packaging/release-allowed-signers:
chanto-release ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5PMqav6ZU7swlGeD/fm5sHrGS5MDNfAgTuwHFECxndTo check a download by hand, put SHA256SUMS, its signature, the archive and
the key file in one folder, then, with OpenSSL 3 or later:
openssl base64 -d -A -in SHA256SUMS.sig -out SHA256SUMS.sig.bin
openssl pkeyutl -verify -pubin -inkey release-signing-key.pub -rawin \
-in SHA256SUMS -sigfile SHA256SUMS.sig.bin # prints "Signature Verified Successfully"
shasum -a 256 -c SHA256SUMS --ignore-missing # or: sha256sum -c SHA256SUMS --ignore-missingor with ssh-keygen (v0.1.5 and later):
ssh-keygen -Y verify -f release-allowed-signers -I chanto-release -n chanto-release \
-s SHA256SUMS.sshsig < SHA256SUMS # prints 'Good "chanto-release" signature ...'
shasum -a 256 -c SHA256SUMS --ignore-missingThe private key never leaves the release workflow's secrets and an offline backup.
To build from a checkout (needs Rust 1.95+), run ./install.sh --from-source; it
builds a release binary and installs it like the installer. Cargo can also
build a release from crates.io (installs to Cargo's bin directory):
cargo install chanto --lockedWith npm (the package is @chanto/cli, which installs the chanto command and
pulls in only your platform's binary):
npm i -g @chanto/cliWith Homebrew (macOS and Linux):
brew install chanto-sh/tap/chantoEach release renders the formula from packaging/homebrew/chanto.rb (version
and archive checksums), uploads it as a homebrew-formula artifact, and pushes
it to the chanto-sh/homebrew-tap
repository with a deploy key that can write to that repository only
(HOMEBREW_TAP_DEPLOY_KEY). A fork without that secret skips the push.
chanto upgrade moves to the latest release the way Chanto was installed, and
never without asking (--yes skips the question; --check only reports; --force
reinstalls the latest release):
- Installer (install.sh / install.ps1): downloads the release archive for your
platform, verifies it against the release's
SHA256SUMS, checks that the new binary runs, then replaces the old one (removed, then the new one moved into place). On a mismatch or any failure the old binary stays. - Homebrew: offers to run
brew upgrade chanto. - Cargo: prints the
cargo installcommand; a build in a source checkout is told togit pulland rebuild. If the install method can't be told, nothing is replaced and Chanto says how to install a release.
/upgrade in a session reports whether a newer release exists and the command
to run.
Interactive and print sessions check for stable release updates in the background,
at most once per day, with a two-second timeout. The single request is
GET https://chanto.sh/releases/latest, with a Chanto
version User-Agent; it sends no prompts, keys, or project data. Results and failed
attempt timestamps are cached in ~/.chanto/update-check.json (or
$CHANTO_HOME/update-check.json). A newer release produces one dim TUI line or
an stderr line after a print run, with the appropriate Homebrew, Cargo, or
chanto upgrade command. Very short runs may exit before a notice is ready.
Checks never run when CI is set. Disable them with CHANTO_NO_UPDATE_CHECK=1
or in your configuration:
[updates]
check = falseRequirements: a model, either a hosted provider (a key or login) or a local server such as Ollama (ollama serve) or another OpenAI-compatible one. rg (ripgrep) is used when present. pdftotext is needed for PDF reads, and Chrome/Chromium for the Browser tool.