make it easyer to connect to a remove browser allow it with --browser ip alias too
Testing / test (push) Failing after 13m59s

This commit is contained in:
2026-05-01 19:55:02 +02:00
parent f836844791
commit 647867d05e
7 changed files with 196 additions and 33 deletions
+68 -22
View File
@@ -93,29 +93,47 @@ def _remote_display_name(endpoint: str, profile_name: str, display_name: str) ->
return f"{remote_name}:{display_name or profile_name}"
def remote_browser_targets(endpoint: str, token: str | None = None) -> list[BrowserTarget]:
"""Return browser targets advertised by a single remote endpoint."""
remote_targets = send_command("browser-cli.targets", remote=endpoint, token=token)
targets: list[BrowserTarget] = []
for item in remote_targets or []:
profile = str(item.get("profile") or "default")
display = str(item.get("displayName") or profile)
targets.append(
BrowserTarget(
profile=profile,
display_name=_remote_display_name(endpoint, profile, display),
socket_path="",
remote=endpoint,
token=token,
)
)
return targets
def _remote_browser_targets() -> list[BrowserTarget]:
targets: list[BrowserTarget] = []
for endpoint, cfg in _load_remotes().items():
token = str(cfg.get("token") or "") or None
try:
remote_targets = send_command("browser-cli.targets", remote=endpoint, token=token)
targets.extend(remote_browser_targets(endpoint, token))
except (BrowserNotConnected, RuntimeError):
continue
for item in remote_targets or []:
profile = str(item.get("profile") or "default")
display = str(item.get("displayName") or profile)
targets.append(
BrowserTarget(
profile=profile,
display_name=_remote_display_name(endpoint, profile, display),
socket_path="",
remote=endpoint,
token=token,
)
)
return targets
def remote_target_for_alias(alias: str | None) -> BrowserTarget | None:
"""Resolve a user-facing remote alias such as 'host:profile' to a target."""
if not alias:
return None
for target in _remote_browser_targets():
endpoint_profile = f"{target.remote}:{target.profile}" if target.remote else None
if alias in {target.display_name, endpoint_profile}:
return target
return None
def active_browser_targets(*, include_remotes: bool = True) -> list[BrowserTarget]:
targets: list[BrowserTarget] = []
if REGISTRY_PATH.exists():
@@ -164,10 +182,42 @@ def _resolve_socket(profile: str | None = None) -> str:
)
def _send_remote(endpoint: str, framed: bytes) -> bytes:
host, _, port_str = endpoint.rpartition(":")
if not host or not port_str:
raise BrowserNotConnected(f"Invalid remote endpoint '{endpoint}': expected host:port")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((host, int(port_str)))
sock.sendall(framed)
return _recv_all(sock)
def _auto_route_remote(endpoint: str, token: str | None) -> str | None:
targets = remote_browser_targets(endpoint, token)
if len(targets) == 1:
return targets[0].profile
if len(targets) > 1:
aliases = [target.profile for target in targets]
examples = "\n".join(f" browser-cli --remote {endpoint} --browser {a} ..." for a in aliases)
raise BrowserNotConnected(
f"Multiple remote browser instances are active: {', '.join(aliases)}\n"
f"Use --browser <alias> to select one:\n{examples}"
)
return None
def send_command(command: str, args: dict | None = None, profile: str | None = None, remote: str | None = None, token: str | None = None) -> Any:
"""Send a command to the browser and return the response data."""
requested_profile = profile or os.environ.get("BROWSER_CLI_PROFILE")
remote_endpoint = remote or os.environ.get("BROWSER_CLI_REMOTE")
resolved_token = token or os.environ.get("BROWSER_CLI_TOKEN") or token_for_remote(remote_endpoint)
remote_alias_target = None
if not remote_endpoint and requested_profile:
remote_alias_target = remote_target_for_alias(requested_profile)
if remote_alias_target:
remote_endpoint = remote_alias_target.remote
requested_profile = remote_alias_target.profile
resolved_token = token or os.environ.get("BROWSER_CLI_TOKEN") or (remote_alias_target.token if remote_alias_target else None) or token_for_remote(remote_endpoint)
msg = {
"id": str(uuid.uuid4()),
"command": command,
@@ -176,7 +226,9 @@ def send_command(command: str, args: dict | None = None, profile: str | None = N
if remote_endpoint:
if resolved_token:
msg["token"] = resolved_token
route_profile = profile or os.environ.get("BROWSER_CLI_PROFILE")
route_profile = requested_profile
if not route_profile and command != "browser-cli.targets":
route_profile = _auto_route_remote(remote_endpoint, resolved_token)
if route_profile:
msg["_route"] = route_profile
payload = json.dumps(msg).encode("utf-8")
@@ -184,13 +236,7 @@ def send_command(command: str, args: dict | None = None, profile: str | None = N
try:
if remote_endpoint:
host, _, port_str = remote_endpoint.rpartition(":")
if not host or not port_str:
raise BrowserNotConnected(f"Invalid remote endpoint '{remote_endpoint}': expected host:port")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((host, int(port_str)))
sock.sendall(framed)
response = _recv_all(sock)
response = _send_remote(remote_endpoint, framed)
elif is_windows():
sock_path = _resolve_socket(profile)
with PipeClient(sock_path, family="AF_PIPE") as conn: