Skip to content

1ay1/agentty

Repository files navigation

agentty

Release Downloads License: MIT C++26

Blazing-fast Claude in your terminal. 8.8 MB binary, sub-millisecond cold start, sandboxed by default, SSH-airgap in one command.

A drop-in alternative to claude-code written in C++26 — no Node, no Python, no Electron, no npm install. Signs in with your Claude Pro/Max OAuth (or ANTHROPIC_API_KEY).

agentty streaming a turn with a tool call landing inline

Speed

Measured on the same Arch box, same shell, same day:

agentty (C++26) claude-code (Node)
Cold-start --help < 1 ms ~150 ms
--version < 1 ms ~60 ms
Binary on disk 8.8 MB 222 MB (+ Node runtime)
Install curl | chmod +x npm i -g + Node
GC pauses mid-stream None V8 GC

No JIT warmup, no require() graph to walk, no GC ticking while bytes stream in from the API. The TUI redraw loop is a poll(2) over the model stream + your input fd — every keystroke and every SSE chunk lands on the next frame.

Why

Four things the official client doesn't try to do:

  1. Native speed. C++26, statically linked, posix_spawn everywhere. Spawns in microseconds, no GC pauses mid-stream, no warmup. See the table above.
  2. One static binary. 8.8 MB. curl | chmod +x | run. No Node runtime, no npm install, no version drift between machines.
  3. Sandbox by default. Every shell and build call runs inside bwrap (Linux) / sandbox-exec (macOS). Workspace + system libs + network reachable; ~/.ssh, /etc, other projects read-only. An approved bash call still can't cat ~/.ssh/id_rsa.
  4. One-command SSH airgap. agentty airgap user@host runs the agent on a box with no direct internet — your laptop relays the bytes over SOCKS5-over-SSH. TLS pins on the real upstreams end-to-end.

Plus:

  • Workspace boundary. Filesystem tools refuse paths outside the launch directory (--workspace / opts out).
  • Inline render. Lives at the bottom of your terminal, preserves scrollback, doesn't take over the screen.
  • Reads like a single function. The reducer is one std::visit over a closed event sum; the permission matrix is a constexpr with static_asserts — change a policy cell and the build breaks, not a test nobody runs.

Install

One line. Same line to update.

curl -fsSL https://raw.githubusercontent.com/1ay1/agentty/master/install.sh | sh

Detects your OS and arch, downloads the right binary from the latest release, verifies SHA256, installs to /usr/local/bin (if root) or ~/.local/bin. Re-running the same command updates to the newest release. No apt, no brew, no version drift.

Flags: --prefix ~/somewhere, --version v0.1.0. Works on Linux + macOS, x86_64 + aarch64.

Distro-native packages — if you'd rather your package manager track it

Debian / Ubuntu

curl -fsSLO https://github.com/1ay1/agentty/releases/latest/download/agentty_0.1.0_amd64.deb
sudo dpkg -i agentty_0.1.0_amd64.deb       # or agentty_0.1.0_arm64.deb

Update: dpkg -i the new release's .deb.

Fedora / RHEL / openSUSE

sudo rpm -Uvh https://github.com/1ay1/agentty/releases/latest/download/agentty-0.1.0-1.x86_64.rpm

-U is upgrade; works for the first install too. Same command future-proofs the update path.

Arch Linux

yay -S agentty-bin                          # or paru, pikaur, etc.
yay -Syu agentty-bin                        # update

Or install the release-page .pkg.tar.zst with sudo pacman -U.

macOS (Homebrew)

brew tap 1ay1/tap
brew install agentty
brew upgrade agentty                        # update

Linux Homebrew gets the prebuilt static binary; macOS builds from source (~1 min).

Windows (Scoop)

scoop bucket add 1ay1 https://github.com/1ay1/scoop-bucket
scoop install agentty
scoop update agentty                        # update

Direct .exe: curl -L https://github.com/1ay1/agentty/releases/latest/download/agentty-windows-x86_64.exe -o agentty.exe.

Raw static binaries

