Installing cctop
cctop runs on Linux, including WSL. It reads Linux process tables and drives agents over ptys and unix sockets, and there is no macOS or Windows build.
cctop is a single binary. It links no system libraries and needs no runtime, so
“installing” it means putting one file on your PATH. That includes the
multiplexer its tabs’ agents run in: rmux is built in, so there is no rmux or
tmux to install alongside it.
Let the script do it
curl -fsSL https://raw.githubusercontent.com/flolep2607/cctop/main/install.sh | sh
It works out your architecture from uname -m, fetches that archive from the
latest release, verifies it against the .sha256 published beside it, and
installs the binary into /usr/local/bin — or ~/.local/bin if that directory
is not yours to write, printing the line to add to your profile when the
fallback is not on your PATH either. sudo is used only if the install needs
it, and a sudo that cannot run (no tty, no askpass, no sudo at all) falls
back rather than stopping.
Then, if sshfs is missing, it offers to install it — what
cctop sandbox needs — with
[y/N], so pressing Enter changes nothing. The question is asked on the
terminal even under curl | sh, and skipped where there is none. To answer it
in advance:
curl -fsSL https://raw.githubusercontent.com/flolep2607/cctop/main/install.sh | CCTOP_WITH_SSHFS=1 sh
curl -fsSL https://raw.githubusercontent.com/flolep2607/cctop/main/install.sh | sh -s -- --with-sshfs
(CCTOP_WITH_SSHFS=0 or --without-sshfs to skip it.) It uses whichever of
apt-get, dnf, yum, pacman, zypper and apk it finds, through sudo unless you
are root, and prints the command before running it. A failed sshfs install is
reported and does not undo the cctop one.
Nothing is unpacked until the checksum has been checked, and a mismatch stops
the install instead of warning about it afterwards. To read it before running
it, curl -fsSLO it and look.
Download a binary by hand
A release ships two archives, x86_64 and aarch64, both statically linked against
musl — so either runs on any distro, glibc or not. Grab the one for your
architecture from the
latest release and put
cctop somewhere on your PATH:
# x86_64
d=$(mktemp -d)
curl -fsSL https://github.com/flolep2607/cctop/releases/latest/download/cctop-x86_64-unknown-linux-musl.tar.gz | tar xz -C "$d"
sudo install -m755 "$d/cctop" /usr/local/bin/cctop && rm -rf "$d"
# aarch64
d=$(mktemp -d)
curl -fsSL https://github.com/flolep2607/cctop/releases/latest/download/cctop-aarch64-unknown-linux-musl.tar.gz | tar xz -C "$d"
sudo install -m755 "$d/cctop" /usr/local/bin/cctop && rm -rf "$d"
The archive holds one file, called cctop, which is why each of these unpacks
into a temporary directory rather than into whatever directory you are standing
in. Run one inside a cctop checkout and tar stops at
Cannot open: File exists; the install that follows then finds the crate
directory where it expected the binary, reports omitting directory 'cctop',
and leaves nothing on your PATH.
Every archive ships with a .sha256 file next to it, named for the archive
rather than after it — cctop-x86_64-unknown-linux-musl.sha256, not
cctop-x86_64-unknown-linux-musl.tar.gz.sha256, which is a 404:
d=$(mktemp -d)
curl -fsSL -O --output-dir "$d" https://github.com/flolep2607/cctop/releases/latest/download/cctop-x86_64-unknown-linux-musl.sha256
curl -fsSL -O --output-dir "$d" https://github.com/flolep2607/cctop/releases/latest/download/cctop-x86_64-unknown-linux-musl.tar.gz
(cd "$d" && sha256sum -c cctop-x86_64-unknown-linux-musl.sha256)
Staying up to date
A downloaded binary has no package manager behind it, so cctop --update
fetches the newest release for your architecture and replaces the running
executable in place:
cctop --update
Replacing the binary needs write access to the directory it lives in. The install
above puts it in /usr/local/bin with sudo, so updating it needs sudo too:
sudo cctop --update
An update that lands prints what it brought, one heading per version crossed, so a machine three versions behind sees all three rather than only the newest:
Updated 0.7.0 -> 0.7.3.
What changed since 0.7.0:
0.7.1
- Codex accounts per subscription, and a tab you can close without losing
your place
0.7.2
- Fix the login hint for a named account, and add a run skill that drives
the TUI
0.7.3
- the signals between cctop and its agents stop getting lost
Full notes: https://github.com/flolep2607/cctop/releases
The notes come from the GitHub releases themselves, fetched after the binary is already in place — so a network that fails at that moment costs you the summary and not the update, and you get the link instead.
cctop checks for a new release once an hour in the background and, when one exists, says so in the footer. The next time you start it, it installs that release before opening: the version was already known, so nothing is waited on to discover it, and the download is the only pause. It then prints what changed, waits for you to press Enter, and starts as the new version.
Startup is the only moment it will do this. Nothing is open yet — no terminal held, no agent hosted, no pane to lose — so the new binary can simply take the place of the old one. That is not true of any later moment, which is why an update that becomes available while cctop is running waits for the next start rather than interrupting the one you are in.
A release counts once its binary for your machine is attached, so cctop never
offers one it cannot fetch yet. It installs a given version over a given binary
at most once: if that version is installed and the old one still starts, it says
so on each start instead of downloading again. Each update it attempts leaves a
line in update.log in the cache directory, which is the thing to attach to a
report about one that went wrong.
To start on the version you already have, pass --no-auto-update. To stop it
happening at all, set "auto_update": false in ui-prefs.json under your cache
directory (~/.cache/cctop); cctop --update still works whenever you want
it. cctop claude and the other
agent aliases skip it too — you are waiting on an agent, and a download between
the command and the agent starting is not what you asked for.
If cargo installed cctop, it asks instead of acting:
cctop 0.7.6 is out, and cargo installed this one (0.7.5) — replacing the binary
here would leave `cargo install --list` naming a version that is gone.
Run `cargo install cctop --version 0.7.6 --locked`? It builds from source. [y] update / [n] not now:
Answering y runs exactly that command, with cargo’s own output on screen, and
starts the new version when it finishes. The objection was never the file —
~/.cargo/bin is writable — but the bookkeeping, and cargo install is what
keeps cargo’s record straight. It builds from source, so it takes minutes, which
is why it is a question and not a default. With
cargo-binstall on your PATH
the command offered is cargo binstall cctop --version … --locked --no-confirm
instead, which fetches the release archive in seconds and keeps the same
record. Answering n is remembered against
that version and the question waits for the next release; cctop --update asks
again whenever you want it.
A package manager other than cargo is left alone entirely — cctop will not touch a binary something else is responsible for. Update it the way you installed it.
A cargo build output is left alone as well, for bookkeeping of a quieter kind:
cargo’s fingerprint sits beside target/debug/cctop and would go on calling
whatever replaced it the build it produced — the update would land, and
cargo build would report the file fresh and never put the real one back.
cargo install cctop --force is how the release reaches PATH.
With cargo
cargo binstall cctop
cargo-binstall downloads the
release archive, the same static binary the script installs, and records it
the way cargo install would — so nothing has to compile. Without binstall,
cargo builds it from crates.io:
cargo install cctop
Or straight from the repository, without waiting for a release:
cargo install --git https://github.com/flolep2607/cctop
From source
git clone https://github.com/flolep2607/cctop
cd cctop
cargo build --release
The binary lands at target/release/cctop. It links no system libraries and
needs no runtime — a single file you can copy anywhere.
Building requires Rust 1.89 or newer (the code uses let-chains and std’s file locks).