fd5447cbb9
Testing / remote-protocol-compat (0.9.3) (push) Successful in 42s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 44s
Package Extension / package-extension (push) Successful in 43s
Build & Publish Package / publish (push) Successful in 43s
Testing / test (push) Successful in 45s
Restructure the Python API and internals around composable namespaces and a standalone transport/endpoint layer. Bump to 0.12.0. Python API: - Replace flat methods (b.tabs_list(), b.group_list()) with namespaces: b.nav, b.tabs, b.groups, b.windows, b.dom, b.extract, b.page, b.storage, b.cookies, b.session, b.perf, b.extension. - Shrink browser_cli/__init__.py to a thin composition root; move all behaviour into browser_cli/sdk/ (one module per namespace + factories, base, routing). Internals: - Add browser_cli/transport.py and remote_transport.py to isolate IPC from command logic; client.py now delegates instead of owning transport. - Add browser_cli/endpoints.py for endpoint resolution and browser_cli/errors.py for shared error types. - Extract markdown rendering into browser_cli/markdown.py (out of extract). - Add USER_AGENT to version_manager. Tooling & tests: - Add justfile with common dev tasks. - Update CLI commands and demo to the namespaced API. - Rework tests for the new layout; add test_transport.py and test_refactor_boundaries.py to lock in module boundaries. BREAKING CHANGE: flat API methods are removed in favour of namespaces (e.g. b.tabs_list() -> b.tabs.list(), b.group_list() -> b.groups.list()).
64 lines
2.6 KiB
Python
64 lines
2.6 KiB
Python
"""Navigation namespace: ``b.nav.*``."""
|
|
from __future__ import annotations
|
|
|
|
from browser_cli.models import Tab
|
|
from browser_cli.sdk.base import Namespace
|
|
|
|
class NavigationNS(Namespace):
|
|
"""Open URLs, navigate history, and focus tabs."""
|
|
|
|
def open(self, url: str, *, background: bool = False, window: str | None = None, group: str | None = None) -> None:
|
|
"""Open *url* in a new tab."""
|
|
self._c._cmd("navigate.open", {"url": url, "background": background, "window": window, "group": group})
|
|
|
|
def open_wait(
|
|
self,
|
|
url: str,
|
|
*,
|
|
timeout: float = 30.0,
|
|
background: bool = False,
|
|
window: str | None = None,
|
|
group: str | None = None,
|
|
) -> Tab:
|
|
"""Open *url* in a new tab and block until fully loaded. Returns the Tab."""
|
|
return self._c._require_tab(
|
|
self._c._cmd("navigate.open_wait", {
|
|
"url": url, "timeout": int(timeout * 1000),
|
|
"background": background, "window": window, "group": group,
|
|
}),
|
|
"navigate.open_wait returned unexpected data",
|
|
)
|
|
|
|
def reload(self, tab_id: int | None = None) -> None:
|
|
self._c._cmd("navigate.reload", {"tabId": tab_id})
|
|
|
|
def hard_reload(self, tab_id: int | None = None) -> None:
|
|
self._c._cmd("navigate.hard_reload", {"tabId": tab_id})
|
|
|
|
def back(self, tab_id: int | None = None) -> None:
|
|
self._c._cmd("navigate.back", {"tabId": tab_id})
|
|
|
|
def forward(self, tab_id: int | None = None) -> None:
|
|
self._c._cmd("navigate.forward", {"tabId": tab_id})
|
|
|
|
def focus(self, pattern: str) -> dict | None:
|
|
"""Focus the first tab whose URL matches *pattern*. Returns the matched tab info, if any."""
|
|
return self._c._cmd("navigate.focus", {"pattern": pattern})
|
|
|
|
def to(self, tab_id: int, url: str) -> None:
|
|
"""Navigate a specific tab to *url* in place."""
|
|
self._c._cmd("navigate.to", {"tabId": tab_id, "url": url})
|
|
|
|
def search(
|
|
self, engine: str, query: str, *,
|
|
background: bool = False, window: str | None = None, group: str | None = None,
|
|
) -> None:
|
|
"""Open a search query in the given engine (e.g. 'google', 'youtube', 'ddg')."""
|
|
from urllib.parse import quote_plus
|
|
from browser_cli.commands.search import ENGINES
|
|
template = ENGINES.get(engine)
|
|
if template is None:
|
|
raise ValueError(f"Unknown search engine '{engine}'. Available: {', '.join(ENGINES)}")
|
|
url = template.format(query=quote_plus(query))
|
|
self._c._cmd("navigate.open", {"url": url, "background": background, "window": window, "group": group})
|