Fully-static, no shared-library dependencies. Drop and run, replace on update:

curl -fsSL https://github.com/1ay1/agentty/releases/latest/download/agentty-linux-x86_64 -o agentty && chmod +x agentty
curl -fsSL https://github.com/1ay1/agentty/releases/latest/download/agentty-linux-aarch64 -o agentty && chmod +x agentty

Verify with SHA256SUMS on the release page.

From source

git clone --recursive git@github.com:1ay1/agentty.git
cd agentty && cmake -B build && cmake --build build -j
./build/agentty

Requires GCC 14+ / Clang 18+ / MSVC 14.40+ and CMake 3.28+.

Cut your own release — maintainer workflow, one script

Every published artifact is built locally, no CI:

scripts/bump.sh 0.2.0        # bumps CMakeLists, builds everything, tags, uploads via gh

Under the hood: rewrites project(agentty VERSION ...), commits the bump, builds deb/rpm/pkg.tar.zst/tarball/binaries/homebrew/scoop/AUR manifests via scripts/release.sh, tags vX.Y.Z, pushes, and gh release creates with every artifact attached. Single source of truth: CMakeLists.txt.

Or step-by-step:

scripts/release.sh                  # build every artifact into dist/, no upload
scripts/release.sh --tag v0.2.0     # build + tag + upload via gh

Quick start

cd path/to/your/project   # cwd is the workspace root
agentty

First launch opens an auth modal:

  • OAuth (Claude Pro/Max). Opens your browser; the callback writes the token to ~/.config/agentty/credentials.json (0600). agentty picks the right header on relaunch automatically.
  • API key. Paste an sk-ant-… token. Saved to the same file.

OAuth against your existing Pro/Max subscription is the main path — no extra billing, same account you already pay for.

Override order, highest priority first:

  1. -k <key> / --key <key> — single-session, never written to disk.
  2. ANTHROPIC_API_KEY env var.
  3. CLAUDE_CODE_OAUTH_TOKEN env var.
  4. The on-disk creds from the modal.

Then you're in a thread. Type, hit Enter. Mid-stream typing queues your next message and lands it when the current turn finishes. Esc cancels.

You start in the Ask profile — writes, shell calls, and network calls each prompt before running. S-Tab cycles to Write (autonomous) or Minimal (prompts for everything but pure reads). Choice persists.

Threads live at ~/.agentty/threads/<workspace-hash>/, one JSON file each — safe to inspect, back up, delete. ^J opens the thread list.

agentty --workspace ~/code/other-project   # run against a different workspace without cd
agentty status                              # which auth source will be used
agentty login / logout                      # non-interactive auth, useful over SSH
agentty airgap user@host                    # see below

Keys

Enter      send                   ^K     command palette
Alt+Enter  newline                ^J     thread list
Ctrl+E     expand composer        ^T     todo / plan
Esc        cancel / reject        ^/     model picker
S-Tab      cycle profile          ^N     new thread
                                  ^C     quit

Tools

Each tool gets a purpose-built widget: diffs render as diffs, search results group by file with line numbers, bash shows exit codes, todos become checklists.

read, write, edit, bash, grep, glob, list_dir, find_definition, web_fetch, web_search, todo, diagnostics, git_status, git_diff, git_log, git_commit, remember, forget.

Air-gapped hosts (SSH tunnel)

Run agentty on a box that can't reach the internet directly. Your laptop relays the bytes; TLS pins on the real upstreams, so the network between laptop and remote can't MITM you.

One command, from the laptop that does have internet:

agentty airgap --setup user@airgapped-host    # first time: also copies your credentials
agentty airgap user@airgapped-host            # every time after

How: ssh -R 1080 exposes a SOCKS5 proxy on the remote at localhost:1080; connections to it tunnel back over SSH and are dialed by your laptop. The remote agentty gets AGENTTY_SOCKS_PROXY=localhost:1080 and routes every TCP destination through it — chat, OAuth refresh, web_fetch, web_search. One env var, no per-host enumeration.

