add multi browser mode to arragate data from all browsers by tabs list, tabs count, group list, group count and windows list
remove (unnamed) into the group names just leave it a empty string, remove Focused on windows how should the browser know what windows are focused
This commit is contained in:
+42
-17
@@ -13,6 +13,7 @@ import os
|
||||
import socket
|
||||
import struct
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -24,11 +25,37 @@ class BrowserNotConnected(Exception):
|
||||
"""Raised when the native host socket is not available."""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BrowserTarget:
|
||||
profile: str
|
||||
display_name: str
|
||||
socket_path: str
|
||||
|
||||
|
||||
def _active_sockets(reg: dict) -> dict:
|
||||
"""Return only entries whose socket file exists on disk."""
|
||||
return {k: v for k, v in reg.items() if Path(v).exists()}
|
||||
|
||||
|
||||
def display_browser_name(profile_name: str, sock_path: str) -> str:
|
||||
if profile_name != "default":
|
||||
return profile_name
|
||||
return Path(sock_path).stem or profile_name
|
||||
|
||||
|
||||
def active_browser_targets() -> list[BrowserTarget]:
|
||||
if not REGISTRY_PATH.exists():
|
||||
return []
|
||||
try:
|
||||
reg = json.loads(REGISTRY_PATH.read_text())
|
||||
except Exception:
|
||||
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()
|
||||
]
|
||||
|
||||
|
||||
def _resolve_socket(profile: str | None = None) -> str:
|
||||
"""Return the socket path for the given profile (or auto-detect)."""
|
||||
target = profile or os.environ.get("BROWSER_CLI_PROFILE")
|
||||
@@ -45,23 +72,21 @@ def _resolve_socket(profile: str | None = None) -> str:
|
||||
return str(SOCKET_DIR / f"{safe}.sock")
|
||||
|
||||
# Auto-detect: error when multiple browser instances are active
|
||||
if REGISTRY_PATH.exists():
|
||||
try:
|
||||
reg = json.loads(REGISTRY_PATH.read_text())
|
||||
active = _active_sockets(reg)
|
||||
if len(active) > 1:
|
||||
aliases = list(active.keys())
|
||||
examples = "\n".join(f" browser-cli --browser {a} ..." for a in aliases)
|
||||
raise BrowserNotConnected(
|
||||
f"Multiple browser instances are active: {', '.join(aliases)}\n"
|
||||
f"Use --browser <alias> to select one:\n{examples}"
|
||||
)
|
||||
if active:
|
||||
return next(iter(active.values()))
|
||||
except BrowserNotConnected:
|
||||
raise
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
active = active_browser_targets()
|
||||
if len(active) > 1:
|
||||
aliases = [target.profile for target in active]
|
||||
examples = "\n".join(f" browser-cli --browser {a} ..." for a in aliases)
|
||||
raise BrowserNotConnected(
|
||||
f"Multiple browser instances are active: {', '.join(aliases)}\n"
|
||||
f"Use --browser <alias> to select one:\n{examples}"
|
||||
)
|
||||
if active:
|
||||
return active[0].socket_path
|
||||
except BrowserNotConnected:
|
||||
raise
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
raise BrowserNotConnected(
|
||||
"Cannot resolve a browser socket automatically.\n"
|
||||
|
||||
Reference in New Issue
Block a user