tula

Install

One file, and nothing else to install beside it.

install
curl --proto '=https' --tlsv1.2 -LsSf https://hsnice16.github.io/tula/install.sh | sh
--proto '=https'
Only HTTPS, on redirects too
--tlsv1.2
Nothing older than TLS 1.2
-L
Follow a redirect
-s
No progress bar
-S
But still show errors
-f
Stop on an HTTP error, so an error page is never piped into a shell

This pipes a script into a shell, so read it before you run it. install.sh is what the command fetches, copied straight from the one in the repo — the same file, and the one every test runs against.

Every install is checked

Published checksum

Always. Refuses a download that does not match.

Build attestation

Sigstore-backed, keyless. Refuses a binary this repo did not build — where the GitHub CLI is installed and signed in to check it.

Versioned installs

~/.tula/versions, behind a symlink. Going back is a link flip.

What it runs on

macOSYesIntel and ARM, 64-bit.
LinuxYesIntel and ARM, 64-bit. Needs glibc.
Alpine, or any musl LinuxNoThe installer says so and stops.
WindowsThrough WSLInstall inside WSL, where it is Linux. There is no native build.

Other channels

The same binary. Homebrew serves the attested archive; npm repackages it, so its tarball carries no attestation — verify through Homebrew or the install script.

homebrew
brew install hsnice16/tap/tula
npm
npm install -g @tula/cli

Verify it yourself

verify
curl -fLO https://github.com/hsnice16/tula/releases/download/v0.1.0/tula-v0.1.0-darwin-arm64.tar.gz
gh attestation verify tula-v0.1.0-darwin-arm64.tar.gz --repo hsnice16/tula

A checksum served beside a file only proves it is intact. This proves who built it. The attestation covers the archive, not the binary inside it, and the installer keeps no copy — so the download is the first step, not a repeat of one.

You need the GitHub CLI, signed in with gh auth login. It will not fetch an attestation without a token, even for a public repository.

Where it puts things

Everything lives under ~/.tula. Each version goes in its own folder, and ~/.tula/bin/tula is a link to the one you are running. Your keys are kept somewhere else, ~/.config/tula, so a reinstall never touches them.

If ~/.tula/bin is not on your PATH, the installer adds a line to your zsh, bash or fish profile and tells you which file it changed. Under any other shell it prints the line for you to add and edits nothing. Set TULA_NO_MODIFY_PATH=1 and it prints rather than edits, whatever your shell.

To install one exact version instead of the newest, set TULA_VERSION. Pin it that way in CI, and set TULA_REQUIRE_ATTESTATION=1 to make a missing provenance check a refusal rather than a warning.

Update, go back, remove

To update, run the install command again.

update
curl --proto '=https' --tlsv1.2 -LsSf https://hsnice16.github.io/tula/install.sh | sh

Old versions stay where they are, so going back to one is a link flip and not another download.

go back
ln -sf ~/.tula/versions/<version>/tula ~/.tula/bin/tula

To remove tula, delete both folders — the second one holds the keys you saved — and the line the installer added to your shell profile.

remove
rm -rf ~/.tula ~/.config/tula