Trust model. Airgap doesn't trust the network between laptop and remote, but does trust the remote with your tokens — --setup copies credentials.json over at chmod 600. A compromised remote can exfiltrate your Anthropic credentials independent of the tunnel. Use it on hosts you'd already trust with the same secret.

Bare-metal version, if you'd rather not use the wrapper:

ssh -t -R 1080 user@airgapped-host \
    'AGENTTY_SOCKS_PROXY=localhost:1080 agentty'

Requires OpenSSH ≥ 7.6 on both ends (October 2017 — every distro has it). AGENTTY_AIRGAP_SSH injects extra ssh flags; --remote-agentty PATH if it isn't on the remote PATH.

Behind a TLS-terminating corporate proxy

SOCKS keeps TLS end-to-end, so cert verification works untouched. Different story if you route through a forward proxy that re-encrypts with its own cert (Zscaler, Bluecoat, mitmproxy). Install the proxy's CA into the system trust store (update-ca-certificates on Debian, update-ca-trust on Fedora) — agentty picks up system roots at startup. As a last resort, AGENTTY_INSECURE=1 skips peer verification entirely; don't ship that to anyone you care about.

How it compares

agentty claude-code aider
Language / runtime C++26 — single static binary TypeScript / Node Python
Footprint ~9 MB npm + Node runtime pip + Python runtime
Air-gapped mode Yes (agentty airgap, SOCKS5/SSH) No No
Auth OAuth (Pro/Max) + ANTHROPIC_API_KEY OAuth + ANTHROPIC_API_KEY per-provider env vars
Models Claude (Anthropic) Claude (Anthropic) many (OpenAI / Anthropic / local …)

Want a multi-model agent across providers? aider. Want Anthropic's first-party experience with their support behind it? claude-code. agentty is the niche pick when you specifically want a single-binary Claude client with no runtime dependency, or you need an air-gapped host through an SSH tunnel.

How it works

Pure-functional update loop: (Model, Msg) -> (Model, Cmd). Strong ID newtypes (ToolCallId, ThreadId, OAuthCode, PkceVerifier) — swapping arguments is a compile error, not a debugging session.

View is a single function Model -> Element. Rendering is delegated to maya, a sister header-mostly TUI engine — agentty builds widget Configs from Model state, maya owns every chrome glyph, layout decision, and breathing animation. The host constructs no Elements.

Subprocess uses posix_spawn + poll(2) with in-process SIGTERM → SIGKILL deadlines on POSIX, CreateProcessW + a reader thread on Windows — no GNU timeout dependency, no popen quoting hazards. File writes are atomic (write + fsync/_commit + rename/MoveFileExW).

Deep dive: docs/RENDERING.md walks the view pipeline turn-by-turn; docs/UI.md is the per-widget Config reference.

Standalone build

cmake -B build -DAGENTTY_STANDALONE=ON

Statically links OpenSSL + nghttp2 + libstdc++ + libgcc when their .a archives are installed. libc stays dynamic on Linux/macOS (fully-static glibc breaks getaddrinfo and the NSS resolver). Pass -DAGENTTY_FULLY_STATIC=ON with a musl toolchain for a 100% static binary. Windows: implies /MT and pulls third-party libs from the x64-windows-static vcpkg triplet.

Accurate one-liner: statically linked except libc and (usually) OpenSSL. For a 100%-static drop-in, the latest release ships pre-built agentty-linux-x86_64 and agentty-linux-aarch64 with zero shared-library dependencies (Alpine + musl + GCC 14.2).

Status

Works on Linux, macOS, and Windows — all three actively tested and built daily. Prebuilt release binaries for Linux (x86_64, aarch64) and Windows (x86_64); macOS builds from source in seconds.

File bugs with $TERM, your terminal emulator name, and a screenshot. Code-path bugs welcome too — paste the relevant block and git rev-parse HEAD.

License

MIT — see LICENSE.

About

Blazing-fast Claude in your terminal. 8.8 MB binary, sub-millisecond cold start, sandboxed by default, one-command SSH airgap. C++26 alternative to claude-code — no Node, no Python, no Electron.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors