Go to file
王性驊 a514b33fb3 Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings
Permissions and reach
- a file leaving a computer passes the same questions as reading it;
  "looking" shell commands that do more than look ask first
- a symlink out of the work/sealed folder counts as outside it
  (real paths, not just lexical ones); the search walk skips links
- web_fetch and skill_install read the public web only: localhost, the
  LAN and cloud metadata are refused, at every redirect
- preview shows a file without running it; browser_upload may ask
- vault: logins no longer match across shared suffixes (pages.dev,
  com.tw, ...); registrable_domain knows public suffixes
- axwrite: found elements are retained (use-after-free)

Relay
- replacing or turning off 2FA needs the current code (rate-limited);
  new recovery codes only count once enrollment is verified
- a removed computer loses its socket and its `call` access
- a site name taken by another account answers 409
- RELAY_TRUST_PROXY: the login lock counts the caller's address, not
  the proxy's (compose files and README)
- httpd: half a body is not a request

Desktop
- sign-in, join and restore work with 2FA on (code field; --serve reads
  ANYBOT_ACCOUNT_CODE; the setup wizard points to a pairing code)
- Windows: text was typed twice; modifiers are held through click, drag
  and scroll; horizontal scroll; screen control is no longer refused
- a recording that hits the limit is transcribed, not thrown away
- bot's computer: a new home volume restores the snapshot; a snapshot
  is read through before the home is wiped; a failed volume removal
  stops reset/restore
- events of a stopped turn no longer land in the next one; each channel
  message gets a turn of its own
- saving a bot's settings keeps what it got meanwhile (three-way merge);
  a save file that cannot be read is kept
- pages in Big5/GBK/Shift_JIS are read in their own encoding
  (encoding_rs); osascript output past 64 KB no longer stalls
- pick_tab keeps a job's own non-http tab; pictures larger than the
  texture limit are fitted; the auto-update time field takes typing
- skills live in <data>/skills; memories are unnumbered in the prompt;
  the phone may skillify and skill_install

CI
- the test step fails when the tests fail (it piped into tail)

Tests: anybot 268 passed, 27 ignored; relay 16 passed; clippy unchanged.
Not run: Windows on a real machine (win.rs type-checked alone), the
Docker paths of the bot's computer, the live accessibility writes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-10 11:46:17 +08:00
.gitea/workflows Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings 2026-11-10 11:46:17 +08:00
bench/computer-use Injection defences and a red-team suite (S3) 2026-11-09 17:19:21 +08:00
box GTK 2 apps in the box get numbers, a quick model's answer always goes past the bot's own model, and a bot finishes what it was asked 2026-11-09 12:53:06 +08:00
deploy Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings 2026-11-10 11:46:17 +08:00
docs Plan: M5 complete (C6, P5, C5, P7+C8, C9 engine) 2026-11-09 20:51:33 +08:00
fonts AnyBot: first commit of the working desktop app 2026-11-04 16:51:51 +08:00
icons Remove what nothing uses and keep one copy of what was written several times 2026-11-05 23:21:47 +08:00
mobile Skills you can hold in your hand: skill files, install, 示範即教學 (P7+C8) 2026-11-09 20:46:02 +08:00
relay Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings 2026-11-10 11:46:17 +08:00
skills Skills you can hold in your hand: skill files, install, 示範即教學 (P7+C8) 2026-11-09 20:46:02 +08:00
src Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings 2026-11-10 11:46:17 +08:00
.dockerignore AnyBot: first commit of the working desktop app 2026-11-04 16:51:51 +08:00
.gitignore Release builds on Gitea Actions: macOS app, Ubuntu, headless Linux, server 2026-11-04 22:07:46 +08:00
Cargo.lock Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings 2026-11-10 11:46:17 +08:00
Cargo.toml Bug sweep: gates, relay 2FA, Windows input, snapshots, encodings 2026-11-10 11:46:17 +08:00
FEATURES.md A screen never runs its own box or VM, from the start 2026-11-09 15:32:36 +08:00
LICENSE Apache-2.0: license file, manifest fields, README section 2026-11-09 16:36:36 +08:00
MECHANICS.md AnyBot: first commit of the working desktop app 2026-11-04 16:51:51 +08:00
Makefile Bots do a planned sequence in one step; the box's screen settles by what it shows; no login is ever the only copy 2026-11-06 09:47:37 +08:00
README.en.md Say what the walls are: SECURITY.md + threat model (P5) 2026-11-09 20:33:56 +08:00
README.md Say what the walls are: SECURITY.md + threat model (P5) 2026-11-09 20:33:56 +08:00
SECURITY.md Say what the walls are: SECURITY.md + threat model (P5) 2026-11-09 20:33:56 +08:00
install.sh Demo recording keeps its last events off the UI thread; dialogs, screensaver probe and installer traps fixed 2026-11-05 15:48:22 +08:00
mechanics.json AnyBot: first commit of the working desktop app 2026-11-04 16:51:51 +08:00

README.en.md

AnyBot

中文 README · English

Your own AI bot. It chats, and it does things: files, shell commands, your browser, your screen, scheduled jobs. Self-hosted — your data stays on machines you own.

  • Every bot can use a different model: xAI Grok, OpenAI, Claude, Gemini, OpenRouter, OpenCode Go, Ollama (local), or any OpenAI-compatible endpoint
  • Desktop app (macOS, Linux) + mobile web app (install to home screen, push notifications)
  • Multiple computers: one brain, the others are its hands — all linked through your own account server, no ports opened

Demo

📹 No recording yet — see docs/demo/README.md.

How it compares

