Install-on-demand bootstrap
How an adapter ships spt-core with itself. The contract: the canonical
install one-liner is also every adapter’s pack-in installer — there is no
second mechanism, no vendored binary, no bespoke fetch logic to maintain.
Your adapter checks for spt, and runs the official script when it’s
missing.
The scripts are non-interactive by construction (they will never prompt), idempotent (safe to re-run), sha256-verify what they download, and register the user PATH. Served from the permanent canonical URL:
https://sabermage.github.io/spt-releases/install.shhttps://sabermage.github.io/spt-releases/install.ps1
The generic contract
if `spt` is on PATH -> done (optionally check `spt --version` ≥ your floor)
else -> run the official one-liner for the OS
then -> first invocation may need the absolute path (Windows)
After first install, spt-core keeps itself current (signed self-update) — the bootstrap never needs to handle upgrades.
Check-and-install: POSIX sh
Drop this into your adapter’s bootstrap (plugin install step, postinstall script, first-run guard):
if ! command -v spt >/dev/null 2>&1; then
echo "spt-core not found - installing..."
curl -fsSL https://sabermage.github.io/spt-releases/install.sh | sh
# current shell may not see the PATH update yet:
SPT="$HOME/.local/bin/spt"
else
SPT="spt"
fi
"$SPT" --version
Check-and-install: PowerShell
if (-not (Get-Command spt -ErrorAction SilentlyContinue)) {
Write-Output "spt-core not found - installing..."
irm https://sabermage.github.io/spt-releases/install.ps1 | iex
# The user-PATH registration only reaches NEW terminals -- use the
# absolute install path for everything in THIS process:
$spt = Join-Path $env:LOCALAPPDATA 'spt\bin\spt.exe'
} else {
$spt = 'spt'
}
& $spt --version
The Windows PATH-refresh gotcha
The installer registers the binary directory on the user PATH via the registry. Already-running processes — including the terminal (and your bootstrap) that just ran the installer — do not see registry PATH changes.
So: the first invocation after an install must use the absolute path
(%LOCALAPPDATA%\spt\bin\spt.exe; the installer prints it). Every new
terminal after that finds spt normally. The snippets above bake this in.
On Linux the equivalent (a ~/.profile entry the current shell hasn’t
sourced) is handled the same way: $HOME/.local/bin/spt absolutely, once.
Pinning and air-gapped installs
The scripts take environment knobs — never flags, so the pipe-to-shell form stays canonical:
| Env var | Meaning |
|---|---|
SPT_INSTALL_VERSION | Install a specific release tag instead of latest |
SPT_INSTALL_DIR | Override the install directory |
SPT_INSTALL_ASSET_BASE | A URL or local directory holding the release assets + SHA256SUMS directly (CI, air-gap, mirrors) |
SPT_INSTALL_NO_PATH | 1 = skip PATH registration |
Example — pin a version inside a CI job:
SPT_INSTALL_VERSION=v0.1.0 \
curl -fsSL https://sabermage.github.io/spt-releases/install.sh | sh
Trust model
First fetch trusts HTTPS + GitHub and verifies the binary’s sha256 against
the release’s SHA256SUMS. From then on, spt update performs full Ed25519
signature verification against the two-key trust anchor embedded in every
binary — the installer never needs to be the strong link twice.