Skip to main content
Documentation menu

Getting started

Install

macOS and Linux (arm64 or x86_64):

sh
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:

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:

sh
# 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/chanto

Only 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:

sh
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.com

Both 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:

text
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAHk8ypq/plTuzCUZ4P9+bmwesZLkwM18CBO7AcUQLGd0=
-----END PUBLIC KEY-----

and, for ssh-keygen, packaging/release-allowed-signers:

text
chanto-release ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB5PMqav6ZU7swlGeD/fm5sHrGS5MDNfAgTuwHFECxnd

To check a download by hand, put SHA256SUMS, its signature, the archive and the key file in one folder, then, with OpenSSL 3 or later:

sh
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-missing

or with ssh-keygen (v0.1.5 and later):

sh
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-missing

The 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):

sh
cargo install chanto --locked

With npm (the package is @chanto/cli, which installs the chanto command and pulls in only your platform's binary):

sh
npm i -g @chanto/cli

With Homebrew (macOS and Linux):

sh
brew install chanto-sh/tap/chanto

Each 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 install command; a build in a source checkout is told to git pull and 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:

toml
[updates]
check = false

Requirements: 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.

Edit this page on GitHub Report a problem

Commands, settings, errors: type a few words.