diff --git a/README.en.md b/README.en.md index 8e81830..6dc4cb1 100644 --- a/README.en.md +++ b/README.en.md @@ -76,18 +76,14 @@ Running this from an agent, with no questions asked: `sh install.sh --print` rep 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.
-
+
-
-
@@ -161,7 +157,6 @@ Three programs are enough, and there is no database server: `anybot` (the deskto
| 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) |
Chinese is the source of truth; `docs/en/` is a summary for people who do not read Chinese.
diff --git a/README.md b/README.md
index 288d036..0d4a559 100644
--- a/README.md
+++ b/README.md
@@ -76,18 +76,14 @@ irm https://code.30cm.net/daniel.w/AnyBot/raw/branch/main/install.ps1 | iex
你說「在我的電腦上做」,它不會默默執行。畫面上出現要做的事,你按允許才繼續。付款、寄出、刪除這類動作,每次都會再問一次,即使你關掉了別的詢問。
-
+
-
-
@@ -161,7 +157,6 @@ flowchart TD
| 信任邊界、金鑰放哪 | [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/`。
diff --git a/docs/demo/README.md b/docs/demo/README.md
index 521d608..1dfdf4b 100644
--- a/docs/demo/README.md
+++ b/docs/demo/README.md
@@ -1,19 +1,20 @@
# Demo media
-README stills in `shots/readme/` are taken from the current build, not from `shots/` (those are older comparisons).
+README 用的圖(`shots/readme/`)一律從**目前這版程式**重拍,不要用 `shots/`(那是舊的對比圖)。
-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.
+統一用深色(`ANYBOT_SHOT_DARK=1`)、照 2x 拍、再壓到 960px 寬:README 的圖就是 960px,這樣在 Retina 上清楚,也不會撐破文件欄(約 980px)。
+
+## 拍桌面
```sh
cargo build --bin anybot
-export ANYBOT_DATA_DIR=/tmp/anybot-readme-shot ANYBOT_SHOT_FRAMES=48
+export ANYBOT_DATA_DIR=/tmp/anybot-readme-shot ANYBOT_SHOT_FRAMES=48 \
+ ANYBOT_SHOT_SIZE=1920x1200 ANYBOT_SHOT_DARK=1
-# 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
+ANYBOT_SHOT_VIEW=chat ANYBOT_SHOT_NOPOPUP=1 target/debug/anybot --screenshot /tmp/chat.png
+target/debug/anybot --screenshot /tmp/ask.png # 預設示範資料:裡面就有允許卡片
+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'):
@@ -22,9 +23,11 @@ for n in ('chat', 'ask', 'routines'):
PY
```
-`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`.
+`ANYBOT_SHOT_NOPOPUP=1` 把允許卡片壓掉(拍乾淨的畫面)。要卡片就**不要**加 `ANYBOT_SHOT_VIEW`,預設的示範資料會選到正在等允許的那個 Bot。
-`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`.
+## 拍手機
+
+`shots/readme/phone.png` 是目前的 `mobile/index.html`,390×844 的瀏覽器截圖,壓到 300px 寬。不是舊的 `shots/phone.png` 那張拼圖。
```sh
python3 -m http.server 8766 --directory mobile &
@@ -34,19 +37,28 @@ 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).
+手機頁面預設跟著系統深淺色;README 的圖是深色,拍之前在那支手機(或 Chrome 的模擬偏好)設成深色。
-The README shows a demo here. To record one:
+## 電腦 + 手機那張合成圖
-1. Start AnyBot (desktop) and a bot with a key; run at 1440p, hide notifications.
-2. Record a 20–40 s clip of one complete task, e.g. "organise the Downloads folder"
- (chat → plan → tool steps → files moved) and one computer-use task
- (bot opens the browser, fills a form, stops before Send — the approval card
- popping up **is** the product).
-3. Export GIF: `ffmpeg -i clip.mov -vf "fps=12,scale=960:-1:flags=lanczos,split[a][b];[a]palettegen[p];[b][p]paletteuse" docs/demo/anybot.gif`
- (keep it under ~8 MB; if bigger, cut to one task).
-4. Name it `docs/demo/anybot.gif`. The README comment shows where to un-comment
- the `` line.
+README 中間用一張合成圖(左:桌面允許卡片,右:手機登入),手機才不會被单独摆在中间、被挤到一边。合成是程式做的,重拍後重跑一次:
-Preferred: one GIF (desktop, computer-use with the approval card) + one 30 s
-MP4 (`demo.mp4`) of the phone app pairing a new machine.
+```sh
+python3 docs/demo/composite.py # shots/readme/{ask,phone}.png → computer-phone.png
+```
+
+改大小就編輯 `docs/demo/composite.py` 最上面的 `W / pad / gap / phone_w`。
+
+## 動圖(還沒有)
+
+README 上最好有一段會動的。要录:
+
+1. 打開桌面 App、金鑰設好,螢幕 1440p,關掉通知。
+2. 录 20–40 秒一件事從頭到尾,例如「整理下載資料夾」(聊天 → 計畫 → 工具步驟 → 檔案真的被搬動),加一段操作電腦(開瀏覽器、填表、在送出前停下——**允許卡片跳出來那一刻就是產品**)。
+3. 輸出 GIF:`ffmpeg -i clip.mov -vf "fps=12,scale=960:-1:flags=lanczos,split[a][b];[a]palettegen[p];[b][p]paletteuse" docs/demo/anybot.gif`
+ (控制在 8 MB 內,太大就只留一件事)
+4. 檔名 `docs/demo/anybot.gif`,README 註解裡有要放的位置。
+
+偏好:一支 GIF(桌面 + 電腦操作 + 允許卡片)加一支 30 秒 MP4(`demo.mp4`,手機配對新電腦)。
+
+改完圖,照 [../readme-style.md](../readme-style.md) 最後面那段檢查有沒有跑版。
diff --git a/docs/demo/composite.py b/docs/demo/composite.py
new file mode 100644
index 0000000..95c10d1
--- /dev/null
+++ b/docs/demo/composite.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+"""Build the README's computer-and-phone still from the two raw shots.
+
+Run docs/demo/README.md's capture steps first (dark, 2x), then:
+
+ python3 docs/demo/composite.py
+"""
+from PIL import Image, ImageDraw
+from pathlib import Path
+
+root = Path(__file__).resolve().parents[2]
+shots = root / "shots" / "readme"
+BG = (22, 22, 22) # the app's dark pane, so the canvas reads as one screen
+
+desk = Image.open(shots / "ask.png").convert("RGB") # the approval card
+phone = Image.open(shots / "phone.png").convert("RGB") # the sign-in page
+
+W, pad, gap, phone_w = 960, 24, 24, 264
+phone_h = round(phone.size[1] * phone_w / phone.size[0])
+desk_w = W - 2 * pad - gap - phone_w
+desk_h = round(desk.size[1] * desk_w / desk.size[0])
+H = pad + max(phone_h, desk_h) + pad
+
+def rounded(im, r):
+ mask = Image.new("L", im.size, 0)
+ ImageDraw.Draw(mask).rounded_rectangle([0, 0, *im.size], radius=r, fill=255)
+ out = Image.new("RGB", im.size, BG)
+ out.paste(im, (0, 0), mask)
+ return out, mask
+
+canvas = Image.new("RGB", (W, H), BG)
+im, mask = rounded(desk.resize((desk_w, desk_h), Image.LANCZOS), 12)
+canvas.paste(im, (pad, pad + (phone_h - desk_h) // 2), mask)
+im, mask = rounded(phone.resize((phone_w, phone_h), Image.LANCZOS), 18)
+canvas.paste(im, (W - pad - phone_w, pad), mask)
+
+out = shots / "computer-phone.png"
+canvas.save(out, optimize=True)
+print(out.relative_to(root), canvas.size)
diff --git a/shots/readme/ask.png b/shots/readme/ask.png
index 6562210..b9c824e 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 cc5a8ac..7763f11 100644
Binary files a/shots/readme/chat.png and b/shots/readme/chat.png differ
diff --git a/shots/readme/computer-phone.png b/shots/readme/computer-phone.png
new file mode 100644
index 0000000..05194ee
Binary files /dev/null and b/shots/readme/computer-phone.png differ
diff --git a/shots/readme/routines.png b/shots/readme/routines.png
index 8af2391..21b4483 100644
Binary files a/shots/readme/routines.png and b/shots/readme/routines.png differ