AnyBot/Cargo.toml

91 lines
4.3 KiB
TOML
Raw Permalink Normal View History

[package]
name = "anybot"
version = "0.1.0"
license = "Apache-2.0"
edition = "2021"
# Older Rust stops with a clear message instead of odd errors deep in a dependency.
rust-version = "1.95"
[[bin]]
name = "anybot"
path = "src/main.rs"
[dependencies]
zhconv = "0.4"
eframe = "0.37"
ureq = { version = "3", features = ["json"] }
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 03:46:17 +00:00
# Web pages that are not UTF-8 (Big5, GBK, Shift_JIS…), read as what they say they are.
encoding_rs = "0.8"
# 長連線 to the account server (WebSocket over the same TLS ureq uses), and compressing what goes over it.
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
# Which certificates the account server may show: the public ones (built in), plus the ones this
# computer trusts itself, so a server on the local network that signs its own (https://10.0.0.25)
# works once this computer trusts it, the same as for the browser.
webpki-root-certs = "1"
rustls-native-certs = "0.8"
# Firefox keeps the names of its newer profiles (「女生」「阿金」…) only in a small SQLite file
# (Profile Groups/*.sqlite); bundled, so no system SQLite is needed.
rusqlite = { version = "0.41", features = ["bundled"] }
flate2 = "1"
# `anybot setup`: the guided setup in a terminal (servers and Linux computers without a window).
crossterm = "0.29"
unicode-width = "0.2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
dirs = "7"
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "gif", "webp", "bmp", "tiff", "ico"] }
base64 = "0.22"
People watch and help on the bots' computer through VNC (noVNC), carried by the account server The core: the bot works the computer; a person watches it like a colleague, and takes over when it needs them. VNC is made for that (only what changed, every mouse move and key, touch on phones), so the pictures sent one by one go, and with them their own input path. - vnc.rs: a VNC proxy to the box's x11vnc through one docker exec (a Python bridge that ends with either side). It signs in to the box with the box's own password (its VNC_PASSWORD) and offers the viewer no password, so the password never leaves the brain. The person's clicks and keys make the bot's steps wait until 8 s after they stop; text typed in the viewer's box (any language) is pasted in the box. - Account server: /screen (the viewer page) and /novnc.js (noVNC 1.6.0, MPL-2.0, bundled); /relay/vnc/<host> takes the browser's WebSocket (account session, or a 10-minute ticket the app asks for with POST /relay/screen-ticket; owners and admins) and carries it over that AnyBot's lasting connection (vopen / vdata / vtext / vclose). Both ends of that connection wait 2 ms instead of 40 ms to read while things move: a request and its answer took up to 160 ms more than needed. - Phone page: 看 Bot 的電腦 and 接管 open the viewer page (also on the local network: /api/vnc on the AnyBot's own phone server). This Mac's own screen moved to the ⋯ menu. - Mac app: 看畫面 opens the viewer in the browser (a screen of a brain: the brain's computer by ticket; else this computer's box, noVNC straight from it). The in-app picture viewer, the live JPEG stream, the person's click/move/scroll/key endpoints and the input shell are gone. - Opening a Mac app uses LaunchServices (`open -a`): agent-desktop's launch waited on the window through accessibility and failed without 輔助使用 now and then. Measured on this Mac (made-up account, local relay + headless brain + the real box): viewer signed in in 0.4–0.7 s, a request and its answer through relay + brain + box 25–58 ms median; headless Chrome shows the desktop live in /screen. remote_e2e 28/28 ×2, 149 unit tests, relay 11. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 15:05:44 +00:00
# VNC sign-in (the 16-byte challenge) for people watching the bots' computer.
des = "0.8"
chrono = "0.4"
chrono-tz = "0.10"
iana-time-zone = "0.1"
ring = "0.17"
tungstenite = { version = "0.30", default-features = false, features = ["handshake"] }
calamine = "0.38.0"
resvg = "0.49.0"
hayro = "0.9"
zip = { version = "9", default-features = false, features = ["deflate"] }
rodio = { version = "0.23", default-features = false, features = ["playback", "flac", "mp3", "mp4", "vorbis", "wav", "symphonia-aiff", "symphonia-alac", "symphonia-caf"] }
pdf-extract = "0.12"
unicode-normalization = "0.1"
cpal = "0.18"
mermaid-rs-renderer = { version = "0.3", default-features = false }
pulldown-cmark = { version = "0.13", default-features = false }
# Seeing and using other apps through the OS accessibility APIs (AX on macOS, AT-SPI on Linux,
# UI Automation on Windows): numbered UI elements a bot can act on without screenshots.
# vercel-labs/agent-desktop, Apache-2.0, pinned to a release.
agent-desktop-core = { git = "https://github.com/vercel-labs/agent-desktop", tag = "v1.1.0" }
argon2 = "0.5"
[profile.release]
opt-level = 2
[target.'cfg(not(target_os = "macos"))'.dependencies]
[target.'cfg(target_os = "linux")'.dependencies]
agent-desktop-linux = { git = "https://github.com/vercel-labs/agent-desktop", tag = "v1.1.0" }
x11rb = { version = "0.13", features = ["xtest", "screensaver", "record"] }
# Wayland: wlroots desktops (sway, Hyprland…) through their own protocols; GNOME and KDE through
# the desktop portals (one "allow" dialog, remembered).
wayland-client = "0.31"
# (wl.rs: SO_RCVTIMEO on the compositor socket, so a frozen compositor can't freeze the app)
libc = "0.2"
wayland-protocols = { version = "0.32", features = ["client", "staging", "unstable"] }
wayland-protocols-wlr = { version = "0.3", features = ["client"] }
wayland-protocols-misc = { version = "0.3", features = ["client"] }
memmap2 = "0.9"
ashpd = { version = "0.13", default-features = false, features = ["async-io", "remote_desktop", "screencast", "screenshot"] }
zbus = { version = "5", default-features = false, features = ["async-io", "blocking-api"] }
futures-lite = "2"
async-io = "2"
[target.'cfg(target_os = "macos")'.dependencies]
agent-desktop-macos = { git = "https://github.com/vercel-labs/agent-desktop", tag = "v1.1.0" }
One way to act on a screen: a real click or keystroke, wherever the bot looked - Acting by an app's number (read_app's e7) is now a real click at that control's spot, the same path as screenshot coordinates. agent-desktop only reads; its own actions (a second set with its own key names and failures: no typing in terminals, "/" and "`" failing off the main thread) are gone, with computer_use_select, background clicks and press_key's app. - Every action comes back with the screen after it (or, with no picture allowed, the front app's numbered controls), so the bot no longer spends a step on a screenshot to check. - Coordinates map without remembering a screenshot: the picture's size depends only on the screen. The phone's taps go straight to the screen as the person's, in the pixels of the picture it was sent; they used to borrow the bot's last screenshot scale and landed 1.25x off on the bots' computer, or failed with "screenshot first". - Mac typing pastes (⌘V, clipboard put back): with 注音 on, text sent as key events vanished while return arrived, so commands typed into a terminal ran empty. Bare printing keys ("slash", "r") are typed the same way; keys like "slash" and "grave" have names. - The bots' Docker computer: one docker exec per step (action, settle, picture), never `mousemove --sync` (it waits forever when the pointer is already there: a second click on the same spot hung two minutes), open_app (chromium = the browser browser_* drive, xterm). Tests: box_screen_is_exact (real Docker: bot and phone coordinates exact, same spot twice in under 2 s, ASCII + Chinese + named key typed), Calculator by numbers and Terminal typing under 注音 through the signed app, remote_e2e 28/28, Linux build + 151 tests + x11_live. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 13:51:19 +00:00
# Typing by pasting (any input method, any language); already in the build through egui.
arboard = { version = "3.7", default-features = false }
[target.'cfg(target_os = "windows")'.dependencies]
agent-desktop-windows = { git = "https://github.com/vercel-labs/agent-desktop", tag = "v1.1.0" }
windows = { version = "0.61", features = ["Win32_Foundation", "Win32_Graphics_Gdi", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_WindowsAndMessaging", "Win32_System_Threading"] }