implement windows support of the extension
Testing / test (push) Successful in 47s

This commit is contained in:
2026-04-13 11:02:54 +02:00
parent 080ca6da6d
commit 9dbe57c66c
9 changed files with 297 additions and 65 deletions
+22 -14
View File
@@ -1,11 +1,11 @@
"""
Unix socket client — sends commands to the native host relay socket.
Used by both the CLI and the public Python API.
Local IPC client — sends commands to native host relay endpoint.
Used by both CLI and public Python API.
Profile selection order:
1. Explicit `profile` argument to send_command()
2. BROWSER_CLI_PROFILE environment variable
3. First entry in /tmp/.browser_cli/registry.json
3. First entry in runtime registry
4. Otherwise, no browser can be resolved automatically
"""
import json
@@ -14,11 +14,13 @@ import socket
import struct
import uuid
from dataclasses import dataclass
from multiprocessing.connection import Client as PipeClient
from pathlib import Path
from typing import Any
SOCKET_DIR = Path("/tmp/.browser_cli")
REGISTRY_PATH = SOCKET_DIR / "registry.json"
from browser_cli.platform import endpoint_for_alias, is_windows, registry_path
REGISTRY_PATH = registry_path()
class BrowserNotConnected(Exception):
@@ -32,8 +34,10 @@ class BrowserTarget:
socket_path: str
def _active_sockets(reg: dict) -> dict:
"""Return only entries whose socket file exists on disk."""
def _active_endpoints(reg: dict) -> dict:
"""Return only entries whose endpoint appears reachable."""
if is_windows():
return dict(reg)
return {k: v for k, v in reg.items() if Path(v).exists()}
@@ -52,7 +56,7 @@ def active_browser_targets() -> list[BrowserTarget]:
return []
return [
BrowserTarget(profile=profile, display_name=display_browser_name(profile, sock_path), socket_path=sock_path)
for profile, sock_path in _active_sockets(reg).items()
for profile, sock_path in _active_endpoints(reg).items()
]
@@ -68,8 +72,7 @@ def _resolve_socket(profile: str | None = None) -> str:
return reg[target]
except Exception:
pass
safe = target.replace(" ", "_").replace("/", "_")
return str(SOCKET_DIR / f"{safe}.sock")
return endpoint_for_alias(target)
# Auto-detect: error when multiple browser instances are active
try:
@@ -107,10 +110,15 @@ def send_command(command: str, args: dict | None = None, profile: str | None = N
framed = struct.pack("<I", len(payload)) + payload
try:
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
sock.connect(sock_path)
sock.sendall(framed)
response = _recv_all(sock)
if is_windows():
with PipeClient(sock_path, family="AF_PIPE") as conn:
conn.send_bytes(payload)
response = conn.recv_bytes()
else:
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
sock.connect(sock_path)
sock.sendall(framed)
response = _recv_all(sock)
except (FileNotFoundError, ConnectionRefusedError, OSError):
profile_hint = f" (profile: {profile})" if profile else ""
raise BrowserNotConnected(