refactor: modularize auth transport and markdown
Testing / remote-protocol-compat (0.9.5) (push) Successful in 1m4s
Testing / test (push) Successful in 1m22s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 1m7s
Package Extension / package-extension (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 1m5s
Testing / remote-protocol-compat (0.9.5) (push) Successful in 1m4s
Testing / test (push) Successful in 1m22s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 1m7s
Package Extension / package-extension (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 1m5s
- Split auth into focused package modules for agent keys, file keys, signing, and post-quantum transport helpers while keeping the public browser_cli.auth import surface intact. - Move transport encoding internals into a package with separate codec and binary-hoisting helpers, preserving browser_cli.transport compatibility. - Extract remote TCP auth/socket helpers and serve challenge setup out of the runtime paths to make connection handling easier to reason about. - Move the extension markdown extractor into a dedicated content/markdown folder with separate root selection, code normalization, renderer, and utils. - Centralize CLI Rich rendering helpers for tab/window tree and table output, and add rendering tests for the shared builders. - Remove local typing ignores in SDK/decorator/script plumbing and bump the package and extension version to 0.15.3.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
|
||||
import click
|
||||
from rich.console import Console
|
||||
@@ -12,25 +14,25 @@ from browser_cli.commands import client_from_ctx, handle_errors
|
||||
console = Console()
|
||||
|
||||
def _load_steps(path: Path):
|
||||
text = path.read_text(encoding="utf-8")
|
||||
if path.suffix.lower() in {".yaml", ".yml"}:
|
||||
try:
|
||||
import yaml # type: ignore
|
||||
except Exception as exc:
|
||||
raise click.ClickException("YAML scripts require PyYAML; use JSON or install PyYAML") from exc
|
||||
return yaml.safe_load(text)
|
||||
return json.loads(text)
|
||||
text = path.read_text(encoding="utf-8")
|
||||
if path.suffix.lower() in {".yaml", ".yml"}:
|
||||
try:
|
||||
yaml = cast(Any, importlib.import_module("yaml"))
|
||||
except Exception as exc:
|
||||
raise click.ClickException("YAML scripts require PyYAML; use JSON or install PyYAML") from exc
|
||||
return yaml.safe_load(text)
|
||||
return json.loads(text)
|
||||
|
||||
def _parse_step(step):
|
||||
if isinstance(step, str):
|
||||
return step, {}
|
||||
if isinstance(step, dict):
|
||||
if "command" in step:
|
||||
return step["command"], step.get("args") or {}
|
||||
if len(step) == 1:
|
||||
command, args = next(iter(step.items()))
|
||||
return command, args or {}
|
||||
raise click.ClickException(f"Invalid script step: {step!r}")
|
||||
if isinstance(step, str):
|
||||
return step, {}
|
||||
if isinstance(step, dict):
|
||||
if "command" in step:
|
||||
return step["command"], step.get("args") or {}
|
||||
if len(step) == 1:
|
||||
command, args = next(iter(step.items()))
|
||||
return command, args or {}
|
||||
raise click.ClickException(f"Invalid script step: {step!r}")
|
||||
|
||||
@click.command("script")
|
||||
@click.argument("file", type=click.Path(exists=True, dir_okay=False, path_type=Path))
|
||||
@@ -41,28 +43,28 @@ def _parse_step(step):
|
||||
@click.option("--allow-dangerous", is_flag=True, help="Allow high-risk commands such as dom.eval, storage.*, screenshots")
|
||||
@handle_errors
|
||||
def cmd_script(file: Path, json_output: bool, continue_on_error: bool, allow_read_page: bool, allow_control: bool, allow_dangerous: bool):
|
||||
"""Run a JSON/YAML batch script of browser-cli wire commands."""
|
||||
steps = _load_steps(file)
|
||||
if not isinstance(steps, list):
|
||||
raise click.ClickException("Script root must be a list")
|
||||
client = client_from_ctx()
|
||||
policy = CommandPolicy(allow_read_page=allow_read_page, allow_control=allow_control, allow_dangerous=allow_dangerous)
|
||||
results = []
|
||||
for index, step in enumerate(steps, start=1):
|
||||
command, args = _parse_step(step)
|
||||
try:
|
||||
assert_command_allowed(command, policy)
|
||||
result = client.command(command, args)
|
||||
results.append({"index": index, "command": command, "ok": True, "result": result})
|
||||
if not json_output:
|
||||
console.print(f"[green]✓[/green] {index}: {command}")
|
||||
except Exception as exc:
|
||||
results.append({"index": index, "command": command, "ok": False, "error": str(exc)})
|
||||
if not continue_on_error:
|
||||
if json_output:
|
||||
click.echo(json.dumps(results, indent=2, default=str))
|
||||
raise
|
||||
if not json_output:
|
||||
console.print(f"[red]✗[/red] {index}: {command}: {exc}")
|
||||
if json_output:
|
||||
click.echo(json.dumps(results, indent=2, default=str))
|
||||
"""Run a JSON/YAML batch script of browser-cli wire commands."""
|
||||
steps = _load_steps(file)
|
||||
if not isinstance(steps, list):
|
||||
raise click.ClickException("Script root must be a list")
|
||||
client = client_from_ctx()
|
||||
policy = CommandPolicy(allow_read_page=allow_read_page, allow_control=allow_control, allow_dangerous=allow_dangerous)
|
||||
results = []
|
||||
for index, step in enumerate(steps, start=1):
|
||||
command, args = _parse_step(step)
|
||||
try:
|
||||
assert_command_allowed(command, policy)
|
||||
result = client.command(command, args)
|
||||
results.append({"index": index, "command": command, "ok": True, "result": result})
|
||||
if not json_output:
|
||||
console.print(f"[green]✓[/green] {index}: {command}")
|
||||
except Exception as exc:
|
||||
results.append({"index": index, "command": command, "ok": False, "error": str(exc)})
|
||||
if not continue_on_error:
|
||||
if json_output:
|
||||
click.echo(json.dumps(results, indent=2, default=str))
|
||||
raise
|
||||
if not json_output:
|
||||
console.print(f"[red]✗[/red] {index}: {command}: {exc}")
|
||||
if json_output:
|
||||
click.echo(json.dumps(results, indent=2, default=str))
|
||||
|
||||
Reference in New Issue
Block a user