Commit Graph

8 Commits

Author SHA1 Message Date
王性驊 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
王性驊 d3eae415c5 One AnyBot per data folder: a second copy says so instead of opening
Two copies on one folder each keep their own idea of the chats and overwrite each other's saves,
and a second copy starting up would take the first one's open turns in the work log for a crash
and close them. The window, `--serve` and `--ask` now hold an OS file lock on anybot.lock in the
data folder (flock; LockFileEx on Windows), and `anybot setup` holds it while it writes the
settings, after stopping the service and before starting it again.

The lock goes with the process however it ends, so a copy that crashed or was killed never blocks
the next one. A new copy waits up to 5 s for one that is closing (a relaunch, a service restart).
Past that, a second window shows a small notice naming the holder's process and the folder, and
`--serve` / `--ask` say it on stderr and exit 1 (launchd's and systemd's restart then retry). Each
ANYBOT_DATA_DIR has its own lock; a screenshot run doesn't take it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha5F5gJt93t3yEx3XcS
2026-11-09 00:49:42 +08:00
王性驊 4506cc149b Clippy is clean on macOS and Linux, for the app and the relay
Every warning `cargo clippy --all-targets` gave (50 on macOS, 8 more only on
Linux, 1 in the relay), fixed without changing what anything does:
- long types get a name (Peer, Members, Imported, Joining, Mention, Stream…);
- the two big enum variants are boxed (the vault's login plan, joining an
  account);
- a test now waits for the copy it relaunched (it left a zombie behind);
- a hint's format had a dead `if` whose two branches were both "";
- the rest is what clippy suggests: sort_by_key, as_chunks, is_none_or,
  is_multiple_of, while let, from_ref, next_back, struct init, no casts to
  the same type.

Checked: cargo test (177 macOS, 181 Linux), relay tests (11), remote_e2e
28/28, and the live Linux test (X11; Wayland clicks, keys, Chinese typing,
scroll and screenshots).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha2RVfSYmrhqNnqx9Z4
2026-11-07 10:10:28 +08:00
王性驊 dabb4113c2 Setup quotes service paths and writes launcher and unit files atomically 2026-11-05 15:48:22 +08:00
王性驊 370dbd91f7 Hands: their own virtual screen, even next to a logged-in desktop
A service set up without a screen (over SSH, or on Wayland) used to pick up the desktop
session's DISPLAY/WAYLAND_DISPLAY from systemd, so screenshots waited for a 「分享螢幕」
answer nobody could give. Now it starts its own virtual screen; `anybot setup --real-screen`
keeps the desktop. `anybot setup --refresh-service` rewrites the start script after an update
(install.sh runs it), so joined computers pick up such changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha3oEtWeHh58zA7ErHa
2026-11-05 08:10:13 +08:00
王性驊 472a004f87 One-step install: install.sh, fixed Linux and server builds, clearer README
- install.sh (curl | sh): app, hands, server and deps modes; installs system packages
  (right names per release, e.g. libasound2t64 on Ubuntu 24.04), Rust via rustup (1.95+),
  Docker for the server; limits parallel compiles on small machines
- Server Docker image: add the ALSA build/runtime packages (the build failed), cache the
  cargo registry and target between rebuilds, JOBS build arg
- 加一台電腦 now gives a line that installs AnyBot on a blank computer before joining it
- Makefile: make deps installs Rust too, make doctor, clear message when Rust is missing/old
- README rewritten: one line per use, getting started, update/remove, troubleshooting,
  deployment options; docs/install.md and multi-device.md follow it
- Tested on fresh ubuntu:24.04 (app) and debian:12 (curl | sh hands) containers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha3oEtWeHh58zA7ErHa
2026-11-05 00:52:10 +08:00
王性驊 365dc87e54 Add a computer with one line: pairing codes, simpler setups
- 加一台電腦 (phone menu and the app's 大腦 card) gives a ten-minute,
  one-time code and the line to run: anybot setup <address> <code>. The
  new computer joins as hands for that brain with no password and nothing
  to answer, starts with the computer and checks the brain sees it.
- anybot setup without arguments is one screen: address and code (a pasted
  line fills both), or the account and password instead. No role, name or
  confirm questions; a brain is asked only when there are several.
- Hands computers are no longer offered as brains.
- The server setup asks only the domain, account and password.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha3oEtWeHh58zA7ErHa
2026-11-04 20:56:06 +08:00
王性驊 cb922da3fe anybot setup and the server setup: guided setup with a brain picker
- anybot setup: a full-screen terminal guide (role, name, account server,
  account, which brain) that saves the settings, installs a systemd user
  service (with a virtual screen when there is none), and checks that the
  account server and the brain see the computer. Flags for scripts.
- Hands can be limited to one brain; the account server says which AnyBot
  asks. Choosing a brain in the app does the same.
- deploy/server/setup.sh: domain, account, sign-ups and keys step by step;
  writes .env and Caddyfile, starts everything and checks HTTPS. The
  server's brain creates the account on first start.
- deploy/linux/hands.sh installs what's needed and opens anybot setup
  (no password kept in a file any more).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha3oEtWeHh58zA7ErHa
2026-11-04 20:38:45 +08:00