Metadata-Version: 2.4
Name: browser-use-headless
Version: 0.1.4
Summary: The simplest, thinnest, and most powerful harness to control your real browser with your agent.
License-Expression: MIT
Project-URL: Homepage, https://github.com/browser-use-headless/browser-use-headless
Project-URL: Repository, https://github.com/browser-use-headless/browser-use-headless
Project-URL: Issues, https://github.com/browser-use-headless/browser-use-headless
Keywords: agent,automation,browser,cdp,chrome,scraping
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: cdp-use==1.4.5
Requires-Dist: fetch-use==0.4.0
Requires-Dist: pillow==12.2.0
Requires-Dist: requests>=2.32.0
Requires-Dist: websockets==15.0.1
Dynamic: license-file

# browser-harness-headless

The simplest, thinnest, and most powerful harness to control headless Chrome/Chromium with your agent — no display server needed.

A headless adaptation of [browser-harness](https://github.com/browser-use/browser-harness) that auto-launches and manages a headless Chrome instance. Perfect for CI pipelines, servers, containers, and any environment without a GUI.

## Quick Start

```bash
pip install -e .
```

```bash
browser-harness-headless <<'EOF'
new_tab("https://example.com")
print(page_info()["title"])
capture_screenshot("page.png")
EOF
```

That's it. No Chrome setup, no display, no config. The harness launches headless Chrome automatically on first use.

## How It Works

```
┌──────────────┐       ┌────────────┐       ┌─────────────────┐
│  Agent Code  │──IPC──│   Daemon   │──CDP──│ Headless Chrome  │
│  (stdin)     │       │ (Unix sock)│       │ (--headless=new) │
└──────────────┘       └────────────┘       └─────────────────┘
```

1. **CLI** (`browser-harness-headless`) reads Python from stdin, ensures daemon is running
2. **Daemon** is a long-lived process that holds the CDP WebSocket to Chrome
3. **Headless Chrome** runs with `--headless=new` (modern headless — full rendering, no GUI)

## Usage

### As a CLI tool

```bash
# Run inline code
echo 'new_tab("https://httpbin.org/get"); print(js("document.body.innerText"))' | browser-harness-headless

# Run a script file
browser-harness-headless < my_script.py

# Multi-line heredoc
browser-harness-headless <<'EOF'
new_tab("https://news.ycombinator.com")
wait_for_load()
titles = js("""
    Array.from(document.querySelectorAll('.titleline a'))
        .slice(0, 5)
        .map(a => a.textContent)
""")
print(titles)
EOF
```

### Management Commands

```bash
browser-harness-headless --doctor    # Diagnostics
browser-harness-headless --status    # JSON status
browser-harness-headless --restart   # Restart daemon + Chrome
browser-harness-headless --stop      # Stop everything
```

## Configuration

| Env Var | Description |
|---------|-------------|
| `BHH_CHROME_PATH` | Path to Chrome/Chromium binary |
| `BHH_CDP_WS` | Connect to existing CDP WebSocket instead of launching Chrome |
| `BHH_HOME` | Config/runtime directory (default: `~/.config/browser-harness-headless`) |
| `BHH_DOMAIN_SKILLS` | Enable domain-specific skills (`1` to enable) |

## Helpers

All helpers are pre-imported when code runs via the CLI:

| Helper | Description |
|--------|-------------|
| `new_tab(url)` | Open a new tab and navigate |
| `goto_url(url)` | Navigate current tab |
| `page_info()` | Get URL, title, viewport size, scroll position |
| `click_at_xy(x, y)` | Click at viewport coordinates |
| `type_text(text)` | Insert text at cursor |
| `fill_input(selector, text)` | Framework-aware form filling (React/Vue/Ember) |
| `press_key(key, modifiers)` | Simulate key press |
| `scroll(x, y, dx, dy)` | Mouse wheel scroll |
| `capture_screenshot(path, full_page)` | Take PNG screenshot |
| `list_tabs()` / `switch_tab()` / `close_tab()` | Tab management |
| `js(expression)` | Execute JavaScript, return result |
| `wait_for_load()` | Wait for page load |
| `wait_for_element(selector)` | Wait for DOM element |
| `wait_for_network_idle()` | Wait for network quiet |
| `upload_file(selector, path)` | Upload file to input |
| `http_get(url)` | HTTP GET via page's fetch |
| `cdp(method, **params)` | Raw Chrome DevTools Protocol |

## Architecture

```
src/browser_harness_headless/
├── __init__.py      # Package init
├── run.py           # CLI entry point
├── admin.py         # Chrome launch, daemon lifecycle
├── daemon.py        # CDP WebSocket owner, IPC server
├── helpers.py       # Agent-facing API (navigation, input, screenshots, etc.)
├── _ipc.py          # Unix socket / TCP IPC layer
└── paths.py         # Filesystem layout
```

## Key Differences from browser-harness

| Feature | browser-harness | browser-harness-headless |
|---------|----------------|--------------------------|
| Browser | Uses your running Chrome | Auto-launches headless Chrome |
| Display | Requires GUI/display | No display needed |
| Setup | Enable remote debugging manually | Zero setup |
| Cloud | Browser Use cloud support | Local-only (or bring your own CDP) |
| Auth | OAuth for cloud | None needed |
| Dependencies | cdp-use, fetch-use | websockets, pillow only |

## Requirements

- Python 3.11+
- Chrome or Chromium installed (or set `BHH_CHROME_PATH`)
- No display server needed

## License

MIT
