0d5c49c19a
Testing / test (push) Failing after 10m21s
- compat.py → compat/ package: auth.py (auth-field normalizers), commands.py (command-format shims), __init__.py (re-exports) - Add _auth_0_9_3 transformer: normalizes pubkey to lowercase before auth so clients < 0.9.3 sending uppercase hex are accepted - adapt_auth() now called before auth check in serve.py; command extracted after adapt_auth so future transformers can rename commands safely - serve.py: deduplicate _recv_exact (import from client), unify resp/resp_payload across Windows/Unix branches, require lowercase hex pubkey (re.fullmatch), reorganize imports, drop unused os import - client.py: move payload/framed construction inside branches (remote path no longer serializes JSON it never uses); fix _is_valid_key_spec operator precedence; import MAX_MSG_BYTES from version_manager - auth.py: narrow except clause (ValueError instead of bare Exception) - Bump version 0.9.2 → 0.9.3 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
96 lines
3.8 KiB
Python
96 lines
3.8 KiB
Python
import click
|
|
from browser_cli.commands import _handle
|
|
from rich.console import Console
|
|
|
|
console = Console()
|
|
|
|
|
|
@click.group("nav")
|
|
def nav_group():
|
|
"""Navigate — open URLs, reload, go back/forward, focus tabs."""
|
|
|
|
|
|
@nav_group.command("open")
|
|
@click.argument("url")
|
|
@click.option("--bg", is_flag=True, help="Open in background (no focus)")
|
|
@click.option("--window", "window_name", default=None, help="Open in named window")
|
|
@click.option("--group", "group_name", default=None, help="Open directly into a tab group (name or ID)")
|
|
def cmd_open(url, bg, window_name, group_name):
|
|
"""Open URL in a new tab."""
|
|
_handle("navigate.open", {"url": url, "background": bg, "window": window_name, "group": group_name})
|
|
suffix = ""
|
|
if group_name:
|
|
suffix = f" in group '{group_name}'"
|
|
elif window_name:
|
|
suffix = f" in window '{window_name}'"
|
|
console.print(f"[green]Opened:[/green] {url}{suffix}")
|
|
|
|
|
|
@nav_group.command("reload")
|
|
@click.argument("tab_id", type=int, required=False)
|
|
def cmd_reload(tab_id):
|
|
"""Reload the active (or specified) tab."""
|
|
_handle("navigate.reload", {"tabId": tab_id})
|
|
console.print("[green]Reloaded[/green]")
|
|
|
|
|
|
@nav_group.command("hard-reload")
|
|
@click.argument("tab_id", type=int, required=False)
|
|
def cmd_hard_reload(tab_id):
|
|
"""Hard reload (bypass cache) the active (or specified) tab."""
|
|
_handle("navigate.hard_reload", {"tabId": tab_id})
|
|
console.print("[green]Hard reloaded[/green]")
|
|
|
|
|
|
@nav_group.command("back")
|
|
@click.argument("tab_id", type=int, required=False)
|
|
def cmd_back(tab_id):
|
|
"""Navigate back in the active (or specified) tab."""
|
|
_handle("navigate.back", {"tabId": tab_id})
|
|
console.print("[green]Navigated back[/green]")
|
|
|
|
|
|
@nav_group.command("forward")
|
|
@click.argument("tab_id", type=int, required=False)
|
|
def cmd_forward(tab_id):
|
|
"""Navigate forward in the active (or specified) tab."""
|
|
_handle("navigate.forward", {"tabId": tab_id})
|
|
console.print("[green]Navigated forward[/green]")
|
|
|
|
|
|
@nav_group.command("focus")
|
|
@click.argument("pattern")
|
|
def cmd_focus(pattern):
|
|
"""Jump to a tab by URL pattern or tab ID."""
|
|
result = _handle("navigate.focus", {"pattern": pattern})
|
|
if result:
|
|
console.print(f"[green]Focused:[/green] {result.get('url', result)}")
|
|
else:
|
|
console.print(f"[yellow]No tab found matching:[/yellow] {pattern}")
|
|
|
|
|
|
@nav_group.command("open-wait")
|
|
@click.argument("url")
|
|
@click.option("--timeout", type=float, default=30.0, show_default=True, help="Max seconds to wait for load")
|
|
@click.option("--bg", is_flag=True, help="Open in background (no focus)")
|
|
@click.option("--window", "window_name", default=None, help="Open in named window")
|
|
@click.option("--group", "group_name", default=None, help="Open in tab group")
|
|
def cmd_open_wait(url, timeout, bg, window_name, group_name):
|
|
"""Open URL in a new tab and wait until fully loaded."""
|
|
result = _handle("navigate.open_wait", {
|
|
"url": url, "timeout": int(timeout * 1000),
|
|
"background": bg, "window": window_name, "group": group_name,
|
|
})
|
|
title = result.get("title", "") if isinstance(result, dict) else ""
|
|
console.print(f"[green]Loaded:[/green] {url}" + (f" — {title}" if title else ""))
|
|
|
|
|
|
@nav_group.command("wait")
|
|
@click.option("--tab", "tab_id", type=int, default=None, help="Tab ID (default: active tab)")
|
|
@click.option("--timeout", type=float, default=30.0, show_default=True, help="Max seconds to wait")
|
|
@click.option("--ready-state", type=click.Choice(["complete", "interactive"]), default="complete", show_default=True, help="Target ready state")
|
|
def cmd_wait(tab_id, timeout, ready_state):
|
|
"""Wait until tab finishes loading."""
|
|
result = _handle("navigate.wait", {"tabId": tab_id, "timeout": int(timeout * 1000), "readyState": ready_state})
|
|
console.print(f"[green]Ready:[/green] {result.get('url', '')} — {result.get('title', '')}")
|