The profile-use install script fetches the latest version from GitHub API,
which is rate-limited to 60 req/hour for unauthenticated requests. CI
runners share IPs and exhaust this limit. Pin to v1.0.2 to skip the API
call. Users can update later via browser-use profile update.
--profile now accepts both directory names ("Default", "Profile 1") and
display names ("Person 1", "Work") with case-insensitive matching. On
unknown profile, lists all available profiles with both names.
On Windows, os.kill(pid, 0) calls TerminateProcess which kills the process
instead of checking liveness. Use ctypes OpenProcess for Windows, keeping
os.kill(pid, 0) for Unix. Affects list_sessions(), tunnel PID checks, and
_handle_sessions().
- Pass INSTALL_DIR to sh instead of curl so profile-use installs to
the correct location (~/.browser-use/bin/)
- Replace macOS-specific 'brew install cloudflared' with generic link
- Narrow cloud --help intercept to only fire when --help is immediately
after 'cloud', so 'cloud v2 --help' still shows OpenAPI endpoints
- Guard signal handler against concurrent shutdown tasks on repeated signals
- Route error response bodies to stderr in cloud REST commands
- Replace stale port 49200 in README Windows troubleshooting
await the shutdown task in run() so browser cleanup (kill/stop) completes
before the event loop tears down. Previously, asyncio.run() could cancel
the shutdown mid-cleanup, leaving Chrome processes orphaned.
- Intercept `cloud --help` early so it routes to _print_cloud_usage()
instead of argparse's generic stub
- Remove permissive `or 'cloud'` fallback in epilog test assertion
- Delete no-op regex test that didn't verify actual code
- Tighten default socket path assertion to check 'default.sock'
- Document coordinate clicking (click <x> <y>) in all interaction sections
- Annotate extract command as not yet implemented in README and SKILL.md
- Remove browser.extract() from Python wrapper docs (raises NotImplementedError)
- Add --session flag to global options tables in both SKILL.md files
Wrap socket creation + connect in try/finally across 5 locations to
ensure sockets are closed when connect() raises. Previously, failed
connections leaked file descriptors until GC ran.
- Add `browser-use upload <index> <path>` command for uploading files to
file input elements via the CLI
- Extract find_file_input_near_element from nested closures in tools/service.py
to a reusable method on BrowserSession, deduplicating two copies
- Add BrowserWrapper.upload() for the Python REPL
- Resolve file paths to absolute on the client side before sending to daemon
- Update SKILL.md files and README with upload command docs
Document profile subcommand as passthrough to profile-use Go binary,
add file layout section showing ~/.browser-use/ structure, update
authenticated browsing workflow examples for new profile list output.
Use nargs=REMAINDER to capture profile-use args, matching the cloud
subcommand pattern. Without this, argparse rejects unknown args like
'browser-use profile update'.
Unify all CLI-managed files under ~/.browser-use/ (config, sockets, PIDs,
binaries, tunnels) instead of scattering across ~/.config/browser-use/ and
~/.browser-use/run/. Add profile-use Go binary as managed subcommand via
browser-use profile, with auto-download fallback and install.sh integration.
Wire cloudflared and profile-use availability checks into browser-use doctor.
Adds `--connect` to auto-discover running Chrome instances via DevToolsActivePort
files and well-known port probing, eliminating manual CDP URL construction. Fixes
daemon process hanging on `close` when connected to external browsers (--connect,
--cdp-url, cloud) by calling stop() (disconnect) instead of kill() (terminate).
The `run` command pulled in heavy SDK dependencies (openai, anthropic,
google), had a bug (await on sync get_llm), and is superseded by
`browser-use cloud` for agent execution. CLI is now purely a browser
automation interface.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Login/logout with API key persistence, versioned REST calls (v2/v3),
task polling, and OpenAPI-driven help. Stdlib only, no daemon needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the multi-session server (server.py, SessionRegistry, portalocker locking,
PID files, orphan detection) with a minimal daemon (daemon.py) that holds one
BrowserSession in memory. Socket file existence = alive. Auto-exits when browser
dies via CDP watchdog.
-2277 lines, +142 lines across 20 files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all cloud API paths from the CLI while leaving core library
cloud support (BrowserSession(use_cloud=True), browser/cloud/) untouched.
Deleted: api_key.py, cloud_task.py, cloud_session.py
Removed: --browser remote, cloud-only run flags, task/session subcommands,
cloud profile ops (create/update/delete/sync), remote mode validation
Kept: tunnel (just Cloudflare), all local commands, install_config.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changes install.sh to clone from github.com/browser-use/browser-use@main
by default instead of installing from PyPI. Custom branches and repos
can still be specified via BROWSER_USE_BRANCH and BROWSER_USE_REPO
environment variables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously only suggested --full, but --remote-only is a lighter-weight
option when users only need cloud browser support.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The session server had a race condition where concurrent CLI calls could
spawn multiple server processes. The old server would be orphaned when
the new one overwrote the PID file and deleted its socket.
Changes:
- Add flock-based locking using portalocker (already a dependency)
- Server acquires exclusive lock before writing PID file
- CLI checks both is_server_running() AND is_session_locked()
- Add kill_orphaned_server() to clean up servers with PID but no lock
- Increase socket timeout from 0.1s to 0.5s for reliability
- cleanup_session_files() now removes .lock and .meta files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename tunnel_manager.py to tunnel.py
- Remove dead code: commands/tunnel.py (session-scoped implementation never reached)
- Remove TunnelInfo dataclass and tunnels field from sessions.py
- Remove tunnel routing from server.py (unreachable code path)
- Update imports in main.py, doctor.py, setup.py, and tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all references from browser-use.com/install.sh to
browser-use.com/cli/install.sh across documentation and code.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reverts changes to browser_use/llm/browser_use/chat.py to keep
CLI changes isolated. Browser-use models are now hardcoded in
agent.py instead of importing from chat.py.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Forward all cloud-only flags in _handle_remote_run_with_wait
Previously only forwarded 6 params; now includes session_id, vision,
metadata, secrets, allowed_domains, skill_ids, structured_output,
judge, judge_ground_truth, plus session creation for profile/proxy
- Use asyncio.to_thread for blocking SDK call in poll_until_complete
Prevents client.tasks.get_task from blocking the event loop while
polling for task completion
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use asyncio.to_thread() for poll_until_complete to prevent time.sleep()
from blocking the async event loop when --wait is used.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace custom HTTP client with browser-use-sdk for tasks and sessions,
completing the SDK migration started in 8a992229.
## SDK Migration
- Add `sdk.py` with singleton client factory (`get_sdk_client()`)
- Rewrite `cloud_task.py` to use SDK (-300 lines)
- All functions return typed SDK models (TaskView, SessionView, etc.)
- Add `_filter_none()` to omit None values (SDK sends null, API rejects)
## No Client-Side Defaults
- Remove hardcoded defaults from CLI (max_steps, proxy_country, etc.)
- Let API use its own defaults (documented at docs.cloud.browser-use.com)
- Only pass values user explicitly sets
## New CLI Features
- `session create` - create session without task
- `session share <id>` - create/delete public share URLs
- `task list --session <id>` - filter tasks by session
- New task flags: --metadata, --secret, --allowed-domain, --skill-id,
--structured-output, --judge, --judge-ground-truth, --start-url
## Async by Default
- Change `--no-wait` to `--wait` (flip default behavior)
- Tasks return immediately with task_id by default
- Use `--wait` to block until completion
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace raw urllib HTTP calls with the official browser-use-sdk client
for all cloud profile API operations. This provides:
- Type-safe responses (ProfileView, ProfileListResponse)
- Cleaner error handling via SDK exceptions
- Consistent SDK usage pattern (matches skills/service.py)
- Removes 40 lines of manual HTTP/auth handling from main.py
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move prerequisites before install commands (no longer hidden)
- Add Windows troubleshooting section with common issues
- Minor wording improvements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>