Install
openclaw skills install bsessionBrowser automation — setup the bsession environment, fetch info from a website (one-shot), create scripted automations (one-shot or recurring), or debug existing sessions. Works from any repo.
openclaw skills install bsessionYou help users automate browsers inside the bsession Docker container — whether it's initial setup, a quick interactive fetch, a scripted automation (one-shot or recurring), or debugging an existing session.
This is a global skill — it works from any repo. bsession is installed at ~/.bsession/, and the bsession CLI is on PATH.
Before doing anything, determine how to reach bsession. Check in this order:
bsession on PATH → use bsession~/.bsession/bsession exists → use ~/.bsession/bsession./bsession in current directory → use ./bsessiondocker exec agent-browser echo ok) → use docker exec agent-browser python3 /app/session.py as the CLISimilarly, resolve workspace:
~/.bsession/workspace/ exists → use it./workspace/ in current directory → use itdocker exec agent-browser ls /workspace/conf → use docker exec to access filesUse these resolved paths for all commands throughout the session.
~/.bsession/ — where bsession source + docker-compose live~/.bsession/workspace/ (default, overridable) — or resolved per aboveParse the user's slash command arguments:
list → List mode (show all available scripts and sessions)setup → Setup mode (install and configure bsession)fetch <url> → Fetch mode (interactive one-shot extraction, with option to persist)new <name> → Create mode (scaffold a script — one-shot or recurring)run <name> → Run mode (execute a saved session and show results)Before running any mode except setup, verify the container is running:
docker exec agent-browser echo ok 2>/dev/null
If this fails, tell the user to either:
/browser setup for a fresh install, ordocker compose up -d from the bsession project directory/browser or /browser list)Show all available scripts, their status, and what they do.
bsession list
For each .py file in ~/.bsession/workspace/scripts/, read the module docstring (the triple-quoted string at the top of the file).
For each .conf file in ~/.bsession/workspace/conf/, read the [env] section to show current configuration.
Display a summary like:
Session Status Type Description
─────────────────────────────────────────────────────────────────
uscis running recurring USCIS case status monitor
price-check stopped one-shot Amazon product price scraper
Available commands:
/browser <name> debug a session
/browser new <name> create a new automation
/browser fetch <url> quick one-shot fetch
/browser setup)Run the install script:
bash ~/.openclaw/workspace/skills/browser/scripts/install.sh
Or with options:
bash ~/.openclaw/workspace/skills/browser/scripts/install.sh --workspace /path/to/workspace
bash ~/.openclaw/workspace/skills/browser/scripts/install.sh --vnc-password secret
bash ~/.openclaw/workspace/skills/browser/scripts/install.sh --repo https://github.com/gaxxx/bsession.git
Ask the user for custom options before running. The script handles Docker check, uv/Python install, image build, container start, and CLI setup.
/browser fetch <url>)One-shot: open a URL, extract information, return it. No script, no conf file, no loop.
docker exec agent-browser python3 -c "
import urllib.request
try:
urllib.request.urlopen('http://localhost:9222/json/version', timeout=2)
print('IN_USE')
except:
print('FREE')
"
If 9222 is in use, try 9223, 9224, etc. Start a temporary Chrome on a free port:
docker exec agent-browser python3 -c "
import sys; sys.path.insert(0, '/app')
from lib.browser import start_chrome
pid = start_chrome(PORT, '/workspace/data/profile-tmp')
print(f'Chrome started, pid={pid}')
"
docker exec agent-browser agent-browser --cdp PORT open "URL"
sleep 5
docker exec agent-browser agent-browser --cdp PORT snapshot
Handle Cloudflare if detected:
docker exec agent-browser python3 -c "
import sys; sys.path.insert(0, '/app')
from lib.browser import ab, is_cloudflare, wait_for_cloudflare
snap = ab(PORT, 'snapshot')
if is_cloudflare(snap):
wait_for_cloudflare(PORT, snap)
snap = ab(PORT, 'snapshot')
print(snap)
"
docker exec agent-browser agent-browser --cdp PORT fill REF "value"
docker exec agent-browser agent-browser --cdp PORT click REF
docker exec agent-browser agent-browser --cdp PORT snapshot
Parse the relevant information and present it cleanly.
After returning results, always ask if the user wants to save as a reusable script. If yes, create a one-shot script + conf in ~/.bsession/workspace/.
docker exec agent-browser python3 -c "
import sys; sys.path.insert(0, '/app')
from lib.browser import stop_chrome
stop_chrome(PORT)
"
/browser new <name>)Ask the user:
Then scaffold ~/.bsession/workspace/conf/<name>.conf and ~/.bsession/workspace/scripts/<name>.py following the conventions in the reference section below.
/browser run <name>)bsession show <name>bsession run <name>bsession logs <name> -n 50/browser <session-id>)bsession list, bsession show <id>, read logs and scriptbsession restart <id>Imports:
import os, re, sys, time
sys.path.insert(0, "/app")
from lib.browser import (
ab, ab_quiet, find_ref, is_cloudflare, wait_for_cloudflare,
send_webhook, make_logger,
)
Config from env vars:
port = int(os.environ.get("CDP_PORT", 9222))
session_name = os.environ.get("SESSION_NAME", "<name>")
webhook_url = os.environ.get("N8N_WEBHOOK_URL", "")
check_interval = int(os.environ.get("CHECK_INTERVAL", 1800))
Core pattern: open URL → wait → snapshot → handle Cloudflare → find elements → interact → parse results
One-shot: execute and exit. Recurring: wrap in while True with sleep, compare state, webhook on change.
ab(port, cmd, *args) / ab_quiet(port, cmd, *args) — run agent-browser commandsfind_ref(snapshot, pattern) / find_all_refs(snapshot, pattern) — parse accessibility treeis_cloudflare(snapshot) / wait_for_cloudflare(port, snapshot, ...) — Cloudflare handlingsend_webhook(url, payload) — POST JSON to webhookmake_logger(session_name) — create timestamped logger