browser-agent-server 1.0.0__tar.gz → 1.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/CHANGELOG.md +17 -0
  2. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/PKG-INFO +1 -1
  3. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/pyproject.toml +1 -1
  4. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/chrome.py +1 -0
  5. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/cli.py +2 -0
  6. browser_agent_server-1.0.2/tests/test_chrome_state_dir.py +48 -0
  7. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/uv.lock +1 -1
  8. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/.github/workflows/ci.yml +0 -0
  9. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/.github/workflows/release.yml +0 -0
  10. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/.gitignore +0 -0
  11. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/AGENTS.md +0 -0
  12. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/LICENSE +0 -0
  13. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/README.md +0 -0
  14. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/docs/api.md +0 -0
  15. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/docs/architecture.md +0 -0
  16. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/docs/deployment.md +0 -0
  17. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/docs/publishing.md +0 -0
  18. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/docs/security.md +0 -0
  19. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/docs/troubleshooting.md +0 -0
  20. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/__init__.py +0 -0
  21. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/data/browser-agent.service +0 -0
  22. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/server.py +0 -0
  23. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/vision_agent.py +0 -0
  24. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/src/browser_agent/x11_input.py +0 -0
  25. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/tests/test_bezier.py +0 -0
  26. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/tests/test_cli.py +0 -0
  27. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/tests/test_client.py +0 -0
  28. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/tests/test_cloudflare.py +0 -0
  29. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/tests/test_http_api.py +0 -0
  30. {browser_agent_server-1.0.0 → browser_agent_server-1.0.2}/tests/test_ws_frames.py +0 -0
@@ -5,6 +5,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.0.2] - 2026-10-10
9
+
10
+ ### Added
11
+
12
+ - `browser-agent --version` prints the installed package version (the flag was
13
+ missing — noticed while operating the production daemon).
14
+
15
+
16
+ ## [1.0.1] - 2026-10-10
17
+
18
+ ### Fixed
19
+
20
+ - Create the XDG state directory before opening `chrome.err`: a fresh install
21
+ (empty `~/.local/state/browser-agent/`) crashed the very first browser
22
+ launch with `FileNotFoundError`. Found during the production migration onto
23
+ the published package. Regression tests added.
24
+
8
25
  ## [1.0.0] - 2026-10-10
9
26
 
10
27
  Initial public release. Extracted from a private production deployment where
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: browser-agent-server
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: Real headful Chrome on Xvfb with a hardware-level X11 mouse, Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK.
5
5
  Project-URL: Homepage, https://github.com/vernikr/browser-agent
6
6
  Project-URL: Repository, https://github.com/vernikr/browser-agent
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "browser-agent-server"
3
- version = "1.0.0"
3
+ version = "1.0.2"
4
4
  description = "Real headful Chrome on Xvfb with a hardware-level X11 mouse, Cloudflare Turnstile auto-solve and zero-leak CDP. Localhost HTTP API + CLI + Python SDK."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -239,6 +239,7 @@ class RealChromeSession:
239
239
  self._stop_chrome_only()
240
240
 
241
241
  self.user_data_dir.mkdir(parents=True, exist_ok=True)
242
+ self._stderr_path.parent.mkdir(parents=True, exist_ok=True)
242
243
  for lock_name in ("SingletonLock", "SingletonCookie", "SingletonSocket"):
243
244
  lock_path = self.user_data_dir / lock_name
244
245
  if lock_path.exists() or lock_path.is_symlink():
@@ -27,6 +27,7 @@ import urllib.request
27
27
  from importlib import resources
28
28
  from pathlib import Path
29
29
 
30
+ from . import __version__
30
31
  from .chrome import find_chrome_binary, is_warp_proxy_ready
31
32
  from .server import API_VERSION, DEFAULT_HOST, DEFAULT_IDLE_TIMEOUT, DEFAULT_PORT, serve
32
33
 
@@ -264,6 +265,7 @@ def build_parser() -> argparse.ArgumentParser:
264
265
  common.add_argument("--port", type=int, default=DEFAULT_PORT, help="Daemon HTTP port (default: 8765)")
265
266
 
266
267
  parser = argparse.ArgumentParser(prog="browser-agent", description="Real Chrome + X11 Mouse Agent", parents=[common])
268
+ parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
267
269
  sub = parser.add_subparsers(dest="cmd", required=True)
268
270
 
269
271
  p_serve = sub.add_parser("serve", parents=[common], help="Run the localhost HTTP daemon (127.0.0.1:8765)")
@@ -0,0 +1,48 @@
1
+ """Regression: daemon must create the XDG state dir before opening chrome.err.
2
+
3
+ Found on a fresh production install: ChromeManager.start() crashed with
4
+ FileNotFoundError ('~/.local/state/browser-agent/chrome.err') because the state
5
+ directory is only created lazily by other code paths.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import subprocess
11
+
12
+ from browser_agent import chrome as chrome_mod
13
+ from browser_agent.chrome import RealChromeSession
14
+
15
+
16
+ class _FakePopen:
17
+ def __init__(self, args, env=None, stdout=None, stderr=None):
18
+ self.args = args
19
+ self.pid = 4242
20
+ self.returncode = None
21
+
22
+ def poll(self):
23
+ return None # pretend chrome is alive
24
+
25
+
26
+ def test_start_creates_state_dir(monkeypatch, tmp_path):
27
+ state_home = tmp_path / "empty-state"
28
+ monkeypatch.setenv("XDG_STATE_HOME", str(state_home))
29
+ monkeypatch.setenv("HOME", str(tmp_path))
30
+
31
+ mgr = RealChromeSession(cdp_port=9223)
32
+ assert not mgr._stderr_path.parent.exists()
33
+
34
+ monkeypatch.setattr(mgr.x11, "start", lambda: None)
35
+ monkeypatch.setattr(chrome_mod, "find_chrome_binary", lambda: "/usr/bin/true")
36
+ monkeypatch.setattr(mgr, "_wait_for_cdp", lambda timeout=12.0: {"webSocketDebuggerUrl": "ws://x"})
37
+ monkeypatch.setattr(subprocess, "Popen", _FakePopen)
38
+
39
+ mgr.start() # must not raise FileNotFoundError
40
+ assert mgr._stderr_path.parent.is_dir()
41
+ mgr._stderr_file.close()
42
+
43
+
44
+ def test_start_respects_profile_env(monkeypatch, tmp_path):
45
+ monkeypatch.setenv("XDG_STATE_HOME", str(tmp_path / "state"))
46
+ monkeypatch.setenv("BROWSER_AGENT_PROFILE_DIR", "/tmp/browser-agent-profile")
47
+ mgr = RealChromeSession()
48
+ assert str(mgr.user_data_dir) == "/tmp/browser-agent-profile"
@@ -13,7 +13,7 @@ wheels = [
13
13
 
14
14
  [[package]]
15
15
  name = "browser-agent-server"
16
- version = "1.0.0"
16
+ version = "1.0.2"
17
17
  source = { editable = "." }
18
18
  dependencies = [
19
19
  { name = "trafilatura" },