Metadata-Version: 2.4
Name: keres-playwright
Version: 0.1.0
Summary: Playwright-compatible automation client for Keres Browser. Connects to the local Keres Automation Gateway; Keres owns profiles, sessions, and the browser runtime.
License: MIT
Keywords: keres,playwright,automation,browser
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: websockets<16,>=12
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"

# keres-playwright

Playwright-compatible automation client for [Keres Browser](https://keres.browser).
Connects to the local Keres Automation Gateway; Keres owns profiles, sessions,
and the browser runtime (Chromium, Gecko, Camoufox).

> Keres is a web browser, profile manager, and automation platform. This client
> drives browsers through a governed local API — it makes no claims about
> bypassing third-party systems.

## Install

Until the package is published to PyPI (tracked in Stage 17), install from the
repository checkout:

```bash
pip install -e path/to/keres/compatibility/python
```

Requires Python 3.10+ and the Keres desktop app running locally.

## Quickstart

```python
from keres_playwright import keres

browser = keres.connect({"profile": "sales-profile"})
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
page.get_by_role("button", name="Sign in").click()
browser.close()  # disconnects; the profile stays alive in Keres
```

Async flavor:

```python
import asyncio
from keres_playwright.async_api import keres

async def main():
    browser = await keres.connect({"profile": "sales-profile"})
    page = await browser.new_page()
    await page.goto("https://example.com")
    print(await page.title())
    await browser.close()

asyncio.run(main())
```

## Concepts

- **Profile ≠ Context.** A `Browser` maps onto one Keres session bound to the
  profile chosen at connect time. Persistent identity (cookies, storage,
  network configuration) lives with the Keres profile — not with this handle.
- **`close()` is disconnect-only.** Sessions and profiles remain managed by
  Keres after the client disconnects.
- **Explicit profiles.** `connect` requires `{"profile": ...}`; desktop-user
  sessions are never adopted silently.
- **Auto-waiting is server-side**, delegated to the Keres Automation API wait
  engine. The client builds no second waiting implementation.

## Errors

Error names follow Playwright conventions (`TimeoutError`, ...) while every
error carries the original structured Keres code:

```python
from keres_playwright import TimeoutError, KeresError

try:
    page.goto("https://example.com", timeout_ms=5000)
except TimeoutError as exc:
    print(exc.code)  # e.g. NAVIGATION_TIMEOUT
```

## Endpoint and token resolution

1. Explicit options: `connect({"endpoint": ..., "token": ...})`
2. Environment: `KERES_GATEWAY_ENDPOINT`, `KERES_GATEWAY_TOKEN`
3. Discovery file published by the running app:
   `%APPDATA%\com.keres.browser\gateway\endpoint.json` (Windows),
   `~/Library/Application Support/com.keres.browser/gateway/endpoint.json`
   (macOS), `$XDG_CONFIG_HOME/com.keres.browser/gateway/endpoint.json`
   (Linux). Reveal the token in Keres Settings → Developer automation.

The token is sent as the first WebSocket frame — never placed in URLs or logs.

## Capability matrix

Engine support per operation is documented in
[`api/PLAYWRIGHT_API.md`](../../api/PLAYWRIGHT_API.md); unsupported operations
raise `UnsupportedCapabilityError` naming the engine.

## License

MIT