AnyBot OpenClaw OpenHands Khoj UI-TARS-Desktop
Positioning Personal bot across your machines Agent gateway on your hardware Coding agent in sandboxes Personal knowledge/RAG assistant GUI agent on one desktop
Chat with your own bots ✅ multi-bot, per-bot model ✅ via gateways coding-focused ✅ —
Controls your real desktop/browser ✅ + approvals, VNC takeover via plugins sandboxed, not your desktop — ✅ (its whole product)
Multi-device brain/hands/phone ✅ built in, zero open ports bring your own — server + apps single machine
Bot's own sandboxed computer (Docker, optional gVisor) ✅ host shell ✅ — —
Secrets never enter the model (vault fills forms directly) ✅ — — — —
Phone web app + push, no app store ✅ community — ✅ —
One binary, JSON files, no database server ✅ ✅ — needs services Electron
License Apache-2.0 MIT MIT AGPL-3.0 Apache-2.0

AnyBot's bet: a bot that touches your real machines is only trustworthy when the harness — not the model — owns the safety gates: per-action approvals, a sensitive-click policy the model cannot talk its way past, secrets painted out of screenshots, and an audit trail that survives crashes.

Install

Pick one row, paste it into a terminal. The script installs what's needed (system packages, Rust, Docker).

I want… On which machine Command
Desktop app macOS, Linux with a screen curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh
Account server (+ brain + HTTPS) A Linux host with a domain curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- server
Add a computer as hands Any Linux (headless fine) In AnyBot press “Add a computer”, paste the one-liner it shows

First run compiles on your machine (5–15 min); later updates take 1–2 min. Read the script first: install.sh. It installs into your user folders — no root.

Getting started

One computer: install the desktop app → Settings › Models → paste an API key → chat.

Phone + several computers: run the server once (asks only for URL, account, password; gets HTTPS by itself), open the URL on your phone and “Add to Home Screen”, then pair other computers with one-time pairing codes. Any Linux box can become the bot's own computer, running inside Docker (optionally gVisor). A Mac can be the brain instead of a server (docs/multi-device.md, method B). No database to run: state is a handful of JSON files, crash-safe writes; back up two Docker volumes.

Updates, removal

What Command
Update app / hands re-run the install line
Update server on the server: cd ~/AnyBot && make server → “keep settings, update, restart”
Uninstall the program cd ~/AnyBot && make uninstall (your bots and chats are kept)
Stop a hands machine systemctl --user disable --now anybot

Troubleshooting

cd ~/AnyBot && make doctor

It tells you what's missing. Common: Killed/signal: 9 while compiling → add 2 GB swap; requires rustc 1.95 → rustup update stable; Mac says “cannot verify developer” → right-click › Open once; phone says “brain offline” → the brain machine is asleep (docs/multi-device.md).

Build from source

git clone https://code.30cm.net/daniel.w/AnyBot.git
cd AnyBot
make deps && make && make install   # deps: system packages + Rust 1.95+ (one time)

make run · make test · make doctor · make serve (headless) · make setup (pair this machine) · make server · make dist · make help. Needs: Rust ≥1.95, a C compiler, git; on Linux also pkg-config + libasound2-dev (deps installs all).

Deployment

Method For Notes
Docker Compose (default) server install.sh server: relay + brain + Caddy (auto-HTTPS) containers; data in Docker volumes; Tailscale URLs skip Caddy (compose file)
Unattended servers, Ansible ANYBOT_SETUP_USER=… ANYBOT_SETUP_PASSWORD=… [ANYBOT_SETUP_DOMAIN=…] sh install.sh server
Portainer/Coolify/Dokploy existing PaaS they take the standard deploy/server/docker-compose.yml — set ANYBOT_USER, ANYBOT_PASSWORD, ANYBOT_RELAY_PUBLIC_URL
systemd user service hands, headless brains anybot setup installs anybot.service; loginctl enable-linger to keep it running logged-out
launchd Mac as brain/relay see docs/multi-device.md
Gitea Actions release builds on v* tags see docs/release.md

Security in one paragraph

Commands run in a macOS sandbox (deny ~/.aws, Keychain, AnyBot's own data; allow only the attachments dir); per-action approvals with a policy layer the model cannot negotiate; clicking anything labelled “send/pay/transfer” is asked every time, even in direct mode, with no grant that silences it; card numbers and OTPs in screenshots are painted black before the model sees them; everything read from outside is wrapped as <untrusted> data, never treated as orders; the bot's own computer is a Docker container (gVisor for a second wall); relay stores only hashes (argon2id) and supports 2FA with recovery codes; egress binds loopback + detected bridge gateways, never 0.0.0.0. Details: SECURITY.md (summary here) and docs/architecture.md (Chinese; English summary).

Documentation

Doc Contents
docs/install.md (en) per-platform details, manual steps, FAQ
docs/multi-device.md (en) brain / hands / screen: setup, pairing, offline
docs/architecture.md (en) layers, data storage, security design
docs/protocol.md (en) relay API and long-connection wire format
docs/release.md packaging, CI
FEATURES.md every feature (Chinese)

License

Apache License 2.0 — see LICENSE. Copyright the contributors (The AnyBot contributors). Calls to third-party services (xAI, OpenAI, …) go through their public APIs; follow each service's terms and your own key agreements.

Repository layout

install.sh      one-line installer (app, hands, server)
src/            AnyBot: desktop app, headless, `anybot setup`
relay/          account server
mobile/         phone web app (single file, embedded)
box/            the bot's own computer (Docker container)
deploy/         per-platform install & deployment files
docs/           technical docs (docs/en/ = English)
bench/          computer-use benchmark (tasks, scoring, red-team suite)