{"id":48255361,"url":"https://github.com/bitsky-tech/bridgic-browser","last_synced_at":"2026-04-15T14:01:08.073Z","repository":{"id":346739803,"uuid":"1148653206","full_name":"bitsky-tech/bridgic-browser","owner":"bitsky-tech","description":"LLM-driven browser automation library built on Playwright with 67 CLI/SDK tools, stable snapshot refs, and stealth mode.基于 Playwright 的 LLM 驱动浏览器自动化库，提供 67 个 CLI/SDK 工具、稳定快照引用（ref）与默认隐身模式，适用于 AI Agent 端到端网页操作。","archived":false,"fork":false,"pushed_at":"2026-04-13T12:05:47.000Z","size":11850,"stargazers_count":43,"open_issues_count":2,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-13T14:07:41.748Z","etag":null,"topics":["agent-tools","ai-agent","browser-automation","cli","llm","playwright","python"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/bridgic-browser/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitsky-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-03T07:58:01.000Z","updated_at":"2026-04-13T04:31:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bitsky-tech/bridgic-browser","commit_stats":null,"previous_names":["bitsky-tech/bridgic-browser"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/bitsky-tech/bridgic-browser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsky-tech%2Fbridgic-browser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsky-tech%2Fbridgic-browser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsky-tech%2Fbridgic-browser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsky-tech%2Fbridgic-browser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitsky-tech","download_url":"https://codeload.github.com/bitsky-tech/bridgic-browser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsky-tech%2Fbridgic-browser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31844329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T13:28:40.153Z","status":"ssl_error","status_checked_at":"2026-04-15T13:28:29.396Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-tools","ai-agent","browser-automation","cli","llm","playwright","python"],"created_at":"2026-04-04T21:09:19.308Z","updated_at":"2026-04-15T14:01:08.066Z","avatar_url":"https://github.com/bitsky-tech.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[English](#bridgic-browser) | [中文](README_zh.md)\n\n---\n\n## Bridgic Browser\n\n**Bridgic Browser** is a Python library for LLM-driven browser automation built on [Playwright](https://playwright.dev/). It includes CLI tools, Python tools and skills for AI agents.\n\n### Features\n\n- **Comprehensive CLI Tools** - 67 tools organized into 15 categories; Designed to integrate with any AI agent\n- **Python-based Tools** - Used for agent / workflow code generation; Easier integration with [Bridgic](https://github.com/bitsky-tech/bridgic) \n- **Snapshot with Semantic Invariance** - A representation of page snapshot based on accessibility tree and a specially designed ref-generation algorithm that ensures element refs remain unchanged across page reloads\n- **Skills** - Used for guided exploration and code generation; Compatible with most of coding agents\n- **Stealth Mode (Enabled by Default)** - Mode-aware anti-detection: 50+ Chrome args + JS patches in headless mode; minimal ~11 flags in headed mode to match real Chrome fingerprint\n- **Persistent \u0026 Ephemeral Sessions** - Persistent profile by default (`~/.bridgic/bridgic-browser/user_data/`); pass `clear_user_data=True` for an ephemeral session with no profile\n- **Nested iframe Support** - Supports DOM element operations within multi-level nested iframes\n\n### Quick Start\n\n#### Integration with AI\n\nThe easiest way to use **Bridgic Browser** is with a coding agent or AI assistant (such as Claude Code, Cursor, Codex, or OpenClaw). You can use it in two ways: via a Skill or a Plugin. In both cases, Bridgic Browser is installed automatically.\n\n**Method 1: Use AI to directly control the browser and complete tasks in real time.**\n\n\u003cvideo src=\"https://github.com/user-attachments/assets/7ef9304a-34f1-4c87-8eb9-930f6378f020\" controls\u003e\u003c/video\u003e\n\nTo use this method, install the Skill provided by Bridgic Browser.\n\n```bash\nnpx skills add bitsky-tech/bridgic-browser --skill bridgic-browser\n```\n\nAfter installation, the Skill will appear in your agent directories (for example, Claude Code typically under `.claude/skills/bridgic-browser/`, and Cursor under `.agents/skills/bridgic-browser/`).\n\n**Method 2: Let AI generate repeatable browser automation scripts with minimal token usage.**\n\nTo use this method, install the **Plugin** provided by [AmphiLoop](https://github.com/bitsky-tech/AmphiLoop), a brand new methodology, tech stack and toolchain for building AI agents with natural language.\n\n#### Manual Installation\n\n```bash\npip install bridgic-browser\n```\n\nAfter installation, install Playwright browsers:\n\n```bash\nplaywright install chromium\n```\n\n#### CLI Tools Usage\n\n```shell\nbridgic-browser open --headed https://example.com\nbridgic-browser snapshot\n# 'f0201d1c' is the ref value of the 'Learn more' link\nbridgic-browser click f0201d1c\nbridgic-browser screenshot page.png\nbridgic-browser close\n```\n\n#### Python Tools Integration\n\nFirst, build tools:\n\n```python\nfrom bridgic.browser.session import Browser\nfrom bridgic.browser.tools import BrowserToolSetBuilder, ToolCategory\n\n# create a browser instance\nbrowser = Browser(headless=False)\n\nasync def create_tools(browser):\n    # Build a focused tool set for your agent\n    builder = BrowserToolSetBuilder.for_categories(\n        browser,\n        ToolCategory.NAVIGATION,\n        ToolCategory.SNAPSHOT,\n        ToolCategory.ELEMENT_INTERACTION,\n        ToolCategory.CAPTURE,\n        ToolCategory.WAIT,\n    )\n    tools = builder.build()[\"tool_specs\"]\n    return tools\n```\n\nSecond (optional), build a [Bridgic](https://github.com/bitsky-tech/bridgic) agent that uses this tool set:\n\n```python\nimport os\nfrom bridgic.llms.openai import OpenAILlm, OpenAIConfiguration\nasync def create_llm():\n    _api_key = os.environ.get(\"OPENAI_API_KEY\")\n    _model_name = os.environ.get(\"OPENAI_MODEL_NAME\")\n\n    llm = OpenAILlm(\n        api_key=_api_key,\n        configuration=OpenAIConfiguration(model=_model_name),\n        timeout=60,\n    )\n    return llm\n\nfrom bridgic.core.agentic.recent import ReCentAutoma, StopCondition\nfrom bridgic.core.automa import RunningOptions\nasync def create_agent(llm, tools):\n    browser_agent = ReCentAutoma(\n        llm=llm,\n        tools=tools,\n        stop_condition=StopCondition(max_iteration=10, max_consecutive_no_tool_selected=1),\n        running_options=RunningOptions(debug=True),\n    )\n    return browser_agent\n\nasync def main():\n    tools = await create_tools(browser)\n    llm = await create_llm()\n    agent = await create_agent(llm, tools)\n    result = await agent.arun(\n        goal=(\n            \"Summarize the 'Learn more' page of example.com for me\"\n        ),\n        guidance=(\n            \"Do the following steps one by one:\\n\"\n            \"1. Navigate to https://example.com\\n\"\n            \"2. Click the 'Learn more' link\\n\"\n            \"3. Take a screenshot of the 'Learn more' page\\n\"\n            \"4. Summarize the page content in one sentence and tell me how to access the screenshot.\\n\"\n        ),\n    )\n    print(\"\\n\\n*** Final Result: ***\\n\\n\")\n    print(result)\n\n    await browser.close()\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(main())\n```\n\n#### Browser API Usage\n\nYou can also directly call the underlying `Browser` API to control the browser.\n\n```python\nfrom bridgic.browser.session import Browser\n\nbrowser = Browser(headless=False)\n\nasync def main():\n    await browser.navigate_to(\"https://example.com\")\n    snapshot = await browser.get_snapshot()\n    print(snapshot.tree)  # Tree format: - role \"name\" [ref=f0201d1c]\n    for ref, data in snapshot.refs.items():\n        if data.name == \"Learn more\":\n            learn_more_ref = ref\n            break\n    print(f\"Found ref for 'Learn more': {learn_more_ref}\")\n    await browser.click_element_by_ref(learn_more_ref)\n    await browser.take_screenshot(filename=\"page.png\")\n    await browser.close()\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(main())\n```\n\n### CLI Tools\n\n`bridgic-browser` ships with a command-line interface for controlling a browser from the terminal (67 tools organized into 15 categories). A persistent daemon process holds a browser instance; each CLI invocation connects over a Unix domain socket and exits immediately.\n\n#### Configuration\n\nBrowser options are automatically loaded from the following sources (both CLI daemon and SDK `Browser()`), in priority order (highest last wins):\n\n| Source | Example |\n|--------|---------|\n| Defaults | `headless=True`, `clear_user_data=False` (persistent profile) |\n| `~/.bridgic/bridgic-browser/bridgic-browser.json` | User-level persistent config |\n| `./bridgic-browser.json` | Project-local config (in cwd at daemon start) |\n| Environment variables | See `skills/bridgic-browser/references/env-vars.md` |\n\n**Headed browser note:**\nWhen `headless=false` and stealth is enabled, bridgic auto-switches to system Chrome\n(if installed) for better anti-detection (Chrome for Testing is blocked by Google OAuth).\nTo override, set:\n- `channel`: e.g. `”chrome”`, `”msedge”`\n- `executable_path`: absolute path to a browser binary\n\nThe JSON sources accept any `Browser` constructor parameter:\n\n```json\n{\n  \"headless\": false,\n  \"proxy\": {\"server\": \"http://proxy:8080\", \"username\": \"u\", \"password\": \"p\"},\n  \"viewport\": {\"width\": 1280, \"height\": 720},\n  \"locale\": \"zh-CN\",\n  \"timezone_id\": \"Asia/Shanghai\"\n}\n```\n\n```bash\n# One-shot env override\nBRIDGIC_BROWSER_JSON='{\"headless\":false,\"locale\":\"zh-CN\"}' bridgic-browser open URL\n# One-shot ephemeral session (no persistent profile)\nBRIDGIC_BROWSER_JSON='{\"clear_user_data\":true}' bridgic-browser open URL\n```\n\n#### Command List\n\n| Category | Commands |\n|----------|----------|\n| Navigation | `open`, `back`, `forward`, `reload`, `search`, `info` |\n| Snapshot | `snapshot [-i] [-f\\|-F] [-l N] [-s FILE]` |\n| Element Interaction | `click`, `double-click`, `hover`, `focus`, `fill`, `select`, `options`, `check`, `uncheck`, `scroll-to`, `drag`, `upload`, `fill-form` |\n| Keyboard | `press`, `type`, `key-down`, `key-up` |\n| Mouse | `scroll`, `mouse-move`, `mouse-click`, `mouse-drag`, `mouse-down`, `mouse-up` |\n| Wait | `wait [SECONDS] [TEXT] [--gone]` |\n| Tabs | `tabs`, `new-tab`, `switch-tab`, `close-tab` |\n| Evaluate | `eval`, `eval-on` |\n| Capture | `screenshot`, `pdf` |\n| Network | `network-start`, `network-stop`, `network`, `wait-network` |\n| Dialog | `dialog-setup`, `dialog`, `dialog-remove` |\n| Storage | `storage-save`, `storage-load`, `cookies-clear`, `cookies`, `cookie-set` |\n| Verify | `verify-visible`, `verify-text`, `verify-value`, `verify-state`, `verify-url`, `verify-title` |\n| Developer | `console-start`, `console-stop`, `console`, `trace-start`, `trace-stop`, `trace-chunk`, `video-start`, `video-stop` |\n| Lifecycle | `close`, `resize` |\n\nUse `-h` or `--help` on any command for details:\n\n```bash\nbridgic-browser -h\nbridgic-browser scroll -h\n```\n\n### Python Tools\n\nBridgic Browser provides 67 tools organized into 15 categories. Use `BrowserToolSetBuilder` with category/name selection for scenario-focused tool sets.\n\n#### Category-based Selection\n\n```python\nfrom bridgic.browser.tools import BrowserToolSetBuilder, ToolCategory\n\n# Focused set for your specific agent flows\nbuilder = BrowserToolSetBuilder.for_categories(\n    browser,\n    ToolCategory.NAVIGATION,\n    ToolCategory.ELEMENT_INTERACTION,\n    ToolCategory.CAPTURE,\n)\ntools = builder.build()[\"tool_specs\"]\n\n# Include all available tools\nbuilder = BrowserToolSetBuilder.for_categories(browser, ToolCategory.ALL)\ntools = builder.build()[\"tool_specs\"]\n```\n\n#### Name-based Selection (by function name)\n\n```python\n# Select by tool function names\nbuilder = BrowserToolSetBuilder.for_tool_names(\n    browser,\n    \"search\",\n    \"navigate_to\",\n    \"click_element_by_ref\",\n)\ntools = builder.build()[\"tool_specs\"]\n\n# Enable strict mode to catch typos and missing browser methods early\nbuilder = BrowserToolSetBuilder.for_tool_names(\n    browser,\n    \"search\",\n    \"navigate_to\",\n    strict=True,\n)\ntools = builder.build()[\"tool_specs\"]\n```\n\n#### Mixed Selection\n\n```python\nbuilder1 = BrowserToolSetBuilder.for_categories(\n    browser,\n    ToolCategory.NAVIGATION,\n    ToolCategory.ELEMENT_INTERACTION,\n    ToolCategory.CAPTURE,\n)\nbuilder2 = BrowserToolSetBuilder.for_tool_names(\n    browser, \"verify_url\", \"verify_title\"\n)\ntools = [*builder1.build()[\"tool_specs\"], *builder2.build()[\"tool_specs\"]]\n```\n\n#### Tool List\n\n**Navigation (6 tools):**\n- `navigate_to(url)` - Navigate to URL\n- `search(query, engine)` - Search using search engine\n- `get_current_page_info()` - Get current page info (URL, title, etc.)\n- `reload_page()` - Reload current page\n- `go_back()` / `go_forward()` - Browser history navigation\n\n**Snapshot (1 tool):**\n- `get_snapshot_text(limit=10000, interactive=False, full_page=True, file=None)` - Get page state string for LLM (accessibility tree with refs). **limit** (default 10000) controls the maximum characters returned. When the snapshot exceeds limit or **file** is explicitly provided, full content is saved to **file** (auto-generated under `~/.bridgic/bridgic-browser/snapshot/` if `None` and over limit) and only a notice with the file path is returned. **interactive** and **full_page** match `get_snapshot` (interactive-only or full-page by default).\n\n**Element Interaction (13 tools) - by ref:**\n- `click_element_by_ref(ref)` - Click element\n- `input_text_by_ref(ref, text)` - Input text\n- `fill_form(fields)` - Fill multiple form fields\n- `scroll_element_into_view_by_ref(ref)` - Scroll element into view\n- `select_dropdown_option_by_ref(ref, value)` - Select dropdown option\n- `get_dropdown_options_by_ref(ref)` - Get dropdown options\n- `check_checkbox_or_radio_by_ref(ref)` / `uncheck_checkbox_by_ref(ref)` - Checkbox control\n- `focus_element_by_ref(ref)` - Focus element\n- `hover_element_by_ref(ref)` - Hover over element\n- `double_click_element_by_ref(ref)` - Double click\n- `upload_file_by_ref(ref, path)` - Upload file\n- `drag_element_by_ref(start_ref, end_ref)` - Drag and drop\n\n**Tabs (4 tools):**\n- `get_tabs()` / `new_tab(url)` / `switch_tab(page_id)` / `close_tab(page_id)` - Tab management\n\n**Evaluate (2 tools):**\n- `evaluate_javascript(code)` - Execute JavaScript\n- `evaluate_javascript_on_ref(ref, code)` - Execute JavaScript on element\n\n**Keyboard (4 tools):**\n- `type_text(text)` - Type text character by character (key events, no ref — acts on focused element)\n- `press_key(key)` - Press keyboard shortcut (e.g. `\"Enter\"`, `\"Control+A\"`)\n- `key_down(key)` / `key_up(key)` - Key control\n\n**Mouse (6 tools) - Coordinate-based:**\n- `mouse_wheel(delta_x, delta_y)` - Scroll wheel\n- `mouse_click(x, y)` - Click at position\n- `mouse_move(x, y)` - Move mouse\n- `mouse_drag(start_x, start_y, end_x, end_y)` - Drag operation\n- `mouse_down()` / `mouse_up()` - Mouse button control\n\n**Wait (1 tool):**\n- `wait_for(time_seconds, text, text_gone, selector, state, timeout)` - Wait for conditions\n\n**Capture (2 tools):**\n- `take_screenshot(filename=None, ref=None, full_page=False, type=\"png\")` - Capture screenshot\n- `save_pdf(filename)` - Save page as PDF\n\n**Network (4 tools):**\n- `start_network_capture()` / `stop_network_capture()` / `get_network_requests()` - Network monitoring\n- `wait_for_network_idle()` - Wait for network idle\n\n**Dialog (3 tools):**\n- `setup_dialog_handler(default_action)` - Set up auto dialog handler\n- `handle_dialog(accept, prompt_text)` - Handle dialog\n- `remove_dialog_handler()` - Remove dialog handler\n\n**Storage (5 tools):**\n- `get_cookies()` / `set_cookie()` / `clear_cookies()` - Cookie management (`expires=0` is valid and preserved)\n- `save_storage_state(filename)` / `restore_storage_state(filename)` - Session persistence\n\n**Verify (6 tools):**\n- `verify_text_visible(text)` - Check text visibility\n- `verify_element_visible(role, accessible_name)` - Check element visibility by role and accessible name\n- `verify_url(pattern)` / `verify_title(pattern)` - URL/title verification\n- `verify_element_state(ref, state)` - Check element state\n- `verify_value(ref, value)` - Check element value\n\n**Developer (8 tools):**\n- `start_console_capture()` / `stop_console_capture()` / `get_console_messages()` - Console monitoring\n- `start_tracing()` / `stop_tracing()` / `add_trace_chunk()` - Performance tracing\n- `start_video()` / `stop_video()` - Video recording\n\n**Lifecycle (2 tools):**\n- `close()` - Close browser\n- `browser_resize(width, height)` - Resize viewport\n\n### CLI Tools -\u003e Python Tools Mapping\n\n| CLI command | SDK tool method |\n|---|---|\n| `open` | `navigate_to` |\n| `search` | `search` |\n| `info` | `get_current_page_info` |\n| `reload` | `reload_page` |\n| `back` | `go_back` |\n| `forward` | `go_forward` |\n| `snapshot` | `get_snapshot_text` |\n| `click` | `click_element_by_ref` |\n| `fill` | `input_text_by_ref` |\n| `fill-form` | `fill_form` |\n| `scroll-to` | `scroll_element_into_view_by_ref` |\n| `select` | `select_dropdown_option_by_ref` |\n| `options` | `get_dropdown_options_by_ref` |\n| `check` | `check_checkbox_or_radio_by_ref` |\n| `uncheck` | `uncheck_checkbox_by_ref` |\n| `focus` | `focus_element_by_ref` |\n| `hover` | `hover_element_by_ref` |\n| `double-click` | `double_click_element_by_ref` |\n| `upload` | `upload_file_by_ref` |\n| `drag` | `drag_element_by_ref` |\n| `tabs` | `get_tabs` |\n| `new-tab` | `new_tab` |\n| `switch-tab` | `switch_tab` |\n| `close-tab` | `close_tab` |\n| `eval` | `evaluate_javascript` |\n| `eval-on` | `evaluate_javascript_on_ref` |\n| `press` | `press_key` |\n| `type` | `type_text` |\n| `key-down` | `key_down` |\n| `key-up` | `key_up` |\n| `scroll` | `mouse_wheel` |\n| `mouse-click` | `mouse_click` |\n| `mouse-move` | `mouse_move` |\n| `mouse-drag` | `mouse_drag` |\n| `mouse-down` | `mouse_down` |\n| `mouse-up` | `mouse_up` |\n| `wait` | `wait_for` |\n| `screenshot` | `take_screenshot` |\n| `pdf` | `save_pdf` |\n| `network-start` | `start_network_capture` |\n| `network` | `get_network_requests` |\n| `network-stop` | `stop_network_capture` |\n| `wait-network` | `wait_for_network_idle` |\n| `dialog-setup` | `setup_dialog_handler` |\n| `dialog` | `handle_dialog` |\n| `dialog-remove` | `remove_dialog_handler` |\n| `cookies` | `get_cookies` |\n| `cookie-set` | `set_cookie` |\n| `cookies-clear` | `clear_cookies` |\n| `storage-save` | `save_storage_state` |\n| `storage-load` | `restore_storage_state` |\n| `verify-text` | `verify_text_visible` |\n| `verify-visible` | `verify_element_visible` |\n| `verify-url` | `verify_url` |\n| `verify-title` | `verify_title` |\n| `verify-state` | `verify_element_state` |\n| `verify-value` | `verify_value` |\n| `console-start` | `start_console_capture` |\n| `console` | `get_console_messages` |\n| `console-stop` | `stop_console_capture` |\n| `trace-start` | `start_tracing` |\n| `trace-chunk` | `add_trace_chunk` |\n| `trace-stop` | `stop_tracing` |\n| `video-start` | `start_video` |\n| `video-stop` | `stop_video` |\n| `close` | `close` |\n| `resize` | `browser_resize` |\n\n### Core Components\n\n#### Browser\n\nThe main class for browser automation with automatic launch mode selection:\n\n```python\nfrom bridgic.browser.session import Browser\n\n# Persistent session (default — profile saved to ~/.bridgic/bridgic-browser/user_data/)\nbrowser = Browser(\n    headless=True,\n    viewport={\"width\": 1600, \"height\": 900},\n)\n\n# Persistent session with custom profile path\nbrowser = Browser(\n    headless=False,\n    user_data_dir=\"./user_data\",\n    stealth=True,  # Enabled by default\n)\n\n# Ephemeral session (no persistent profile)\nbrowser = Browser(\n    headless=True,\n    clear_user_data=True,\n)\n```\n\n**Key Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `headless` | bool | True | Run in headless mode |\n| `viewport` | dict | 1600x900 | Browser viewport size |\n| `user_data_dir` | str/Path | None | Custom path for persistent profile (ignored when `clear_user_data=True`) |\n| `clear_user_data` | bool | False | If True, use ephemeral session (no profile); if False, use persistent profile |\n| `stealth` | bool/StealthConfig | True | Stealth mode configuration |\n| `channel` | str | None | Browser channel (chrome, msedge, etc.) |\n| `proxy` | dict | None | Proxy settings |\n| `downloads_path` | str/Path | None | Download directory |\n\n**Snapshot:** Use `get_snapshot(interactive=False, full_page=True)` to get an `EnhancedSnapshot` with `.tree` (accessibility tree string) and `.refs` (ref → locator data). By default `full_page=True` includes all elements regardless of viewport position. Pass `interactive=True` for clickable/editable elements only (flattened output), or `full_page=False` to limit to viewport-only elements. Use `get_element_by_ref(ref)` to get a Playwright Locator from a ref (e.g. \"1f79fe5e\") for click, fill, etc.\n\n#### StealthConfig\n\nConfigure stealth mode for bypassing bot detection:\n\n```python\nfrom bridgic.browser.session import StealthConfig, Browser\n\n# Custom stealth configuration\nconfig = StealthConfig(\n    enabled=True,\n    disable_security=False,\n)\n\nbrowser = Browser(stealth=config, headless=False)\n```\n\n#### DownloadManager\n\nHandle file downloads with proper filename preservation:\n\n```python\n# Pass downloads_path to Browser — it creates and manages the DownloadManager internally\nbrowser = Browser(downloads_path=\"./downloads\", headless=True)\nawait browser.navigate_to(\"https://example.com\")  # lazy start triggers here\n\n# Access downloaded files via the built-in manager\nfor file in browser.download_manager.downloaded_files:\n    print(f\"Downloaded: {file.file_name} ({file.file_size} bytes)\")\n```\n\n### Stealth Mode\n\nStealth mode is **enabled by default** and includes:\n\n- **Headless mode**: 50+ Chrome args + JS init script patching `navigator.webdriver`, `window.chrome`, WebGL, `document.hasFocus()`, `visibilityState`, and more. All patched functions spoof `Function.prototype.toString` to return `[native code]`.\n- **Headed mode**: minimal ~11 flags only (matching real Chrome); JS patches are skipped entirely so third-party challenge iframes (e.g. Cloudflare Turnstile) see unmodified native APIs.\n\n```python\n# Stealth is ON by default\nbrowser = Browser()  # stealth=True\n\n# Disable stealth if needed\nbrowser = Browser(stealth=False)\n\n# Custom stealth settings\nfrom bridgic.browser.session import create_stealth_config\n\nconfig = create_stealth_config(\n    disable_security=True,\n)\nbrowser = Browser(stealth=config)\n```\n\n### Error Model\n\nSDK and CLI share one structured error protocol.\n\n- Base type: `BridgicBrowserError`\n- Stable fields: `code`, `message`, `details`, `retryable`\n- Behavior subclasses:\n  - `InvalidInputError` (invalid arguments/user input)\n  - `StateError` (invalid runtime state, e.g. no active page/session)\n  - `OperationError` (operation execution failures)\n  - `VerificationError` (assertion/verification failures)\n\nWhy keep a small number of behavior subclasses:\n\n- Lets callers catch by behavior when needed (e.g. retry only `StateError`)\n- Encodes default retry semantics close to the failure source\n- Avoids a large, hard-to-maintain class hierarchy while keeping error handling predictable\n\nDaemon protocol is also structured:\n\n- Success: `{\"success\": true, \"result\": \"...\"}`\n- Failure: `{\"success\": false, \"error_code\": \"...\", \"result\": \"...\", \"data\": {...}, \"meta\": {\"retryable\": false}}`\n\nCLI client converts daemon failures into `BridgicBrowserCommandError`, and CLI output keeps machine code visible as `Error[CODE]: ...`.\n\n### Requirements\n\n- Python 3.10+\n- Playwright 1.57+\n- Pydantic 2.11+\n\n### Community\n\nJoin us to share feedback, ask questions, and keep up with what's new:\n\n- 🐦 Twitter / X: [@bridgic](https://x.com/bridgic)\n- 💬 Discord: [Join our server](https://discord.gg/5rQYnTKNCd)\n\n### License\n\nMIT License\n\n## More documentation\n\n- [Browser Tools Guide](docs/BROWSER_TOOLS_GUIDE.md) – Tool selection, ref vs coordinate, wait strategies, patterns.\n- [Snapshot and Page State](docs/SNAPSHOT_AND_STATE.md) – SnapshotOptions, EnhancedSnapshot, get_snapshot_text, get_element_by_ref.\n- [API Summary](docs/API.md) – Session and DownloadManager API reference.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsky-tech%2Fbridgic-browser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitsky-tech%2Fbridgic-browser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsky-tech%2Fbridgic-browser/lists"}