A small CLI for the Browser Use Cloud. It manages your Boxes (cloud agent machines), opens shells in them, and gives an agent on a box consent-gated, read-only access to your laptop. A single Go binary — no local browser.
Prebuilt — no Go needed:
curl -fsSL https://github.com/ShawnPana/bux-cli/raw/main/install.sh | shDetects your OS/arch and downloads the matching binary from the latest release. (On a
private repo this needs gh authenticated — or use the from-source path below.)
From source — needs Go:
git clone https://github.com/ShawnPana/bux-cli && cd bux-cli
./install.sh # build (provisioner embedded) + put `bux` on PATH
./install.sh --link # dev: symlink the repo binary so rebuilds propagateThe build cross-compiles a Linux binary that's embedded so bux setup can provision boxes;
a plain go build -o bux . works but can't provision. Maintainers cut a release with
./release.sh [tag] — it cross-compiles every platform (pure Go, one host) and publishes
via gh.
Then:
bux link <api-key> # link your project
bux setup <project> <box> # install bux + the read-skill on a box (once per box)
bux share # serve approvals; auto-connects every set-up boxbux link <api-key> # link a project by storing its API key
bux projects # list linked projects (with plan/credits)
bux unlink <project> # forget a project
bux ls # boxes, grouped by project, sorted by creation
bux status box-1 # detail for one box
bux rename box-1 scraper # local label
bux open box-1 # open a shell in the box (default project)
bux open <project> box-1 # ...in a specific project
bux box-1 # shortcut for `bux open box-1`
bux open box-1 --print # just print the ssh command
bux setup box-1 # install/update bux + read-access skill on a box
bux upgrade box-1 # update an already-set-up box to this version
bux version # print this bux's versionA box is addressed by its name (box-1, or a custom name), the index in its project's
bux ls (# column, creation order — handy when a box was renamed), a short UUID prefix,
or its full UUID. Boxes get persisted sequential box-N names in creation order; rename
overrides them. So bux open 2 3 opens the 3rd box of the 2nd project. Most commands accept [project] as a leading argument or via
-p/--project — given either its name or the index bux ls prints next to it
(bux ls 2, bux open 2 box-1); --json gives machine-readable output (each group
carries its index).
State lives in ~/.browser-use-cloud/config.json (override with
$BROWSER_USE_CLOUD_HOME): the API key per project plus the local box-name registry.
The cloud host can be overridden with $BROWSER_USE_CLOUD_BASE_URL.
By default open gives you a persistent shell: it attaches (or creates) a tmux
session on the box with its status bar hidden, so it looks like a normal bux@box
shell but survives disconnects. To leave it running, detach with Ctrl-b Ctrl-b
d (or type tmux detach — foolproof when your laptop is also in tmux); the next
bux open <box> drops you back exactly where you were. exit closes it. (Persistence
is per-box-lifetime.) Pass --fresh for a plain one-shot shell instead.
bux <box> is a shortcut for bux open <box>. Your public key normally is already in
the box's authorized_keys. To bootstrap a box that doesn't have it, open --setup
installs your key deterministically by running an idempotent command in the box's bash
shell over the terminal websocket (POST /boxes/me/shell → WS …/terminal/{token}/ws)
— no LLM agent, no server-side changes.
main.go # bare-name argv rewrite → cobra
cmd/ # cobra commands (link/projects/ls/open/status/rename/setup/upgrade/share/fetch/version)
internal/
config/ client/ auth/ boxes/ terminal/ sshkeys/ output/
remote/ # the read-only fetch broker (protocol + Execute)
share/ # the approval broker, Channel interface, and event hub
setup/ # box provisioning (embedded binary + skill over SSH)
version/ # build-stamped version
Dependencies: cobra (CLI), coder/websocket (the --setup key install), and
charmbracelet/bubbletea + lipgloss (the bux share terminal UI). Otherwise stdlib.
Lets an agent on a box read your laptop's filesystem — list dirs, read files, copy
files out — where you approve every single request and nothing can write. No public
port and no token: bux share dials a reverse tunnel to each set-up box itself.
bux share— on your laptop. Auto-connects every set-up box (a kept-alive reverse tunnel each), serves a read-only approval server on127.0.0.1, and shows a terminal UI (Approvals + Boxes tabs) where youy/n/aeach request. You can also approve from Telegram if the box has a bot bound to a chat. Decisions are logged to~/.browser-use-cloud/share-audit.log.--no-connectskips auto-connect (boxes then reach you viabux open's-Rinstead).bux fetch list|read|grep|get <path>— the agent's command on the box; each call blocks until you approve.grep <pattern> <path>searches a tree read-only (RE2 regexp, skips binaries/.git/node_modules, caps at 500 hits).
Provisioning a box (all from the laptop — the binary is embedded in bux, so the box
needs no Go):
bux setup <project> <box>— install thebuxbinary + Claude Code skill (~/.claude/skills/bux-fetch/) on a box, and install your SSH key first if it's a fresh box. Idempotent and version-aware: it checks the box'sbux versionand no-ops if it already matches, so re-running is cheap. Does not start sharing.bux upgrade <project> <box>— update an already-set-up box to thisbux's version. Errors if bux isn't installed there yet (runsetupfirst); no-ops if already current.--forcere-pushes regardless. (setup --forcedoes the same on the install path.)bux upgrade --all [project]— upgrade every set-up box (all projects, or one). Prints the plan (box current → target) and asks to confirm;-yskips the prompt. Boxes that aren't actually installed are skipped, not failed, so a stale registry entry won't abort the batch.bux share --setup <project> <box>—setup+ start sharing, in one step.
bux ls shows the provisioned version in a SETUP column (— if not set up). The version
is stamped from git describe by ./build.sh, which you must use to build the
provisioner-enabled bux (a plain go build can share/fetch but not provision, and reports
its version as dev).
Read-only by construction — internal/remote uses only os.ReadDir/os.Open; there
is no write/edit/delete/exec path. All access lives and dies with bux share: quit it and
the tunnels close, so no box can reach your laptop. Agents should read SKILL.md, which
explains using bux fetch efficiently (each call costs you a click).
To give an unattended agent (e.g. on a VPS) write access to this private repo without
a GitHub account, use a deploy key. Run ./setup-deploy-key.sh in a checkout — it
generates a dedicated SSH key, wires up an ~/.ssh/config alias, points origin at it,
and sets a commit identity. Then add the printed public key as a write deploy key at
https://github.com/ShawnPana/bux-cli/settings/keys. Override defaults with env vars
(REPO, KEY, HOST_ALIAS, GIT_NAME, GIT_EMAIL).