rupu documentation

rupu is an agentic code-development platform. You describe the work; agents and workflows do it — from the terminal, autonomously on triggers, or from a visual control plane.

Don't code it, rupu it. Define agents as plain Markdown, compose them into workflows, run them by hand or on triggers, and review everything with full transcripts and approvals.

Install

rupu is open source and no longer macOS-only. Every release ships prebuilt binaries for macOS (Apple Silicon) and Linux (x86_64 and aarch64), native .deb and .rpm packages, community packages (AUR, Homebrew, Nix), and a from-source build with Cargo on any platform with a Rust toolchain.

MethodPlatformCommand / asset
HomebrewmacOS · Linuxbrew install section9labs/tap/rupu
AURArch Linuxyay -S rupu-bin (or paru -S rupu-bin)
NixLinux · macOSnix run github:Section9Labs/rupu
.debDebian · Ubunturupu_<version>_amd64.deb · rupu_<version>_arm64.deb
.rpmFedora · RHELrupu-<version>-1.x86_64.rpm · rupu-<version>-1.aarch64.rpm
APT / YUM repoDebian · Ubuntu · Fedora · RHELhttps://rupu.sh/apt · https://rupu.sh/yum/stable
BinarymacOS, Apple Siliconrupu-darwin-arm64 — signed + notarized
BinaryLinux x86_64rupu-linux-x64 — static musl
BinaryLinux aarch64rupu-linux-arm64 — static musl
Cargoany (Rust 1.95+)cargo install --git https://github.com/Section9Labs/rupu

Every bare binary ships with a matching .sha256 sidecar on the latest release (also linked from the Download section). rupu shells out to ripgrep, so every package declares it as a dependency — install rg yourself if you take the bare binary.

Community packages. The AUR, Homebrew, and Nix paths are published from the stable release pipeline and are documented as becoming available with the first stable release after they landed. If one isn't resolving yet, use the prebuilt binary or the .deb / .rpm — check the README's Install section for the current status.

Homebrew (macOS or Linux)

brew install section9labs/tap/rupu

Arch Linux (AUR)

rupu-bin installs the published release binary (not a from-source build) and declares ripgrep as a dependency, matching the .deb / .rpm packages.

yay -S rupu-bin
# or
paru -S rupu-bin

Nix

# run it without installing
nix run github:Section9Labs/rupu

# or install into a profile
nix profile install github:Section9Labs/rupu

Direct binary (macOS or Linux)

Pick the asset for your platform — rupu-darwin-arm64, rupu-linux-x64, or rupu-linux-arm64 — then make it executable and put it on your PATH:

# macOS, Apple Silicon
chmod +x rupu-darwin-arm64
sudo mv rupu-darwin-arm64 /usr/local/bin/rupu

# Linux x86_64 (use rupu-linux-arm64 on aarch64)
chmod +x rupu-linux-x64
sudo mv rupu-linux-x64 /usr/local/bin/rupu

rupu --version

Linux packages (.deb / .rpm)

The packages declare their own dependencies and install shell completions (bash / zsh / fish) plus a man page (man rupu) alongside the binary — that's the reason to prefer them over the bare binary. Download the one matching your distro and architecture from the release page:

# Debian / Ubuntu
sudo apt install ./rupu_<version>_amd64.deb
# or, without apt's dependency resolution
sudo dpkg -i rupu_<version>_amd64.deb

# Fedora / RHEL
sudo dnf install ./rupu-<version>-1.x86_64.rpm
# or
sudo rpm -i rupu-<version>-1.x86_64.rpm

Any install can render the man page on demand — rupu man writes it to stdout, generated from the binary's own command tree, so it can never describe a CLI surface this build doesn't have.

Hosted APT / YUM repositories

rupu publishes signed APT and YUM repositories with every release, so you can install once and then upgrade in place with apt upgrade / dnf upgrade. Everything is signed with the key served from https://rupu.sh/rupu-archive-keyring.asc.

# Debian / Ubuntu — stable channel
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/rupu.asc https://rupu.sh/rupu-archive-keyring.asc
sudo chmod 644 /etc/apt/keyrings/rupu.asc
echo "deb [signed-by=/etc/apt/keyrings/rupu.asc] https://rupu.sh/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/rupu.list
sudo apt update && sudo apt install rupu
# Fedora / RHEL — stable channel
sudo rpm --import https://rupu.sh/rupu-archive-keyring.asc
sudo tee /etc/yum.repos.d/rupu.repo > /dev/null <<'EOF'
[rupu]
name=rupu
baseurl=https://rupu.sh/yum/stable
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://rupu.sh/rupu-archive-keyring.asc
EOF
sudo dnf install rupu

A beta channel is hosted at the same URLs (Suites: beta / baseurl=https://rupu.sh/yum/beta). Don't enable both channels without pinning: a version string like 0.70.4.beta sorts higher than 0.70.4 under both dpkg's and rpm's comparison, so an unpinned upgrade silently moves you onto beta and keeps you there. Each channel's index carries only the current release, so pinning an older version means downloading that release's package by hand. The full pinning recipes are in the README.

From source

Requires Rust 1.95 or newer.

cargo install --git https://github.com/Section9Labs/rupu

Keeping rupu up to date

A direct-binary install updates itself. rupu update fetches the latest build for your release channel, verifies its integrity against the published .sha256, swaps it in place, and keeps a backup of the previous binary so you can --rollback if anything looks wrong.

Packaged installs don't self-update. A binary that came from a native package (.deb / .rpm, including the APT/YUM repos) carries a build marker, and rupu update deliberately refuses to write over itself — the next apt upgrade / dnf upgrade would overwrite whatever it wrote, silently walking your version backwards. It tells you to run sudo apt upgrade rupu / sudo dnf upgrade rupu instead (it reads /etc/os-release to name the right one, and falls back to naming no command at all rather than the wrong one). rupu update --check still works everywhere, so you can always learn you're behind. The same rule of thumb applies to AUR, Homebrew, and Nix: upgrade through the manager that installed it — yay -Syu rupu-bin, brew upgrade rupu, nix profile upgrade.
# update to the latest release on your channel
rupu update

# report only — exits 10 if an update is available (handy in CI)
rupu update --check

# restore the previous binary from the last backup
rupu update --rollback

Other flags: --force reinstalls (or downgrades) to the channel's latest, and --channel beta|stable overrides the channel for a single run.

Release channels

Every release flows through two channels. A vX.Y.Z-beta prerelease is cut first, then promoted to a vX.Y.Z stable release.

ChannelWhat you get
stableFull releases. The default — pick this unless you want to help test.
betaPrereleases. Early access to features before they're promoted to stable.

Choose a channel for a single run with the flag, or set it once in your config. Channel precedence is --channel flag > [update] channel config > stable (the default).

# one-off: pull the latest beta
rupu update --channel beta
# config.toml — track the beta channel by default
[update]
channel = "beta"
# passive "update available" notice on normal commands (default: on)
check = true

Normal commands also surface a passive update available notice when you're behind; set check = false in the [update] section to silence it.

Your first run

Initialize rupu in a repo, authenticate a provider, then run an agent:

# scaffold .rupu/ (agents + workflows) in the current repo
rupu init

# connect a model provider (Anthropic, OpenAI, Gemini, Copilot…)
rupu auth login

# run a one-off agent against a prompt
rupu run code-reviewer --prompt "Review the diff on this branch"

Everything rupu does is recorded as a JSONL transcript you can inspect with rupu transcript.

The four building blocks

Read these in order — each builds on the last.

Then go further