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

# Install, pin and update

> Sign in, install the Synheart runtime, pin it with synheart.lock, run the CLI in CI, and keep the CLI up to date.

## Sign in

```bash theme={null}
synheart login            # OAuth device flow in your browser
synheart whoami           # the signed-in account, organization and plan
synheart auth status      # where credentials load from, and when they expire
synheart auth refresh     # force a token refresh (rarely needed)
synheart logout           # remove local credentials (add --revoke to revoke them on the server too)
```

`synheart login` prints a URL and a code, opens your browser (unless you pass `--no-browser`) and waits while you approve it. The CLI stores your tokens in the system keychain, or in `~/.synheart/credentials.enc` when no keychain is available. Commands that call the network (`install`, `sync`, `org`, `usage`) need a session. Commands that only touch your machine (`mock`, `local`, `receiver`, `doctor`, `version`) do not.

`synheart whoami`, `synheart usage` and the TUI refresh your plan and organization claims automatically when your sign-in is more than 5 minutes old, so an upgrade shows up without signing in again. `synheart auth refresh` forces a refresh if you ever need one.

If a command fails with an `SH-AUTH-*` code, run `synheart auth status`. It checks the credentials file, the keyring and the token expiry, and tells you which step failed. See [Errors and environment](/cli/errors) for each code.

## Install the runtime

The CLI manages the runtime artifact. You install the SDK packages themselves with your platform's package manager (pub.dev, Maven Central or Swift Package Manager).

```bash theme={null}
synheart login
synheart install runtime
synheart sync
synheart env
```

`synheart install` downloads artifacts from the Artifact Registry into your project's `synheart/vendor/` directory and records them in `synheart.lock`. The core runtime goes to `synheart/vendor/runtime/`, and every other package goes to `synheart/vendor/<package>/`.

Products are `syni` and `core`. Components are `runtime` and `spec`. Give one name to install everything it covers, or two to pin one package:

```bash theme={null}
synheart install syni                       # the Syni packages your plan includes
synheart install core                       # the core runtime
synheart install runtime                    # the runtime, for every product that ships it
synheart install runtime syni --version v0.2.0
```

### Channel, version and platform

```bash theme={null}
synheart install runtime --channel latest   # the default
synheart install runtime --version v1.2.3   # an exact version; overrides --channel
synheart install runtime --platform ios     # one platform only: ios or android
synheart install runtime --project-dir ../my-app
```

### Runtime variants

The runtime ships in three variants:

| Variant | Use |
| - | - |
| `edge` | The default build for most plans. |
| `stable` | Locked-down builds for production. |
| `lab` | Research and experimental builds. |

Without `--variant`, the server picks the variant your plan includes. Pass `--variant edge|stable|lab` to ask for one. If your account is not entitled to it, the install fails with `SH-INST-FORBIDDEN`.

```bash theme={null}
synheart install runtime --variant stable
```

The variant is recorded in `synheart.lock`, so `synheart sync` and `synheart runtime upgrade` stay on it.

### Inspect, upgrade or install from a local build

```bash theme={null}
synheart runtime current              # what synheart.lock pins; no network call
synheart runtime current --json
synheart runtime upgrade              # latest release of the variant you are on
synheart runtime install --from ../synheart-core-runtime/build/dist/core
```

`runtime current` exits 1 with `SH-RT-NOLOCK` when the project has no lockfile. `runtime install --from` copies a runtime you built yourself into `synheart/vendor/runtime/`, with no login or network.

## synheart.lock

`synheart install` writes `synheart.lock` in your project. It pins the exact version, variant and artifact hashes that were resolved. Commit it.

`synheart sync` reads the lockfile and installs exactly what it pins, with no new resolution:

```bash theme={null}
synheart sync                       # restore the pinned artifacts
synheart sync --project-dir ../app  # a project in another directory
```

If an artifact in the lockfile is no longer in the registry manifest, or its SHA-256 does not match, `sync` stops with `SH-INST-004` or `SH-INST-005` instead of installing something different. `synheart doctor` also checks that the vendored files still match the lockfile.

## CI/CD

For repeatable builds, commit `synheart.lock` and run `synheart sync` in CI. Sign in with a CI token, because the browser flow needs a person. Create the token in the dashboard and store it as a secret.

```yaml theme={null}
# .github/workflows/build.yml
- run: curl -fsSL https://synheart.sh/install | bash
- run: synheart login
  env:
    SYNHEART_CI_TOKEN: ${{ secrets.SYNHEART_CI_TOKEN }}
- run: synheart sync          # fails if the lockfile no longer matches the registry
- run: synheart doctor        # exits 1 if the runtime is missing, incompatible or modified
- run: flutter build apk
```

Set `SYNHEART_CI_TOKEN` in the environment. Passing `--ci-token` also works, but a flag is visible in process lists and shell history. Add `synheart update --check` if you want CI to flag a new CLI release: it exits 1 when one is available.

## Diagnose your setup

```bash theme={null}
synheart doctor               # environment, scenarios, runtime, sign-in and ports
synheart doctor --online      # also look for a newer runtime (needs login)
synheart env                  # paths, project type, signed-in account, pinned runtime
synheart version --build      # commit, build date and OS for a bug report
synheart explain hsi          # a plain-language primer; run it with no topic to list topics
```

`synheart doctor` reports each step as `ok`, `warn` or `error`. It exits 1 only when your app cannot work: the runtime is missing or incompatible, its files are missing or modified, or a library lacks functions its variant needs. Anything else, such as a busy port, an available update or being signed out, is reported without changing the exit code. Use `--port` to check a different port and `--project` to inspect another project.

`synheart env` reads only local state. It prints the Go version, OS, cache and config paths, the lockfile and vendor directory, the project type (`ios`, `android`, `flutter`, `multi` or `none`), app IDs, the signed-in account and the pinned runtime.

## Update the CLI

```bash theme={null}
synheart update             # check, ask, then replace the binary
synheart update --yes       # skip the prompt (required to apply in scripts and agent mode)
synheart update --check     # report only; exit 1 if a newer version exists
synheart update --rollback  # restore the binary you had before the last update
synheart update --force     # update even when a package manager manages the binary
synheart update --json      # report only, unless you also pass --yes
```

`synheart upgrade` is an alias. The CLI reads the release manifest from `https://dist.synheart.ai/synheart-cli/latest/manifest.json`, downloads the archive for your platform, verifies its SHA-256 against the manifest and swaps the binary in place. It saves the previous binary to `~/.synheart/bin/synheart.prev`, which `--rollback` restores.

`synheart update` refuses to run when a package manager (Homebrew, apt, Chocolatey or `go install`) manages the binary. Update with that package manager, or pass `--force`. On Windows, run the installer again. The installer scripts are also the way to recover a broken install:

* macOS and Linux: `curl -fsSL https://synheart.sh/install | bash`
* Windows (PowerShell): `iwr -useb https://synheart.sh/install.ps1 | iex`

After other commands, the CLI prints a one-line notice on stderr when a newer version is available. It checks at most once every 24 hours. The notice does not appear with `SYNHEART_NO_UPDATE_CHECK=1`, in CI, in agent mode or with `--json`. It is also skipped for `update`, `doctor`, `mcp` and `completion`.

If an update fails, you get `SH-UPD-APPLY` (the existing binary is left untouched) or `SH-NET-002` (the manifest could not be fetched). Both are safe to retry.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.