{"id":50722044,"url":"https://github.com/1ay1/agentty","last_synced_at":"2026-06-10T01:01:54.132Z","repository":{"id":353087895,"uuid":"1213491458","full_name":"1ay1/agentty","owner":"1ay1","description":"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.","archived":false,"fork":false,"pushed_at":"2026-06-05T23:00:32.000Z","size":18311,"stargazers_count":18,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-06T00:18:54.612Z","etag":null,"topics":["agentic-coding","ai-agent","airgap","anthropic","claude","claude-code","claude-code-alternative","cli","coding-agent","cpp","cpp26","developer-tools","llm","sandbox","static-binary","terminal","tui"],"latest_commit_sha":null,"homepage":"https://agentty.org","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/1ay1.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-17T12:44:40.000Z","updated_at":"2026-06-05T23:00:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/1ay1/agentty","commit_stats":null,"previous_names":["1ay1/moha","1ay1/agentty"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/1ay1/agentty","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1ay1%2Fagentty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1ay1%2Fagentty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1ay1%2Fagentty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1ay1%2Fagentty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/1ay1","download_url":"https://codeload.github.com/1ay1/agentty/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/1ay1%2Fagentty/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34132030,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-coding","ai-agent","airgap","anthropic","claude","claude-code","claude-code-alternative","cli","coding-agent","cpp","cpp26","developer-tools","llm","sandbox","static-binary","terminal","tui"],"created_at":"2026-06-10T01:01:53.464Z","updated_at":"2026-06-10T01:01:54.116Z","avatar_url":"https://github.com/1ay1.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentty\n\n[![Release](https://img.shields.io/github/v/release/1ay1/agentty?display_name=tag\u0026color=blue)](https://github.com/1ay1/agentty/releases/latest)\n[![Downloads](https://img.shields.io/github/downloads/1ay1/agentty/total?color=brightgreen)](https://github.com/1ay1/agentty/releases)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![C++26](https://img.shields.io/badge/C%2B%2B-26-00599C)](https://en.cppreference.com/w/cpp/26)\n\n**Blazing-fast Claude in your terminal. 8.8 MB binary, sub-millisecond cold start, sandboxed by default, SSH-airgap in one command.**\n\nA 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`).\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/1ay1/agentty/master/agentty.gif\" alt=\"agentty streaming a turn with a tool call landing inline\" width=\"800\" /\u003e\n\u003c/p\u003e\n\n## Speed\n\nMeasured on the same Arch box, same shell, same day:\n\n|                       | agentty (C++26)        | claude-code (Node) |\n|-----------------------|------------------------|--------------------|\n| Cold-start `--help`   | **\u003c 1 ms**             | ~150 ms            |\n| `--version`           | **\u003c 1 ms**             | ~60 ms             |\n| Binary on disk        | **8.8 MB**             | 222 MB (+ Node runtime) |\n| Install               | `curl \\| chmod +x`     | `npm i -g` + Node  |\n| GC pauses mid-stream  | None                   | V8 GC              |\n\nNo 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.\n\n## Why\n\nFour things the official client doesn't try to do:\n\n1. **Native speed.** C++26, statically linked, `posix_spawn` everywhere. Spawns in microseconds, no GC pauses mid-stream, no warmup. See the table above.\n2. **One static binary.** 8.8 MB. `curl | chmod +x | run`. No Node runtime, no `npm install`, no version drift between machines.\n3. **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`.\n4. **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.\n\nPlus:\n\n- **Open-standard skills.** Full [Agent Skills](https://agentskills.io) implementation — three-tier progressive disclosure, `.agents/` + `.claude/` interop so your existing Claude Code skills work unchanged. Teach it your internal codebase or DSL once; every session starts pre-loaded. See [Skills](#skills--teach-it-your-codebase-once).\n- **Workspace boundary.** Filesystem tools refuse paths outside the launch directory (`--workspace /` opts out).\n- **Inline render.** Lives at the bottom of your terminal, preserves scrollback, doesn't take over the screen.\n- **Reads like a single function.** The reducer is one `std::visit` over a closed event sum; the permission matrix is a `constexpr` with `static_assert`s — change a policy cell and the build breaks, not a test nobody runs.\n\n## Install\n\nOne line. Same line to update.\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/1ay1/agentty/master/install.sh | sh\n```\n\nDetects 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.\n\nFlags: `--prefix ~/somewhere`, `--version v0.1.0`. Works on Linux + macOS, x86_64 + aarch64.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDistro-native packages\u003c/b\u003e — if you'd rather your package manager track it\u003c/summary\u003e\n\n### Debian / Ubuntu\n\n```bash\ncurl -fsSLO https://github.com/1ay1/agentty/releases/latest/download/agentty_0.1.0_amd64.deb\nsudo dpkg -i agentty_0.1.0_amd64.deb       # or agentty_0.1.0_arm64.deb\n```\n\nUpdate: `dpkg -i` the new release's `.deb`.\n\n### Fedora / RHEL / openSUSE\n\n```bash\nsudo rpm -Uvh https://github.com/1ay1/agentty/releases/latest/download/agentty-0.1.0-1.x86_64.rpm\n```\n\n`-U` is upgrade; works for the first install too. Same command future-proofs the update path.\n\n### Arch Linux\n\n```bash\nyay -S agentty-bin                          # or paru, pikaur, etc.\nyay -Syu agentty-bin                        # update\n```\n\nOr install the release-page `.pkg.tar.zst` with `sudo pacman -U`.\n\n### macOS (Homebrew)\n\n```bash\nbrew tap 1ay1/tap\nbrew install agentty\nbrew upgrade agentty                        # update\n```\n\nLinux Homebrew gets the prebuilt static binary; macOS builds from source (~1 min).\n\n### Windows (Scoop)\n\n```powershell\nscoop bucket add 1ay1 https://github.com/1ay1/scoop-bucket\nscoop install agentty\nscoop update agentty                        # update\n```\n\nDirect `.exe`: `curl -L https://github.com/1ay1/agentty/releases/latest/download/agentty-windows-x86_64.exe -o agentty.exe`.\n\n### Raw static binaries\n\nFully-static, no shared-library dependencies. Drop and run, replace on update:\n\n```bash\ncurl -fsSL https://github.com/1ay1/agentty/releases/latest/download/agentty-linux-x86_64 -o agentty \u0026\u0026 chmod +x agentty\ncurl -fsSL https://github.com/1ay1/agentty/releases/latest/download/agentty-linux-aarch64 -o agentty \u0026\u0026 chmod +x agentty\n```\n\nVerify with [`SHA256SUMS`](https://github.com/1ay1/agentty/releases/latest) on the release page.\n\n### From source\n\n```bash\ngit clone --recursive git@github.com:1ay1/agentty.git\ncd agentty \u0026\u0026 cmake -B build \u0026\u0026 cmake --build build -j\n./build/agentty\n```\n\nRequires GCC 14+ / Clang 18+ / MSVC 14.40+ and CMake 3.28+.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eCut your own release\u003c/b\u003e — maintainer workflow, one script\u003c/summary\u003e\n\nEvery published artifact is built locally, no CI:\n\n```bash\nscripts/bump.sh 0.2.0        # bumps CMakeLists, builds everything, tags, uploads via gh\n```\n\nUnder 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 create`s with every artifact attached. Single source of truth: `CMakeLists.txt`.\n\nOr step-by-step:\n\n```bash\nscripts/release.sh                  # build every artifact into dist/, no upload\nscripts/release.sh --tag v0.2.0     # build + tag + upload via gh\n```\n\n\u003c/details\u003e\n\n## Quick start\n\n```bash\ncd path/to/your/project   # cwd is the workspace root\nagentty\n```\n\nFirst launch opens an auth modal:\n\n- **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.\n- **API key.** Paste an `sk-ant-…` token. Saved to the same file.\n\nOAuth against your existing Pro/Max subscription is the main path — no extra billing, same account you already pay for.\n\nOverride order, highest priority first:\n\n1. `-k \u003ckey\u003e` / `--key \u003ckey\u003e` — single-session, never written to disk.\n2. `ANTHROPIC_API_KEY` env var.\n3. `CLAUDE_CODE_OAUTH_TOKEN` env var.\n4. The on-disk creds from the modal.\n\nThen 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.\n\nYou 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.\n\nThreads live at `~/.agentty/threads/\u003cworkspace-hash\u003e/`, one JSON file each — safe to inspect, back up, delete. `^J` opens the thread list.\n\n```bash\nagentty --workspace ~/code/other-project   # run against a different workspace without cd\nagentty status                              # which auth source will be used\nagentty login / logout                      # non-interactive auth, useful over SSH\nagentty airgap user@host                    # see below\nagentty acp                                 # run as an ACP agent for Zed (see below)\n```\n\n## Keys\n\n```\nEnter      send                   ^K     command palette\nAlt+Enter  newline                ^J     thread list\nCtrl+E     expand composer        ^T     todo / plan\nEsc        cancel / reject        ^/     model picker\nS-Tab      cycle profile          ^N     new thread\n                                  ^C     quit\n```\n\n## Tools\n\nEach 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.\n\n`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`.\n\n## Skills — teach it your codebase once\n\nagentty implements the open [Agent Skills](https://agentskills.io) standard —\nthe same `SKILL.md` format Claude Code, Codex, and Cursor use — with full\nthree-tier progressive disclosure:\n\n1. **Catalog** — every skill's name + one-line description rides the system\n   prompt (~50 tokens each). Twenty installed skills cost a paragraph, not a\n   context window.\n2. **Instructions** — the full `SKILL.md` body loads only when the model\n   decides the task matches (or you ask for it). Loading twice in one thread\n   returns a one-line \"already active\" sentinel instead of re-paying the body.\n3. **Resources** — bundled `scripts/`, `references/`, `assets/` are *listed*\n   at activation but never eagerly read; the model `read`s the exact file the\n   instructions call for. Skill directories are read-allowlisted — and *only*\n   read: the write/edit boundary never widens.\n\nDrop a directory with a `SKILL.md` in any of these and it's live on the next\nturn — no restart, no config (mtime-keyed rescan):\n\n```\n\u003cproject\u003e/.agentty/skills/   \u003cproject\u003e/.agents/skills/   \u003cproject\u003e/.claude/skills/\n~/.agentty/skills/           ~/.agents/skills/           ~/.claude/skills/\n```\n\nThe `.agents/` convention means skills installed by any compliant client are\nvisible to agentty and vice versa; `.claude/` compatibility means your\nexisting Claude Code skills work unchanged. Project skills shadow user skills\nwith the same name. Frontmatter supports the full spec surface —\n`compatibility`, `allowed-tools`, `license`, `metadata`, and\n`disable-model-invocation` (hidden from the model, loadable on request) —\nincluding YAML block scalars (`description: \u003e-`). Parsing is lenient per the\nspec's interop guidance: unquoted colons, name/dir mismatches, and missing\nfrontmatter all still load.\n\nActivate explicitly with a slash command — `/skill-name fix the parser` — and\nthe harness splices the instructions in without waiting for the model to\ndecide. Validate your skills the way `skills-ref validate` would, with no\nextra tooling:\n\n```bash\nagentty skills      # list every discovered skill + spec-lint diagnostics\n                    # exit 1 on warnings — drop it straight into CI\n```\n\nWhy this matters: on a codebase or internal DSL no model has ever seen,\nagent accuracy starts below 20% — with curated skills (grammar sheets, golden\nexamples, your team's ticket procedure) it reaches ~85%\n([research](https://arxiv.org/abs/2410.03981)). Write the skill once, commit\nit to the repo, and every teammate's agent knows your conventions from turn\none. Pair with `CLAUDE.md` (always-on context) and `remember` (the model's\nown scratchpad) for the complete memory hierarchy.\n\n## Air-gapped hosts (SSH tunnel)\n\nRun 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.\n\nOne command, from the laptop that *does* have internet:\n\n```bash\nagentty airgap --setup user@airgapped-host    # first time: also copies your credentials\nagentty airgap user@airgapped-host            # every time after\n```\n\nHow: `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.\n\n\u003e **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.\n\nBare-metal version, if you'd rather not use the wrapper:\n\n```bash\nssh -t -R 1080 user@airgapped-host \\\n    'AGENTTY_SOCKS_PROXY=localhost:1080 agentty'\n```\n\nRequires 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.\n\n### Behind a TLS-terminating corporate proxy\n\nSOCKS 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.\n\n## Use agentty inside Zed (ACP)\n\nagentty speaks the [Agent Client Protocol](https://agentclientprotocol.com) — the\nsame protocol Zed uses to drive Claude Code and Gemini. Point Zed at the\n`agentty acp` subcommand and your terminal agent becomes a first-class agent\npanel inside the editor: streaming responses, inline diffs for every edit, and\nnative permission prompts before any file write or shell command.\n\nAdd this to Zed's `settings.json` (`zed: open settings`):\n\n```json\n{\n  \"agent_servers\": {\n    \"agentty\": {\n      \"command\": \"agentty\",\n      \"args\": [\"acp\"]\n    }\n  }\n}\n```\n\nThen open the agent panel (`cmd-?` / `ctrl-?`), pick **agentty** from the agent\nlist, and prompt. Auth is whatever `agentty login` already set up — the ACP\nprocess reads the same `~/.config/agentty/credentials.json`, so there's nothing\nextra to configure. Set the model per-subprocess in the `args` (it does *not*\nclobber your TUI's saved model):\n\n```json\n{\n  \"agent_servers\": {\n    \"agentty\": {\n      \"command\": \"agentty\",\n      \"args\": [\"acp\", \"-m\", \"claude-haiku-4-5\", \"--profile\", \"ask\"]\n    }\n  }\n}\n```\n\n`--profile` picks how eagerly Zed prompts you before a tool runs:\n\n- **`ask`** (default) — prompt for `write` / `edit` / `bash` / network; read-only\n  inspection (`read` / `grep` / `glob` / `list_dir`) runs without a dialog so the\n  loop stays fluid.\n- **`minimal`** — prompt for *everything* that touches the outside world, reads\n  included. Tightest leash.\n- **`write`** — same write/exec/net prompts as `ask`, but never prompts for\n  reads.\n\nWhat works over ACP:\n\n- **Streaming text** — the model's reply renders token-by-token in Zed's panel.\n- **Tool calls** — every `read` / `edit` / `bash` / `grep` / … shows up as a\n  Zed tool card with the right icon, the raw arguments, and live status\n  (pending → running → done/failed).\n- **Inline diffs** — `write` and `edit` emit ACP `diff` content, so Zed renders\n  the file change inline and lets you review it in place.\n- **Follow-along** — read/edit/write/grep tool calls carry the file path as an\n  ACP `location`, so Zed can open and highlight the file the agent is touching\n  in real time.\n- **Permission prompts** — side-effecting tools (`bash`, `write`, `edit`,\n  network) trigger Zed's native allow/reject dialog before they run; the\n  `--profile` flag (above) tunes exactly which tools prompt.\n- **Session modes** — the three permission tiers (`Ask` / `Write` / `Minimal`)\n  surface as ACP session modes, so you can switch them live from Zed's mode\n  picker (`session/set_mode`) without restarting the agent; the starting tier\n  is the `--profile` flag.\n- **Cancellation** — stop a turn from Zed and the in-flight stream tears down.\n- **Full session lifecycle** — agentty advertises and implements the complete\n  ACP v1 session surface: `session/new`, `session/load`, `session/resume`,\n  `session/list`, `session/close`, `session/delete`, plus `logout`. Zed can\n  enumerate past sessions, reopen any of them, and prune them — all backed by\n  the on-disk thread store.\n- **Session persistence + reload** — every session is written to agentty's\n  on-disk thread store after each turn (the *same* format the TUI uses), so it\n  survives a subprocess restart. Zed can call `session/load` to resume a past\n  conversation: agentty replays the full transcript (user + assistant messages\n  and tool cards) as `session/update` notifications, then hands back control.\n  Sessions started in Zed also show up in the standalone TUI's thread picker,\n  and vice versa.\n- **Workspace sandbox** — file tools stay inside the session's `cwd` (the\n  folder you opened in Zed); `bash` is wrapped in bwrap/sandbox-exec exactly\n  like the standalone TUI.\n\nThe ACP agent is the *same* engine as the TUI — same provider, same tools, same\nwire-message shaping, same permission policy — just driven over JSON-RPC on\nstdio instead of a terminal. Any other ACP client (not just Zed) works the same\nway.\n\nThe same `--workspace` and `--sandbox` switches the TUI accepts apply in ACP\nmode (they run before the agent starts), so you can loosen or disable both from\nthe Zed `args`:\n\n```json\n{\n  \"agent_servers\": {\n    \"agentty\": {\n      \"command\": \"agentty\",\n      \"args\": [\"acp\", \"--workspace\", \"/\", \"--sandbox\", \"off\"]\n    }\n  }\n}\n```\n\n- **`--workspace DIR`** — file tools refuse paths outside `DIR` (default: the\n  folder you opened in Zed). Widen it to any directory, or pass `--workspace /`\n  to **turn the filesystem gate off** entirely (unrestricted access).\n- **`--sandbox off`** — stop wrapping `bash` / `diagnostics` in bwrap /\n  sandbox-exec. Use when you already have external isolation (a container, VM,\n  or you simply trust the loop). `--sandbox on` does the opposite: refuse to\n  start if no OS sandbox backend is available.\n\nWith `--workspace /` the startup line honestly reports `sandbox: degraded` —\nbinding the whole filesystem means there's no containment left to enforce.\n\n### agentty-in-Zed on an air-gapped remote\n\nYes — you can run agentty inside Zed against a server with **zero internet access**. Your laptop relays every byte. Nothing runs on the remote besides the agent + your shell session.\n\n#### Roles (read once)\n\n- **Laptop** — has internet, has your Anthropic OAuth/API key, runs Zed, runs `ssh`. The relay.\n- **Remote** — the air-gapped box. No internet. Runs `agentty acp` (spawned by Zed via ssh).\n\nEverything below is done **on the laptop**.\n\n#### Prerequisites\n\n1. `agentty` installed on **both** machines (`which agentty` on each prints a path).\n2. Passwordless SSH from laptop to remote works (`ssh user@remote echo ok` returns `ok` without prompting). If it prompts, run `ssh-copy-id user@remote` first.\n3. You're logged in on the laptop (`agentty status` shows OAuth or API key). If not: `agentty login`.\n4. Zed installed on the laptop.\n\n#### One-time setup (two commands, ~5 seconds total)\n\nFrom the laptop:\n\n```bash\n# 1. Copy your Anthropic credentials to the remote (once):\nagentty airgap --setup user@remote\n\n# 2. Print the Zed config block for this remote:\nagentty airgap user@remote --acp -m claude-haiku-4-5 --profile ask\n```\n\nThe second command **prints to stderr and exits** — it does not start anything. You'll see something like:\n\n```\nagentty airgap --acp: add this to Zed's settings.json\n  → /home/you/.config/zed/settings.json:\n\n  \"agent_servers\": {\n    \"agentty (airgap)\": {\n      \"command\": \"ssh\",\n      \"args\": [\"-T\", \"-R\", \"1080\", \"-o\", \"ExitOnForwardFailure=yes\", ...\n              \"user@remote\",\n              \"AGENTTY_SOCKS_PROXY=localhost:1080 exec agentty acp -m claude-haiku-4-5 --profile ask\"]\n    }\n  }\n```\n\n#### Wire it into Zed (one paste)\n\n1. Open Zed's settings: `cmd-,` (macOS) or `ctrl-,` (Linux) → the settings file opens.\n2. Paste the printed `\"agent_servers\"` block into the JSON. If you already have an `agent_servers` object, merge the `\"agentty (airgap)\"` key into it.\n3. Save.\n\n#### Use it\n\n1. Open the agent panel in Zed: `cmd-?` / `ctrl-?`.\n2. From the agent picker, pick **agentty (airgap)**.\n3. Prompt.\n\nThat's it. Zed spawns `ssh` directly — a single process is the tunnel, the agent, and the JSON-RPC transport. Zed owns its lifecycle: close the agent panel, the ssh + remote `agentty acp` both die. No `ssh -N` running in the background, no wrapper script, no daemon.\n\n#### What's happening under the hood\n\n- Zed runs `ssh -R 1080 user@remote 'AGENTTY_SOCKS_PROXY=localhost:1080 exec agentty acp ...'` directly.\n- `-R 1080` exposes a SOCKS5 proxy on the remote's `localhost:1080`. The remote `agentty` is told to route every outbound connection (chat, OAuth refresh, `web_fetch`, `web_search`) through it. Those connections tunnel back over SSH and are dialed by your laptop.\n- ACP JSON-RPC flows over ssh's stdio. No extra port, no extra process.\n- TLS still negotiates end-to-end with the real upstream (api.anthropic.com etc.). The laptop sees encrypted bytes only — it can't MITM.\n\n#### Trust model (read before `--setup`)\n\n`--setup` copies your laptop's `~/.config/agentty/credentials.json` to the remote (chmod 600). That file contains your OAuth refresh token (or API key). A compromised remote can exfiltrate it independent of the tunnel. **agentty airgap protects the network between laptop and remote, not the remote itself** — treat the remote as a credential-bearing peer, not a sandboxed proxy.\n\n#### Troubleshooting\n\n- **Zed shows the agent greyed out / \"failed to start\"** — check `~/.local/share/zed/logs/Zed.log` (Linux) or `~/Library/Logs/Zed/Zed.log` (macOS) for the ssh spawn line. Common causes: `ssh` not on Zed's PATH (rare), the remote prompts for a password (run `ssh-copy-id` first), or `agentty` isn't on the remote's PATH (pass `--remote-agentty /full/path/to/agentty` to the `airgap` command, then re-print the config).\n- **\"connection refused\" or \"could not resolve host\" mid-turn** — the SOCKS tunnel dropped. Usually a flaky network on the laptop. Close the agent panel in Zed and reopen — Zed respawns ssh.\n- **Slow first response** — first TLS handshake to api.anthropic.com tunnels through ssh, adds ~100 ms. Subsequent turns reuse the connection.\n- **`agentty: command not found` in the ssh spawn log** — agentty isn't on the remote shell's non-interactive PATH (`ssh user@remote 'echo $PATH'` shows what Zed sees). Either install it system-wide on the remote, or re-print the config with `--remote-agentty /full/path/to/agentty`.\n- **The remote needs a non-default ssh port / key / jump host** — export `AGENTTY_AIRGAP_SSH=\"-p 2222 -i ~/.ssh/work -J bastion\"` before running `agentty airgap ... --acp`. Those flags get embedded into the printed config.\n\n\u003e Want to drive it from the command line first to confirm it works before touching Zed? `agentty airgap user@remote` (no `--acp`) launches the agentty TUI running on the remote, in your local terminal. If that works, the ACP version will too — same tunnel, different transport.\n\n\u003e Run `agentty acp` by hand and it'll sit waiting for newline-delimited\n\u003e JSON-RPC on stdin (diagnostics go to stderr, stdout is the protocol channel).\n\u003e `scripts/acp_smoke.py` is a tiny reference client that drives a full\n\u003e initialize → prompt → tool → permission round-trip;\n\u003e `scripts/acp_methods_test.py` exercises the rest of the v1 method surface\n\u003e (modes, list/resume/close/delete, logout) offline.\n\n## How it compares\n\n|                     | agentty                               | claude-code                       | aider                               |\n|---------------------|---------------------------------------|-----------------------------------|-------------------------------------|\n| Language / runtime  | C++26 — single static binary          | TypeScript / Node                 | Python                              |\n| Footprint           | ~9 MB                                 | npm + Node runtime                | pip + Python runtime                |\n| Air-gapped mode     | Yes (`agentty airgap`, SOCKS5/SSH)    | No                                | No                                  |\n| Auth                | OAuth (Pro/Max) + `ANTHROPIC_API_KEY` | OAuth + `ANTHROPIC_API_KEY`       | per-provider env vars               |\n| Models              | Claude (Anthropic)                    | Claude (Anthropic)                | many (OpenAI / Anthropic / local …) |\n\nWant 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.\n\n## How it works\n\nPure-functional update loop: `(Model, Msg) -\u003e (Model, Cmd)`. Strong ID newtypes (`ToolCallId`, `ThreadId`, `OAuthCode`, `PkceVerifier`) — swapping arguments is a compile error, not a debugging session.\n\nView is a single function `Model -\u003e Element`. Rendering is delegated to [maya](https://github.com/1ay1/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.\n\nSubprocess 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`).\n\nDeep dive: [`docs/RENDERING.md`](docs/RENDERING.md) walks the view pipeline turn-by-turn; [`docs/UI.md`](docs/UI.md) is the per-widget Config reference.\n\n## Standalone build\n\n```bash\ncmake -B build -DAGENTTY_STANDALONE=ON\n```\n\nStatically 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.\n\nAccurate one-liner: **statically linked except libc and (usually) OpenSSL.** For a 100%-static drop-in, the [latest release](https://github.com/1ay1/agentty/releases/latest) ships pre-built `agentty-linux-x86_64` and `agentty-linux-aarch64` with zero shared-library dependencies (Alpine + musl + GCC 14.2).\n\n## Status\n\nWorks 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.\n\nFile bugs with `$TERM`, your terminal emulator name, and a screenshot. Code-path bugs welcome too — paste the relevant block and `git rev-parse HEAD`.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1ay1%2Fagentty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F1ay1%2Fagentty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F1ay1%2Fagentty/lists"}