buse: Stateless CLI for browser-use
Project description
buse
Control your browser from your terminal.
buse is a stateless CLI designed for AI agents and automation scripts. It turns complex browser interaction into simple, structured command-line primitives.
Key Features
- Stateless Control: Just point the CLI at a browser and go.
- Persistent Sessions: Multiple browser instances can run simultaneously.
- Universal Primitives: Click, type, scroll, and execute JS with one-liners.
- Vision-Ready:
observecommand captures state + screenshots in a single call. - Session Migration: Export cookies/storage via
save-stateto maintain persistent logins.
Why 'buse'?
Automating a browser usually means writing long, complex scripts or paying for expensive cloud services. buse changes that by letting you control a browser just like any other folder or file on your computer—using simple, one-word commands in your terminal.
For example, open a browser and navigate to a website:
uvx --python 3.12 buse browser-1
uvx --python 3.12 buse browser-1 navigate "https://example.com"
uvx --python 3.12 buse browser-2 # open a second browser
uvx --python 3.12 buse browser-2 search "latest tech news"
Installation
With uv:
uvx --python 3.12 buse --help
With pip:
pip install buse
From source:
cd buse
uv pip install -e .
Requirements
- Python 3.12
- Google Chrome (local install)
Usage Pattern
buse <instance_id> <command> [args]
Command List
1. Lifecycle & State
| Command | Description | Example |
|---|---|---|
<id> |
Initialize/Start a new browser instance | buse b1 |
list |
Show all active browser instances | buse list |
stop |
Stop and kill a browser instance | buse b1 stop |
save-state |
Export cookies/storage to a file | buse b1 save-state cookies.json |
2. Analysis & Extraction
| Command | Description | Example |
|---|---|---|
observe |
Snapshot DOM + optionally save screenshots | buse b1 observe --screenshot |
extract |
LLM extraction (set BUSE_EXTRACT_MODEL) |
buse b1 extract "get product info" |
observe notes
- DOM indices are ephemeral; refresh with
buse <id> observeafter page changes, or use--id/--classfor stability. observe --omniparseralways captures a screenshot: savesimage.jpg(input) andimage_som.jpg(server output) in the screenshots dir or--path.- When available,
screenshot_pathpoints toimage_som.jpg. OmniParserbboxvalues are in CSS pixels (not normalized). - Use
--no-domto skip DOM processing and return an emptydom_minified.
3. Navigation & Interaction
| Command | Description | Example |
|---|---|---|
navigate |
Load a specific URL (supports --new-tab) |
buse b1 navigate "https://google.com" |
new-tab |
Open a URL in a new tab (alias for navigate --new-tab) |
buse b1 new-tab "https://example.com" |
search |
Search the web (engines: google, bing, duckduckgo) |
buse b1 search "query" --engine google |
click |
Click by index, coordinates, or resolve by --id/--class |
buse b1 click --x 500 --y 300 |
input |
Type text into a field by index or --id/--class (use --text when no index) |
buse b1 input 12 "Hello" |
upload-file |
Upload a file to an element by index | buse b1 upload-file 5 "./img.png" |
send-keys |
Send special keys or text (use --list-keys for names, optional focus with --index/--id/--class) |
buse b1 send-keys "Enter" |
find-text |
Scroll to specific text on the page | buse b1 find-text "Contact" |
dropdown-options |
List options for a select element by index or --id/--class |
buse b1 dropdown-options 12 |
select-dropdown |
Select dropdown option by visible text and index or --id/--class (use --text when no index) |
buse b1 select-dropdown 12 "Option" |
hover |
Hover over an element by index or --id/--class |
buse b1 hover 5 |
scroll |
Scroll page or a specific element (use --up or --down) |
buse b1 scroll --up --pages 2 |
refresh |
Reload the current page | buse b1 refresh |
go-back |
Go back in browser history | buse b1 go-back |
wait |
Wait for N seconds | buse b1 wait 2 |
evaluate |
Execute custom JavaScript code | buse b1 evaluate "alert('Hi')" |
4. Advanced
| Command | Description | Example |
|---|---|---|
switch-tab |
Switch by 4-char tab ID | buse b1 switch-tab "4D39" |
close-tab |
Close by 4-char tab ID | buse b1 close-tab "4D39" |
Examples
Flag Matrix
Global (all commands):
--format(json|toon, default:json),-falias--profile(default:false),-palias
Commands:
list: no flags<id>: no flags (start/attach instance)observe:--screenshot(false),--path(unset),--omniparser(false),--no-dom(false)navigate:--new-tab(false)new-tab: no flagssearch:--engine(default:google)click:--x(unset),--y(unset),--id(unset),--class(unset)input:--text(unset),--id(unset),--class(unset)upload-file: no flagssend-keys:--index(unset),--id(unset),--class(unset),--list-keys(false)find-text: no flagsdropdown-options:--id(unset),--class(unset)select-dropdown:--text(unset),--id(unset),--class(unset)hover:--id(unset),--class(unset)scroll:--down/--up(down default),--pages(default:1.0),--index(unset)refresh: no flagsgo-back: no flagswait: no flagsswitch-tab: no flagsclose-tab: no flagssave-state: no flagsextract: no flagsevaluate: no flagsstop: no flags
Commands
# Start a session
buse b1
# Observe without screenshot (JSON)
buse b1 observe
# Observe with screenshot (JSON + image)
buse b1 observe --screenshot
# Navigate and click by coordinates
buse b1 navigate "https://example.com"
buse b1 click --x 280 --y 220
# Click by id/class fallback
buse b1 click --id "submit-button"
buse b1 click --class "cta-primary"
# Input by id with explicit --text
buse b1 input --id "email" --text "test@example.com"
# Upload a file
buse b1 upload-file 5 "./image.png"
# Send special keys
buse b1 send-keys "Enter"
# Send keys to a focused element
buse b1 send-keys --id "search" "Hello"
# List send-keys names
buse b1 send-keys --list-keys
# Find and scroll to text
buse b1 find-text "Contact Us"
# Get dropdown options and select by text
buse b1 dropdown-options --id "country"
buse b1 select-dropdown --id "country" --text "Canada"
# Scroll and wait
buse b1 scroll --down --pages 1.5
buse b1 scroll --up --pages 1
buse b1 wait 2
Output & Profiling
--format json|toonto switch output format.--profile(or-p) includes timing data in the JSON response.
Environment Variables
BUSE_EXTRACT_MODEL: model name forextract(default:gpt-4o-mini).OPENAI_API_KEY: required forextract.BUSE_KEEP_SESSION: set to1to keep the session open within a single process.BUSE_SELECTOR_CACHE_TTL: selector-map cache TTL in seconds (default:0, disabled).BUSE_REMOTE_ALLOW_ORIGINS: override Chrome--remote-allow-origins(default:http://localhost:<port>,http://127.0.0.1:<port>).BUSE_IMAGE_QUALITY: JPEG quality (1-100) for OmniParser images.
References & Inspiration
https://blog.google/innovation-and-ai/models-and-research/google-deepmind/gemini-computer-use-model/
https://www.anthropic.com/news/3-5-models-and-computer-use
https://docs.browser-use.com/introduction
Roadmap
- Support all operating systems: Windows, macOS, Linux (right now works on my 10.15 macOS and Windows 11)
- Add automation scripting examples
- Add MCP support
- Add optional daemon for persistent background sessions
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file buse-0.3.1.tar.gz.
File metadata
- Download URL: buse-0.3.1.tar.gz
- Upload date:
- Size: 234.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ac08f8cc00c8ae478e6881290cc5d15f78323eb72b4bafbf96afb9986a84f5c
|
|
| MD5 |
c43b4eb86a613f2f5a1c750f90bbd266
|
|
| BLAKE2b-256 |
fa64e8c085557849f780d5cec2292f90735d02df4c519820e648027df08ec738
|
Provenance
The following attestation bundles were made for buse-0.3.1.tar.gz:
Publisher:
release.yml on rinvii/buse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
buse-0.3.1.tar.gz -
Subject digest:
5ac08f8cc00c8ae478e6881290cc5d15f78323eb72b4bafbf96afb9986a84f5c - Sigstore transparency entry: 814176068
- Sigstore integration time:
-
Permalink:
rinvii/buse@ffbda705fe071cd4440d279c23c740028692bfbf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/rinvii
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ffbda705fe071cd4440d279c23c740028692bfbf -
Trigger Event:
push
-
Statement type:
File details
Details for the file buse-0.3.1-py3-none-any.whl.
File metadata
- Download URL: buse-0.3.1-py3-none-any.whl
- Upload date:
- Size: 28.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c33c5f4252043af4f17f96f0328970dc647ad9c6736d8865fabd9810cace077b
|
|
| MD5 |
afe8d1b5755d8d6ec7b3c0207e64daa9
|
|
| BLAKE2b-256 |
23a028a89a5be51a93cc5d6577c87e5e98986846301971f3439dfe5167a3e524
|
Provenance
The following attestation bundles were made for buse-0.3.1-py3-none-any.whl:
Publisher:
release.yml on rinvii/buse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
buse-0.3.1-py3-none-any.whl -
Subject digest:
c33c5f4252043af4f17f96f0328970dc647ad9c6736d8865fabd9810cace077b - Sigstore transparency entry: 814176073
- Sigstore integration time:
-
Permalink:
rinvii/buse@ffbda705fe071cd4440d279c23c740028692bfbf -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/rinvii
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ffbda705fe071cd4440d279c23c740028692bfbf -
Trigger Event:
push
-
Statement type: