Commit Graph

14 Commits

Author SHA1 Message Date
王性驊 983a2c2f02 install.sh: stop dying on macOS at the compile step
"$RUST_HOST;" is one variable name to macOS /bin/sh (bash 3.2): it
swallows the first byte of the full-width punctuation, so with set -u a
plain \`sh install.sh app\` aborted at [3/4] with "RUST_HOST\*: unbound
variable". Four such lines in install.sh, one in the server setup.
Brace them, add make lint-sh (sh -n for every shipped script plus a
check for this pattern) so it stays fixed.
2026-11-10 14:32:56 +08:00
王性驊 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
AnyBot Dev 5f7efd7dba Plan: P6 complete (step 2: embeddings + document shelf) 2026-11-09 20:23:38 +08:00
AnyBot Dev bc779d68c5 Server: drive Docker through a filtered socket proxy, never mount the raw socket 2026-11-09 16:36:51 +08:00
王性驊 00f6723588 HTTPS on the local network's own IP, with a certificate the server signs itself
setup.sh offers 「區網 IP」 (alone, or next to Tailscale): Caddy serves https://<LAN IP> with its
own small certificate authority (tls internal, default_sni for clients that send no name) and
hands out the root at http://<LAN IP>/anybot-ca.crt for each device to trust once.
docker-compose.lan.yml binds Caddy to that address only, so it sits beside tailscale serve.

The app now accepts, for the account server, the certificates this computer trusts as well as
the built-in public ones (HTTP and the WebSocket alike), so it connects once the root is
trusted; before that it says what to install instead of "the certificate is wrong".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha2RVfSYmrhqNnqx9Z4
2026-11-07 21:27:07 +08:00
王性驊 4605b317d8 Bot 的電腦 can run under gVisor: its own kernel, Chromium's sandbox back on
容器隔離 in 設定 › 電腦: standard (runc, the container is the only wall, Chromium runs
--no-sandbox) or hardened (runsc: a virtualized kernel, all capabilities dropped but the few
the desktop needs, ANYBOT_BOX_SANDBOX=1 turns Chromium's own sandbox back on). Box image v7.
deploy/mac/gvisor-vm.sh makes a Lima VM with Docker + gVisor for a Mac (started at login),
gvisor-migrate.sh moves the box's files and logins there.

Checked and finished before committing:
- the hardened choice is offered only on a Docker host that has runsc; a box set to it on a
  host without it opens the standard way and says so (it used to not start at all)
- the settings row shows what the box really runs on, and when 更新 is needed
- no swap only under gVisor (a standard box keeps Docker's default)
- the migrate script sees the running Mac app ("AnyBot", not "anybot")
- the VM script starts an existing VM by name, checks runsc and the kernel from the Mac
- the version test says 7

Real run in the Lima VM: desktop, VNC, numbered controls, xdotool and screenshots work; no
Chromium process has --no-sandbox, renderers run with seccomp and their own namespaces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha2RVfSYmrhqNnqx9Z4
2026-11-07 00:03:25 +08:00
王性驊 a202a96c02 Server image: keep dependencies fetched from GitHub between builds
agent-desktop comes from GitHub, and only the crates registry and target were cached, so every
server update fetched it again; a slow GitHub made nobledesktop's update fail (cargo exit 101, then
a fetch that hung for over ten minutes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha2RVfSYmrhqNnqx9Z4
2026-11-06 18:15:22 +08:00
王性驊 102746d9e8 A brain's box can go by its own name (ANYBOT_BOX_NAME); the server's brain takes over its old box under anybot-brain-box
A desktop AnyBot left on the server (older build) took "anybot-box" for its own and paused it
every ~20 s as idle while the brain woke it: the bots' computer kept showing as asleep. The
brain now renames its box once (files are in the volume, kept by name) and uses that name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 18:20:45 +08:00
王性驊 6d6461e4f3 Server setup: Tailscale address instead of a domain, and a no-questions mode
- setup.sh offers the computer's Tailscale address (HTTPS from tailscale serve, Caddy not
  started, nothing open to the internet) — docker-compose.tailscale.yml
- ANYBOT_SETUP_USER / ANYBOT_SETUP_PASSWORD [/ ANYBOT_SETUP_DOMAIN] answer the questions,
  for scripts and deployment tools; install.sh server passes them through

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha3oEtWeHh58zA7ErHa
2026-11-05 01:26:33 +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
王性驊 b153051e58 Lasting connection to the account server, per-item sync, files and models via the brain
- Each AnyBot keeps one WebSocket to the account server (pinged, reopened
  within a second when cut). Requests come down it at once; calls to other
  AnyBots of the account (brain sync, hands) go up it. Frames carry raw
  bytes, compressed when that saves space. HTTP long-poll stays as fallback.
- The account server knows at once when an AnyBot goes away.
- Edits to lists and maps go item by item, so two computers editing one
  list keep both changes.
- Screens fetch chat files from the brain, get model lists through the
  brain's keys, and show the brain's computer as the brain's.
- Moving this computer's bots skips starter bots the brain has and bots
  already moved.
- The phone goes to the brain instead of a computer that shows it.
- deploy/linux/hands.sh: a Linux computer (with or without a screen) as
  hands, kept running by systemd.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uirha3oEtWeHh58zA7ErHa
2026-11-04 19:30:32 +08:00
王性驊 d7ee3f5db9 AnyBot: first commit of the working desktop app
Rust/egui rebuild of Grok Bot as of 2026-11-04: chat with streaming
providers (xAI, OpenAI, Claude, Gemini, OpenRouter, OpenCode Go, Ollama,
custom), tools and approvals, the bot's Docker computer, computer use on
macOS / Linux X11 / Wayland, AnyBot's browser with a full DevTools-based
toolset, the encrypted vault, pinned grid and sidebar sections, Markdown
with Mermaid diagrams, phone access through the relay, and the Linux
build and test scripts.

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