> ## Documentation Index
> Fetch the complete documentation index at: https://tesser.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Install and update

> The install script, the release API behind it, and pinning a release by hash in CI

## Install

```sh theme={"theme":"css-variables"}
curl -fsSL https://tesser.sh/install | sh
```

The script installs `tesser` to `~/.tesser/bin` and adds that directory to
your shell's rc file. To install a specific release:

```sh theme={"theme":"css-variables"}
curl -fsSL https://tesser.sh/install | sh -s -- v0.31.0
```

`tesser update` installs the latest release over the running binary and
restarts the daemon on it; `tesser update v0.31.0` installs that release.

## Release API

`https://install.tesser.sh` serves the install script and answers the
questions it asks. Every response is plain text.

| Request                            | Response                                                                    |
| ---------------------------------- | --------------------------------------------------------------------------- |
| `GET /`                            | The install script.                                                         |
| `GET /latest`                      | The newest stable version, for example `v0.31.0`.                           |
| `GET /<version>/<target>/sha`      | The sha256 of that release's tarball for that target.                       |
| `GET /<version>/<target>/download` | A redirect to the tarball, which holds one file: `tesser`.                  |
| `GET /<version>/manifest.json`     | The release's manifest: version, commit, and each target's sha256 and size. |
| `GET /<version>/manifest.json.sig` | The manifest's ed25519 signature, base64.                                   |

`<target>` is one of `darwin-arm64`, `darwin-x64`, `linux-x64`,
`linux-x64-baseline` (x64 CPUs without AVX2), and `linux-arm64`. A version or
target that does not exist returns 404. A published release never changes.

## How updates are verified

Every release's manifest is signed with Tesser's release key, and the public
half is compiled into the CLI. `tesser update` downloads the manifest and its
signature, refuses a manifest the key did not sign, and checks the tarball
against the sha256 in the signed manifest. Anyone who could change what
install.tesser.sh or the download store serves still could not get an
installed CLI to update to a build we did not sign.

The install script does not check the signature: it trusts the sha256 that
install.tesser.sh serves, like any `curl | sh` installer. To remove that trust
from CI, pin the hash as below.

## Pin a release in CI

To trust nothing but a hash in your own repository, hardcode the target and
the sha256, and check the download against it:

```yaml theme={"theme":"css-variables"}
- name: Install tesser
  run: |
    curl -fsSL https://install.tesser.sh/v0.31.0/linux-x64/download -o tesser.tar.gz
    echo "<sha256>  tesser.tar.gz" | sha256sum -c -
    tar -xzf tesser.tar.gz -C /usr/local/bin tesser
    tesser version
```

Get the value for `<sha256>` once from
`https://install.tesser.sh/v0.31.0/linux-x64/sha`.
