diff --git a/README.en.md b/README.en.md
index 5f928f2..8e81830 100644
--- a/README.en.md
+++ b/README.en.md
@@ -1,150 +1,136 @@
-# AnyBot
+
+
+
-[中文 README](README.md) · **English**
+AnyBot
-Your own AI assistant. It chats, and it can also *do* things: files, commands, web pages, the screen in front of you, and jobs that run on a schedule.
+
+ An AI assistant that runs on your own computers.
+ It chats, and it does things: files, commands, web pages, the screen in front of you, and jobs on a clock.
+
-It runs on **your computers**. You bring the model key (or run Ollama at home). Chats, files, and passwords are not stored on someone else's account server.
+
+ 中文 · English
+
-## Quick install
+
+
+
+
+
+
-Open a terminal and pick one. **The first build takes 5–15 minutes**, later updates 1–2. It installs into your user folder and needs no administrator account.
+
+
+
-**Desktop app** (Mac, Linux with a screen; when in doubt paste this one — it asks what you want)
+You bring the model key: xAI, OpenAI, Claude, Gemini, OpenRouter, OpenCode Go, Ollama at home, or anything that speaks the OpenAI API. Chats, files, and passwords stay on your machines instead of landing in someone else's account server. Each row on the left is a bot — research, writing, “touch the computer” — and each can use a different model.
+
+---
+
+## Install in 30 seconds
+
+Open a terminal and paste one line.
```sh
+# macOS, Linux (not Ubuntu-only: apt, dnf, yum, pacman, zypper, apk, xbps)
curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh
```
-Windows 10/11 (PowerShell):
-
```powershell
+# Windows 10/11 (x64, arm64)
irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
```
-**Account server + brain** (any Linux with Docker, 2 GB RAM or more; it asks for a domain, a user, a password, and sets up HTTPS itself)
+It installs what it needs, asks which piece you want, and walks through the first setup. The first build takes 5–15 minutes, later updates 1–2. It lives in your user folder and needs no administrator account.
+
+Then open AnyBot (on a Mac, the first time: right-click the icon › Open), paste an API key under Settings › Models, make a bot, and talk to it. No key? Pick Ollama and it runs on your own machine.
+
+**Account server + brain** (any Linux with Docker, 2 GB RAM or more; it asks for a domain, a user, a password, and handles HTTPS itself):
```sh
curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- server
```
-**Headless hands** (a computer for the bot to use; no screen needed). The URL and the pairing code come from “Add a computer” in AnyBot:
+**Headless hands** (a computer for the bot to use; a screen is optional). The URL and the pairing code come from “Add a computer” in AnyBot:
```sh
-curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- hands https://your-address 482913
+curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \
+ | sh -s -- hands https://your-address 482913
```
-Hands on Windows:
-
```powershell
-$env:ANYBOT_MODE='hands'; $env:ANYBOT_PAIR_URL='https://your-address'; $env:ANYBOT_PAIR_CODE='482913'; irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
+# Hands on Windows
+$env:ANYBOT_MODE='hands'
+$env:ANYBOT_PAIR_URL='https://your-address'
+$env:ANYBOT_PAIR_CODE='482913'
+irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
```
-After the desktop app, open AnyBot (on a Mac, the first time: right-click the icon › Open), paste an API key under Settings › Models, make a bot, and talk to it. No key? Pick Ollama and it runs on your own machine. A pairing code is valid for 10 minutes and works once; just ask for a new one.
-
-Running this from an agent, with no questions asked: see [install/AGENT.md](install/AGENT.md).
-
-
-
-
-
-Each row is a bot. Research, writing, and “touch the computer” can each use a different model.
+Running this from an agent, with no questions asked: `sh install.sh --print` reports what fits this machine, then use the environment variables — see [install/AGENT.md](install/AGENT.md).
---
## It asks before it acts
-If you say “do this on my computer”, it does not just run it. You see the exact step and choose allow once, always, or no. Sending, paying, and deleting are asked every time, even if you turned other prompts off.
+Say “do this on my computer” and it does not just run it. You see the exact step and choose allow once, always, or no. Sending, paying, and deleting are asked every time, even when you turned the other prompts off.
-
-
+
+
-The phone is the same chat. Open your URL, sign in, and you can watch from outside — and take the screen when a login needs a person.
+- **Files and commands** — it asks first. Or it works only inside its own computer, a small desktop kept apart from yours.
+- **Web pages and forms** — its own browser. Passwords and card numbers are filled by the app, not read out to the model.
+- **The screen you are using** — it reads the buttons in the screenshot, then clicks. If it needs you to sign in, it hands you the screen.
+- **A clock** — “every weekday at 9, three news items” becomes a routine.
+- **A phone, from anywhere** — open your URL in a browser, sign in, and it is the same chat.
-
-
+
+
-## What you can ask it to do
-
-| | |
-|---|---|
-| Chat, edit, look things up | Each bot has a one-line job description and its own model |
-| Files and commands | It asks first. Or it works only inside its own computer, a small desktop kept apart from yours |
-| Web pages and forms | Its own browser. Passwords and card numbers are filled by the app, not read out to the model |
-| The screen you are using | It looks at buttons, then clicks. If it needs you to sign in, it hands you the screen |
-| A clock | “Every weekday at 9, three news items” becomes a routine |
-
-
-
+
+
-Models: xAI, OpenAI, Claude, Gemini, OpenRouter, OpenCode Go, Ollama on your machine, or any OpenAI-compatible endpoint.
-
---
-## One computer is enough
+## One machine thinks, others get used
-If you do not want a server, stop here.
-
-1. Paste the quick-install line above into a terminal. If it asks what to install, choose the desktop app.
-2. Open AnyBot. On a Mac, the first time: right-click the icon › Open.
-3. Settings › Models, paste an API key. Or pick Ollama and skip the key.
-4. Make a bot and talk to it.
-
-The first build takes about 5–15 minutes. Later updates take 1–2. The app lives in your user folder. No administrator account.
-
-For a second computer or a phone, see “A phone, and other computers” below.
-
----
-
-## A phone, and other computers
-
-One machine remembers and thinks (the **brain**). Others are there to be used (the **hands**). The phone is only a window. They meet on an **account server you run**, so the computers at home do not open a port or need a public address.
+One machine remembers and thinks (the **brain**). Others are there to be used (the **hands**). The phone is only a window. They all meet on an **account server you run**, so the computers at home do not open a port or need a public address.
```
you on the phone you on a laptop a computer with no screen
- \ | /
- └──── account server (it only connects them) ──────┘
- |
+ \ | /
+ └───── account server (it only connects them) ─────┘
+ |
brain: bots, chats, memory, routines live here
- |
+ |
hands: the brain asks this machine to see, click, read, browse
```
-| Role | In plain words | What you do |
-|---|---|---|
-| Brain | Holds every bot and chat. Thinks and runs the clock. Must stay on | Set up the server once, or use a Mac that stays awake |
-| Screen | The computer you sit at. You see the brain's bots, and the brain can use this machine | Install the desktop app and sign in |
-| Hands | A computer for the bot. A screen is optional | In AnyBot, press “Add a computer” and paste the line it shows |
-| Phone | The same chat | Open your URL in a browser and add it to the home screen |
+| Role | What you do |
+|---|---|
+| Brain | Set up the server once, or use a Mac that stays awake |
+| Screen | Install the desktop app and sign in to the same account |
+| Hands | Press “Add a computer” and paste the line it shows |
+| Phone | Open your URL in a browser and add it to the Home screen |
-The server is a Linux machine with 2 GB of RAM, plus a domain or Tailscale (no domain; only your devices can open it).
-
-```sh
-curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- server
-```
-
-It asks for three things: URL, account, password. Docker and HTTPS are its job.
-
-No server yet? A Mac can be the brain first. That is method B in [docs/multi-device.md](docs/multi-device.md) ([English summary](docs/en/multi-device.md)).
+No server yet? Use one always-on Mac as the brain — see option B in [docs/multi-device.md](docs/multi-device.md).
---
-## How a sentence becomes an action
-
-For people who want the path, not the source tree. The module map is [docs/architecture.md](docs/architecture.md) ([English summary](docs/en/architecture.md)).
+## What happens to a sentence
```mermaid
flowchart TD
you[You: desktop app or phone]
- relay[Account server
forwards only, does not keep the chat]
+ relay[Account server
relays only, stores no chats]
brain[AnyBot on the brain]
- model[The model you chose]
- ask[Touch a computer? Ask you first]
- box[The bot's own computer
a desktop inside Docker]
- hands[A paired machine
your Mac, Linux, or Windows]
+ model[The model you picked]
+ ask[Touch the computer? Ask first]
+ box[The bot's own computer
a small desktop in Docker]
+ hands[One of the hands
your Mac, Linux, or Windows]
you --> relay --> brain
brain --> model
@@ -153,66 +139,33 @@ flowchart TD
ask --> hands
```
-1. You send a message on the desktop or the phone. The phone does not think on its own. It is looking at the brain's copy of the chat.
-2. The brain sends that message, the bot's instructions, and the tools it may use, to your model.
-3. If the model only needs to answer, the reply comes back. If it wants to read a file, open a page, or click, it proposes one action.
-4. AnyBot's own rules decide, not the model. Ordinary actions ask you. Send, pay, and delete always ask.
-5. After you allow it, the action runs on the computer you named: the bot's sealed desktop, the machine you are using, or a paired hands machine.
-6. The result returns to the chat. Phone and laptop see the same thread, because both are watching the brain.
+1. You send a message on the desktop or the phone. The phone does not think for itself; it reads the same chat on the brain.
+2. The brain hands that sentence, the bot's instructions, and its tools to the model you picked.
+3. If the model only answers, it writes back. If it wants to read a file, open a page, or click something, it proposes an action.
+4. That action goes through AnyBot's own rules first — the model does not decide whether it is allowed.
+5. Once you allow it, the action runs on **the computer you chose**: the isolated desktop, the one you are using, or a paired hand.
+6. The result goes back into the chat. Phone and laptop show the same thing because both read the brain.
-Three programs. No database server.
-
-| Program | What it is |
-|---|---|
-| `anybot` | The window, the background process (`anybot --serve`), and terminal setup (`anybot setup`) are one file |
-| `anybot-relay` | The account server. Computers connect out to it, so you do not open a port at home |
-| Phone page | One file, built into the program. A browser pointed at your URL is the app |
-
-State is a few JSON files, written to a temp file and renamed, so a crash cannot leave a half-written save. macOS: `~/Library/Application Support/AnyBot/`. Linux: `~/.local/share/AnyBot/`. Windows: `%APPDATA%\AnyBot\`.
+Three programs are enough, and there is no database server: `anybot` (the desktop, the background service `anybot --serve`, and the terminal setup `anybot setup` are this one file), `anybot-relay` (the account server; computers connect out to it), and the phone page (one file, built into the app). Details in [docs/architecture.md](docs/architecture.md).
---
-## Install
-
-In a terminal it asks what you want, then walks through the first key or the first pairing. You do not have to understand the flags.
-
-| I want… | On | Paste |
-|---|---|---|
-| Quick install (it asks what you want) | Mac, Linux | `curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \| sh` |
-| Quick install (Windows is the desktop app) | Windows 10/11 | `irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 \| iex` |
-| Desktop app, no questions | Mac, or Linux with a screen | `curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \| sh -s -- app` |
-| Account server and brain | Any Linux with Docker | `curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \| sh -s -- server` |
-| Another computer as hands | Mac, Linux (headless is fine), Windows | The headless-hands line in “Quick install” above, or “Add a computer” in the app and paste the line it shows |
-
-Linux is not Ubuntu-only. The script knows apt, dnf, yum, pacman, zypper, apk, and xbps.
-
-| Later | |
-|---|---|
-| Update the app or a hands machine | Paste the install line again |
-| Update the server | On the server, `cd ~/AnyBot && make server`, keep the current settings |
-| Remove the program | `cd ~/AnyBot && make uninstall` (bots and chats stay) |
-| Install failed | `cd ~/AnyBot && make doctor`, then [docs/install.md](docs/install.md) ([English](docs/en/install.md)) |
-
-Scripts and other agents, with no questions: [install/AGENT.md](install/AGENT.md). Start with `sh install.sh --print`.
-
----
-
-## Which document
-
-The Chinese `docs/` files are the ones that stay current. `docs/en/` is a short English copy of each.
+## Documents
| You want… | Read |
|---|---|
-| To chat on one computer | “Quick install” at the top |
-| Phone, brain, hands, “brain offline” | [docs/multi-device.md](docs/multi-device.md) ([en](docs/en/multi-device.md)) |
-| A platform that will not install | [docs/install.md](docs/install.md) ([en](docs/en/install.md)) |
-| Layers, files, where a turn lives | [docs/architecture.md](docs/architecture.md) ([en](docs/en/architecture.md)) |
-| The account-server wire format | [docs/protocol.md](docs/protocol.md) ([en](docs/en/protocol.md)) |
-| Trust boundary and where keys sit | [SECURITY.md](SECURITY.md) ([en](docs/en/security.md)) |
-| Every feature, as a list | [FEATURES.md](FEATURES.md) (Chinese) |
-| Release builds | [docs/release.md](docs/release.md) |
+| Phone, brain, hands, “it will not connect” | [docs/multi-device.md](docs/multi-device.md) |
+| A platform failed, build it yourself | [docs/install.md](docs/install.md) |
+| How the code is layered | [docs/architecture.md](docs/architecture.md) |
+| The account server's API | [docs/protocol.md](docs/protocol.md) |
+| Trust boundaries, where keys live | [SECURITY.md](SECURITY.md) |
+| Every feature, listed | [FEATURES.md](FEATURES.md) |
+| Packaging, CI | [docs/release.md](docs/release.md) |
+| Editing this README without breaking the layout | [docs/readme-style.md](docs/readme-style.md) |
-From source:
+Chinese is the source of truth; `docs/en/` is a summary for people who do not read Chinese.
+
+## Hack on it
```sh
git clone https://code.30cm.net/daniel.w/AnyBot.git
@@ -220,29 +173,8 @@ cd AnyBot
make deps && make && make install
```
-`make run` opens it without installing. `make test` runs tests. `make help` lists the rest.
-
-### If you are comparing it to other projects
-
-| | AnyBot | OpenClaw | OpenHands | Khoj | UI-TARS-Desktop |
-|---|---|---|---|---|---|
-| What it is | A personal bot across your machines | An agent gateway on your hardware | A coding agent in sandboxes | A personal knowledge assistant | A GUI agent on one desktop |
-| Your real screen, with a person in the loop | Yes. It asks, and you can take the screen | Via plugins | Sandbox, not your desktop | — | Yes. That is the product |
-| Phone and several computers | Built in. No port opened at home | You assemble it | — | Server and apps | One machine |
-| The bot's own sealed computer | Docker, optional gVisor | Host shell | Yes | — | — |
-| Secrets stay out of the model | The app fills the form | — | — | — | — |
-| License | Apache-2.0 | MIT | MIT | AGPL-3.0 | Apache-2.0 |
-
-The bet: a bot that can touch your machines is only trustworthy if the program, not the model, owns the gates.
-
----
-
-## Security
-
-The bot runs on your machines. It asks before it uses them. Text that arrived from a page or a screenshot is data, not orders. Card numbers and one-time codes are painted out of screenshots before a model sees them. Limits and where keys live: [SECURITY.md](SECURITY.md) ([summary](docs/en/security.md)).
-
-Report a vulnerability through the repo's security advisory, not a public issue.
+`make run` opens it, `make test` runs the tests, `make help` lists everything.
## License
-[Apache License 2.0](LICENSE). Calls to xAI, OpenAI, and the others go through those companies' public APIs. Follow their terms and your key agreement.
+Apache-2.0, see [LICENSE](LICENSE).
diff --git a/README.md b/README.md
index dbe4ac3..288d036 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,52 @@
-# AnyBot
+
+
+
-中文 · [English →](README.en.md)
+AnyBot
-你自己的 AI 助理。可以聊天,也能幫你做事:整理檔案、跑指令、看網頁、操作螢幕、到點提醒你。
+
+ 跑在你自己電腦上的 AI 助理。
+ 會聊天,也會做事:整理檔案、跑指令、看網頁、操作螢幕、到點自己排。
+
-它跑在**你的電腦**上。模型用你自己的金鑰(或你家裡的 Ollama)。聊天、檔案、密碼不會先送到別人的帳號伺服器。
+
+ 中文 · English
+
-## 快速安裝
+
+
+
+
+
+
-打開終端機,選一個貼。**第一次編譯 5–15 分鐘**,之後更新 1–2 分鐘。裝在你的使用者資料夾,不需要系統管理員。
+
+
+
-**桌面 App**(Mac、有螢幕的 Linux;不確定就貼這行,它會先問你)
+模型用你自己的金鑰:xAI、OpenAI、Claude、Gemini、OpenRouter、OpenCode Go、家裡的 Ollama,或任何講 OpenAI 那套介面的服務。聊天記錄、檔案、密碼留在你的機器上,不會先存進別人的帳號伺服器。左邊每一行都是一個 Bot:研究、寫作、管電腦,可以各用各的模型。
+
+---
+
+## 30 秒裝好
+
+打開終端機,貼一行。
```sh
+# macOS、Linux(不限 Ubuntu:apt、dnf、yum、pacman、zypper、apk、xbps 都認得)
curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh
```
-Windows 10/11(PowerShell):
-
```powershell
+# Windows 10/11(x64、arm64)
irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
```
-**帳號伺服器 + 大腦**(任何有 Docker 的 Linux,2 GB 以上;它只問網址、帳號、密碼,HTTPS 它自己處理)
+它會自己裝好需要的東西、問你要裝哪一種,然後做第一次設定。第一次編譯 5–15 分鐘,之後更新 1–2 分鐘;裝在你的使用者資料夾,不需要系統管理員。
+
+裝好打開 AnyBot(Mac 第一次要對圖示按右鍵 › 打開),「設定 › 模型」貼上 API 金鑰,建一個 Bot 就能開始聊。沒有金鑰可以選 Ollama,在你自己的電腦上跑。
+
+**帳號伺服器 + 大腦**(任何有 Docker 的 Linux,2 GB 以上;只問網址、帳號、密碼,HTTPS 它自己處理):
```sh
curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- server
@@ -31,118 +55,80 @@ curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh
**無頭手腳**(給 Bot 操控的電腦,沒螢幕也行)。網址和配對碼在 AnyBot 按「加一台電腦」就會看到:
```sh
-curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- hands https://你的網址 482913
+curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \
+ | sh -s -- hands https://你的網址 482913
```
-Windows 手腳:
-
```powershell
-$env:ANYBOT_MODE='hands'; $env:ANYBOT_PAIR_URL='https://你的網址'; $env:ANYBOT_PAIR_CODE='482913'; irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
+# Windows 手腳
+$env:ANYBOT_MODE='hands'
+$env:ANYBOT_PAIR_URL='https://你的網址'
+$env:ANYBOT_PAIR_CODE='482913'
+irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
```
-桌面裝好打開 AnyBot(Mac 第一次要對圖示按右鍵 › 打開),在「設定 › 模型」貼上 API 金鑰,建一個 Bot 就能開始聊。沒有金鑰可以選 Ollama,在你自己的電腦上跑。配對碼 10 分鐘內有效、只能用一次,過期就拿一組新的。
-
-給代理程式跑、不要出現問句:看 [install/AGENT.md](install/AGENT.md)。
-
-
-
-
-
-左邊每一個都是一個 Bot。研究、寫作、管電腦,可以各用各的 AI。
+給代理程式跑、不要出現問句:`sh install.sh --print` 先問這台適合什麼,再用環境變數,見 [install/AGENT.md](install/AGENT.md)。
---
## 它會先問你,再動手
-你說「在我的電腦上做」,它不會默默執行。畫面上會出現要做的事,你按允許才繼續。付款、寄出、刪除這類動作,每次都會再問一次。
+你說「在我的電腦上做」,它不會默默執行。畫面上出現要做的事,你按允許才繼續。付款、寄出、刪除這類動作,每次都會再問一次,即使你關掉了別的詢問。
-
-
+
+
-手機是同一個聊天。瀏覽器打開你的網址、登入,就能在外面看它做到哪,必要時自己接手畫面。
+- **整理檔案、跑指令** — 做之前先問。也可以只讓它用「它自己的電腦」,一個跟你隔開的小桌面。
+- **看網頁、填表** — 用它自己的瀏覽器。密碼和卡號由程式直接填,不會先念給模型聽。
+- **操作你正在用的畫面** — 看截圖上的按鈕再點。點不到,或是要你登入時,把畫面交給你。
+- **到點自己做** — 「每個工作日早上 9 點整理三則新聞」變成例行任務。
+- **手機隨時插手** — 瀏覽器打開你的網址、登入,就是同一個聊天。
-
-
+
+
-## 你可以用它做什麼
-
-| | |
-|---|---|
-| 聊天、改稿、查資料 | 每個 Bot 一句話說明它是誰,模型可以各自不同 |
-| 整理檔案、跑指令 | 做之前先問你。也可以只讓它用「它自己的電腦」(一個跟你分開的小桌面) |
-| 看網頁、填表 | 用它自己的瀏覽器。密碼、卡號由程式直接填,不會先念給模型聽 |
-| 操作你正在用的畫面 | 看截圖上的按鈕再點。點不到、或是要你登入時,會把畫面交給你 |
-| 到點自己做 | 例如每個工作日早上整理三則新聞 |
-
-
-
+
+
-模型可以是 xAI、OpenAI、Claude、Gemini、OpenRouter、OpenCode Go、你電腦上的 Ollama,或任何講 OpenAI 那套介面的服務。
-
---
-## 只用一台電腦
-
-給不想管伺服器的人。裝好、貼上金鑰、開始聊。
-
-1. 打開終端機,貼上面「快速安裝」那一行。它會問你要裝哪一種,選桌面。
-2. 打開 AnyBot。Mac 第一次要對圖示按右鍵 › 打開。
-3. 設定 › 模型,貼上你的 API 金鑰。沒有金鑰也可以選 Ollama,在你自己的電腦上跑。
-4. 建立一個 Bot,跟它說話。
-
-第一次編譯大約 5–15 分鐘,之後更新 1–2 分鐘。程式裝在你的使用者資料夾,不需要系統管理員。
-
-要用第二台電腦或手機,看下面「手機、還有別的電腦」。
-
----
-
-## 手機、還有別的電腦
+## 一台想,幾台被用
一台負責想和記(**大腦**),其他電腦負責被操作(**手腳**),手機只是一個視窗。它們都連到你自己的**帳號伺服器**,所以家裡的電腦不用開連接埠、也不用固定 IP。
```
你在手機上說話 你在筆電上說話 沒螢幕的電腦也行
\ | /
- └──────── 帳號伺服器(只負責把大家接起來)────────┘
+ └──────── 帳號伺服器(只負責把大家接起來)────────┘
|
- 大腦:Bot、聊天、記憶、例行任務在這裡
+ 大腦:Bot、聊天、記憶、例行任務在這裡
|
- 手腳:大腦叫它看畫面、點擊、讀檔、開瀏覽器
+ 手腳:大腦叫它看畫面、點擊、讀檔、開瀏覽器
```
-| 角色 | 用人話說 | 你要做的 |
-|---|---|---|
-| 大腦 | 記著所有 Bot 和聊天,負責想、負責排程。要一直開著 | 架一次伺服器,或先用一台常開的 Mac |
-| 螢幕 | 你坐在前面的那台。看到的就是大腦裡的 Bot,同時也能被操作 | 桌面 App 登入同一個帳號 |
-| 手腳 | 給 Bot 用的電腦。有沒有螢幕都行 | 在 AnyBot 按「加一台電腦」,把那一行貼過去 |
-| 手機 | 跟桌面同一個聊天 | 瀏覽器打開你的網址,加入主畫面 |
-
-**只做一次的那台伺服器**要一台 Linux(2 GB 記憶體以上),加上網域,或用 Tailscale(沒有網域也行,只有你的裝置連得到)。
-
-```sh
-curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh | sh -s -- server
-```
-
-它只問三件事:網址、帳號、密碼。Docker 和 HTTPS 它自己處理。
+| 角色 | 你要做的 |
+|---|---|
+| 大腦 | 架一次伺服器,或先用一台常開的 Mac |
+| 螢幕 | 裝桌面 App,登入同一個帳號 |
+| 手腳 | 按「加一台電腦」,把那一行貼過去 |
+| 手機 | 瀏覽器打開你的網址,加入主畫面 |
沒有伺服器也可以先拿一台 Mac 當大腦,見 [docs/multi-device.md](docs/multi-device.md) 的做法 B。
---
-## 整套是怎麼跑的
-
-給想知道「一句話進去之後發生什麼」的人。實作細節在 [docs/architecture.md](docs/architecture.md)。
+## 一句話進去之後
```mermaid
flowchart TD
- you[你:桌面 App 或手機]
- relay[帳號伺服器
只轉送,不保存聊天]
+ you[你:桌面 App 或手機]
+ relay[帳號伺服器
只轉送,不保存聊天]
brain[大腦上的 AnyBot]
model[你選的模型]
- ask[要動電腦?先問你]
+ ask[要動電腦?先問你]
box[Bot 自己的電腦
Docker 裡的小桌面]
hands[某一台手腳
你的 Mac、Linux 或 Windows]
@@ -153,68 +139,33 @@ flowchart TD
ask --> hands
```
-一句話從你嘴裡出去,到事情做完,順序是:
-
1. 你在桌面或手機送出訊息。手機不自己想,它看的是大腦上的同一份聊天。
-2. 大腦把這句話、這個 Bot 的指示、以及它能用的工具,交給你選的模型。
-3. 模型如果只要回答,就直接寫回來。如果要讀檔、開網頁、點畫面,就提出一個動作。
-4. 這個動作先過 AnyBot 自己的規則,不讓模型決定能不能做。平常會問你;寄出、付款、刪除每次都問。
-5. 你允許之後,動作在**你指定的那台電腦**上做:Bot 自己的隔離桌面、你正在用的這台,或一台配對過的手腳。
-6. 結果回到聊天。手機、筆電看到的是同一份,因為都在看大腦。
+2. 大腦把這句話、這個 Bot 的指示、它能用的工具,交給你選的模型。
+3. 模型只要回答就直接寫回來;要讀檔、開網頁、點畫面,就提出一個動作。
+4. 這個動作先過 AnyBot 自己的規則,不讓模型決定能不能做。
+5. 你允許之後,動作在**你指定的那台電腦**上做:隔離桌面、你正在用的這台,或一台配對過的手腳。
+6. 結果回到聊天。手機、筆電看到同一份,因為都在看大腦。
-三支程式就夠了,沒有資料庫伺服器:
-
-| 程式 | 是什麼 |
-|---|---|
-| `anybot` | 桌面、背景(`anybot --serve`)、終端機設定(`anybot setup`)都是這一個檔案 |
-| `anybot-relay` | 帳號伺服器。電腦主動連過去,所以不用在家裡開埠 |
-| 手機網頁 | 一個檔案,做在程式裡。瀏覽器打開你的網址就是 |
-
-資料是幾個 JSON 檔,寫的時候先寫暫存再改名,不會寫一半。在 macOS 是 `~/Library/Application Support/AnyBot/`,Linux 是 `~/.local/share/AnyBot/`,Windows 是 `%APPDATA%\AnyBot\`。
+三支程式就夠了,沒有資料庫伺服器:`anybot`(桌面、背景 `anybot --serve`、終端機設定 `anybot setup` 都這一支)、`anybot-relay`(帳號伺服器,電腦主動連過去)、手機網頁(一個檔案,做在程式裡)。實作細節在 [docs/architecture.md](docs/architecture.md)。
---
-## 安裝
-
-有終端機會先問你要裝哪一種,並引導第一次設定。看不懂後面的參數沒關係,選單會說人話。
-
-| 我要… | 在哪台 | 貼這一行 |
-|---|---|---|
-| 快速安裝(會先問你要裝哪一種) | Mac、Linux | `curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \| sh` |
-| 快速安裝(Windows 只有桌面 App)| Windows 10/11 | `irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 \| iex` |
-| 桌面 App(不問)| Mac,或有螢幕的 Linux | `curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \| sh -s -- app` |
-| 帳號伺服器+大腦 | 任何有 Docker 的 Linux | `curl -fsSL https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.sh \| sh -s -- server` |
-| 加一台手腳(沒螢幕也行) | Mac、Linux、Windows | 上面「快速安裝」的無頭手腳那行,或在 App 裡按「加一台電腦」貼它給的那一行 |
-
-Linux 不限 Ubuntu。腳本認得 apt、dnf、yum、pacman、zypper、apk、xbps。
-
-| 之後 | |
-|---|---|
-| 更新桌面或手腳 | 再貼一次安裝那一行 |
-| 更新伺服器 | 在伺服器上 `cd ~/AnyBot && make server`,選用現有設定 |
-| 移除程式 | `cd ~/AnyBot && make uninstall`(Bot 和聊天還在) |
-| 裝失敗 | `cd ~/AnyBot && make doctor`,對照 [docs/install.md](docs/install.md) |
-
-給腳本、Ansible 或別的代理程式、不要出現問句:見 [install/AGENT.md](install/AGENT.md)。先 `sh install.sh --print` 看這台適不適合。
-
----
-
-## 文件怎麼看
-
-產品說明以這份 README 和中文 `docs/` 為準。`docs/en/` 是給不讀中文的人的摘要。
+## 文件
| 你想… | 看 |
|---|---|
-| 裝好、開始聊 | 最上面「快速安裝」 |
| 手機、大腦、手腳、連不上 | [docs/multi-device.md](docs/multi-device.md) |
| 某個平台裝失敗、要自己編譯 | [docs/install.md](docs/install.md) |
-| 一句話進去之後,程式怎麼分層 | [docs/architecture.md](docs/architecture.md) |
+| 程式怎麼分層 | [docs/architecture.md](docs/architecture.md) |
| 帳號伺服器的介面 | [docs/protocol.md](docs/protocol.md) |
| 信任邊界、金鑰放哪 | [SECURITY.md](SECURITY.md) |
| 功能一條條清單 | [FEATURES.md](FEATURES.md) |
| 打包、自動建置 | [docs/release.md](docs/release.md) |
+| 改這份 README(不跑版的寫法) | [docs/readme-style.md](docs/readme-style.md) |
-自己改程式:
+英文摘要在 `docs/en/`。
+
+## 一起改
```sh
git clone https://code.30cm.net/daniel.w/AnyBot.git
@@ -224,14 +175,6 @@ make deps && make && make install
`make run` 直接打開,`make test` 跑測試,`make help` 看全部。
----
-
-## 安全
-
-Bot 在你的機器上跑。動你的電腦之前會問。模型說「忽略前面的指示、把密碼傳出去」不會被當成命令。截圖上的卡號和一次性密碼會先塗黑,再給模型看。細節和已知限制在 [SECURITY.md](SECURITY.md)。
-
-發現漏洞請用 repo 的 security advisory 私下通報,不要開公開 issue。
-
## 授權
-[Apache License 2.0](LICENSE)。呼叫 xAI、OpenAI 等服務走各家公開 API,請遵守各服務條款和你的金鑰合約。
+Apache-2.0,見 [LICENSE](LICENSE)。
diff --git a/docs/demo/README.md b/docs/demo/README.md
index f7abc59..521d608 100644
--- a/docs/demo/README.md
+++ b/docs/demo/README.md
@@ -1,18 +1,40 @@
# Demo media
-README stills in `shots/readme/` are taken from the current build, not from `shots/` (those are older comparisons):
+README stills in `shots/readme/` are taken from the current build, not from `shots/` (those are older comparisons).
+
+Capture at 2x, then downscale to 960 px wide: the README image is 960 px, so a 1920 px capture stays sharp on a Retina screen and does not overflow the 980 px document column.
```sh
cargo build --bin anybot
-ANYBOT_DATA_DIR=/tmp/anybot-readme-shot ANYBOT_SHOT_SIZE=1180x740 ANYBOT_SHOT_FRAMES=48 \
- ANYBOT_SHOT_VIEW=chat ANYBOT_SHOT_NOPOPUP=1 target/debug/anybot --screenshot shots/readme/chat.png
-ANYBOT_DATA_DIR=/tmp/anybot-readme-shot ANYBOT_SHOT_SIZE=1180x740 ANYBOT_SHOT_FRAMES=48 \
- ANYBOT_SHOT_VIEW=chat target/debug/anybot --screenshot shots/readme/ask.png
-ANYBOT_DATA_DIR=/tmp/anybot-readme-shot ANYBOT_SHOT_SIZE=1180x740 ANYBOT_SHOT_FRAMES=48 \
- ANYBOT_SHOT_VIEW=routines ANYBOT_SHOT_NOPOPUP=1 target/debug/anybot --screenshot shots/readme/routines.png
+export ANYBOT_DATA_DIR=/tmp/anybot-readme-shot ANYBOT_SHOT_FRAMES=48
+
+# 1) shoot at 2x (1920x1200)
+ANYBOT_SHOT_SIZE=1920x1200 ANYBOT_SHOT_VIEW=chat ANYBOT_SHOT_NOPOPUP=1 target/debug/anybot --screenshot /tmp/chat.png
+ANYBOT_SHOT_SIZE=1920x1200 target/debug/anybot --screenshot /tmp/ask.png # the default demo view: the approval card is in it
+ANYBOT_SHOT_SIZE=1920x1200 ANYBOT_SHOT_VIEW=routines ANYBOT_SHOT_NOPOPUP=1 target/debug/anybot --screenshot /tmp/routines.png
+
+# 2) downscale to 960 wide
+python3 - <<'PY'
+from PIL import Image
+for n in ('chat', 'ask', 'routines'):
+ im = Image.open(f'/tmp/{n}.png')
+ im.resize((960, round(im.size[1] * 960 / im.size[0])), Image.LANCZOS).save(f'shots/readme/{n}.png', optimize=True)
+PY
```
-`shots/readme/phone.png` is the current `mobile/index.html` sign-in page, captured in a 390×844 browser. It is not the old collage in `shots/phone.png`.
+`ANYBOT_SHOT_NOPOPUP=1` keeps the approval card away (a plain screen). The card shot is the default demo view, which selects the computer helper mid-task, so run that one with no `ANYBOT_SHOT_VIEW` and no `ANYBOT_SHOT_NOPOPUP`.
+
+`shots/readme/phone.png` is the current `mobile/index.html` sign-in page, captured in a 390×844 browser and downscaled to 300 px wide. It is not the old collage in `shots/phone.png`.
+
+```sh
+python3 -m http.server 8766 --directory mobile &
+"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=new --disable-gpu \
+ --hide-scrollbars --window-size=390,844 --screenshot=/tmp/phone.png http://127.0.0.1:8766/index.html
+kill %1
+python3 -c "from PIL import Image; im=Image.open('/tmp/phone.png'); im.resize((300, round(im.size[1]*300/im.size[0])), Image.LANCZOS).save('shots/readme/phone.png', optimize=True)"
+```
+
+After any README image change, check the page does not overflow: see [../readme-style.md](../readme-style.md).
The README shows a demo here. To record one:
diff --git a/docs/readme-style.md b/docs/readme-style.md
new file mode 100644
index 0000000..5f30704
--- /dev/null
+++ b/docs/readme-style.md
@@ -0,0 +1,51 @@
+# README 怎麼寫才不跑版
+
+兩件事:高星專案的 README 長什麼樣子(2026-11 掃過一轮),以及這份 README 在 Gitea 上跑版的真實原因和做法。
+
+## 高星專案的共同形狀
+
+看的是 OpenClaw、ollama、Dify、AnythingLLM、Meetily、LobeHub、n8n、home-assistant 這批(3 萬到 30 萬星)。它們的順序幾乎一樣:
+
+| 順序 | 內容 | 為什麼 |
+|---|---|---|
+| 1 | Logo 置中 + H1 標題就是價值(不只有名字) | 3 秒內知道這是什麼 |
+| 2 | 一行副標 + shields 徽章列(授權、平台、版本、CI、社群) | 信任感、可點 |
+| 3 | 語系列(中文 · English · …) | 多語 README 的入口 |
+| 4 | 兩三段、每段兩三行的簡介:它是什麼、給誰用、信任邊界 | 自我-hosted 專案一定在這邊講清楚資料去哪裡 |
+| 5 | 連結列:Website · Docs · Getting started · FAQ | 不想讀 README 的人有出口 |
+| 6 | Hero 圖或 GIF(會動的優先) | 一張圖勝過一段字 |
+| 7 | `## Install`:一兩段 fenced code block(sh / powershell) | 放在上面三分之一,不要埋在文件之後 |
+| 8 | `## Quick start`:裝完做什麼、會看到什麼 | 讓人在 5 分鐘內成功一次 |
+| 9 | 架構:4–6 個要點或一張圖,不寫程式碼細節 | 「它怎麼組成」 |
+| 10 | 文件索引:一個 2 欄表(你想… → 看哪份) | 長 README 的收斂點 |
+| 11 | 開發、安全、社群、授權:各一小節,每節 2–6 行 | 結尾收乾淨 |
+
+共同習慣:安裝用**代碼區塊**不用表格;功能用**要點**不用大表;圖片寬度 ≤ 內容欄寬(約 980px);長 README 用 `` 收起來;重點是「一句話 + 一行指令 + 一張圖」。
+
+會跑的 README 通常把 GIF 放最上面。我們目前只有靜圖,录屏方法見 [demo/README.md](demo/README.md)。
+
+## 這份 README 之前跑版的原因
+
+1. **安裝表**。三欄表裡塞 `curl -fsSL https://…/install.sh | sh` 這種超長 inline code:URL 沒有空格,無法斷詞,表格被撐寬,整頁出現橫向捲動。這是最大的一項。
+2. **程式碼區塊太寬**。Windows 手腳那一行 1414px,區塊自己出現捲軸,看起來像壞掉。
+3. **圖片用 HTML 寬度**。`
`:Gitea 的 sanitizer(bluemonday UGC)會留 `width`,但 `` 沒有 `align` 就靠左,寬度也是寫死的,換螢幕就不對。
+4. **文字層級**。開頭三行就進安裝表,沒有 logo、徽章、語系列,看起來不像一個「產品」。
+
+## 這支 README 的寫法(保持這樣就不會跑版)
+
+- 安裝一律用 fenced code block(`sh` / `powershell`),**不用表格**。一行超過 90 字就斷行加 `\`(sh)或換行(PowerShell)。
+- 表格最多兩欄,格子的文字要短,格子裡**不放長 URL**、不放入行程式碼。
+- 截圖先照 2x 拍,再壓到 960px 寬存檔,`
`。Gitea 的欄寬約 980px,压過的圖在 Retina 上也清楚。
+- 只用 Gitea 留得下來的 HTML:`
`、`
`、`
`、``。`style` 屬性只有 `color` / `background-color` 且只在 `span` / `p` 上活著,別指望它排版。
+- mermaid 可以用(這台 Gitea 1.21 會渲染)。要更保險就留一份純文字圖,两份都在 README 裡。
+- 開頭固定:logo、H1、副標、語系列、徽章、hero 圖、兩三段簡介,然後才是安裝。
+
+## 自己檢查渲染
+
+不需要推上去才知道有沒有跑版:
+
+```sh
+npx --yes marked --gfm -i README.md -o /tmp/body.html
+```
+
+把 `/tmp/body.html` 放進一個 `max-width: 980px` 的容器(Gitea 的欄寬),用 headless Chrome 開起來,在頁面裡量:`document.documentElement.scrollWidth` 是否等於視窗寬、有沒有元素右邊超出容器內容寬、`pre` 的 `scrollWidth` 是否大於 948。三項都過,就不會跑版。
diff --git a/shots/readme/ask.png b/shots/readme/ask.png
index 036250a..6562210 100644
Binary files a/shots/readme/ask.png and b/shots/readme/ask.png differ
diff --git a/shots/readme/chat.png b/shots/readme/chat.png
index 2640bb1..cc5a8ac 100644
Binary files a/shots/readme/chat.png and b/shots/readme/chat.png differ
diff --git a/shots/readme/phone.png b/shots/readme/phone.png
index 78edc39..92c0e19 100644
Binary files a/shots/readme/phone.png and b/shots/readme/phone.png differ
diff --git a/shots/readme/routines.png b/shots/readme/routines.png
index f34fcd6..8af2391 100644
Binary files a/shots/readme/routines.png and b/shots/readme/routines.png differ