diff --git a/browser_cli/client.py b/browser_cli/client.py index fd62d13..e321fbf 100644 --- a/browser_cli/client.py +++ b/browser_cli/client.py @@ -127,10 +127,21 @@ 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(): + targets = _remote_browser_targets() + for target in targets: endpoint_profile = f"{target.remote}:{target.profile}" if target.remote else None if alias in {target.display_name, endpoint_profile}: return target + + endpoint_matches = [] + for target in targets: + if not target.remote: + continue + remote_host, sep, _remote_port = target.remote.rpartition(":") + if alias == target.remote or (sep and alias == remote_host): + endpoint_matches.append(target) + if len(endpoint_matches) == 1: + return endpoint_matches[0] return None diff --git a/extension/manifest.json b/extension/manifest.json index a1efc53..54863fa 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "browser-cli", - "version": "0.8.3", + "version": "0.8.4", "description": "Control your browser from the terminal via browser-cli", "permissions": [ "tabs", diff --git a/pyproject.toml b/pyproject.toml index db686a6..c189b86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "browser-cli" -version = "0.8.3" +version = "0.8.4" description = "Control your real running browser from the terminal via a browser extension" requires-python = ">=3.10" dependencies = [ diff --git a/tests/test_client.py b/tests/test_client.py index 588a525..df0c8e3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -170,6 +170,61 @@ def test_remote_target_for_alias_accepts_full_endpoint_profile(monkeypatch): assert target.remote == "host:8765" +def test_remote_target_for_alias_accepts_host_when_only_one_remote_target(monkeypatch): + remote_host = "browser-host.example" + remote_endpoint = f"{remote_host}:8765" + monkeypatch.setattr( + "browser_cli.client._remote_browser_targets", + lambda: [BrowserTarget("work", f"{remote_host}:work", "", remote=remote_endpoint, token="secret")], + ) + + target = remote_target_for_alias(remote_host) + + assert target is not None + assert target.profile == "work" + assert target.remote == remote_endpoint + + +def test_send_command_resolves_host_alias_to_single_remote_target(monkeypatch): + remote_host = "browser-host.example" + remote_endpoint = f"{remote_host}:8765" + monkeypatch.delenv("BROWSER_CLI_REMOTE", raising=False) + monkeypatch.delenv("BROWSER_CLI_TOKEN", raising=False) + monkeypatch.setenv("BROWSER_CLI_PROFILE", remote_host) + sent = {} + + monkeypatch.setattr( + "browser_cli.client._remote_browser_targets", + lambda: [BrowserTarget("work", f"{remote_host}:work", "", remote=remote_endpoint, token="secret")], + ) + + def fake_send_remote(endpoint, framed): + payload_len = int.from_bytes(framed[:4], "little") + msg = json.loads(framed[4:4 + payload_len]) + sent["endpoint"] = endpoint + sent.update(msg) + return json.dumps({"success": True, "data": []}).encode("utf-8") + + monkeypatch.setattr("browser_cli.client._send_remote", fake_send_remote) + + assert send_command("tabs.list") == [] + assert sent["endpoint"] == remote_endpoint + assert sent["_route"] == "work" + assert sent["token"] == "secret" + + +def test_remote_target_for_alias_keeps_host_alias_ambiguous_for_multiple_targets(monkeypatch): + monkeypatch.setattr( + "browser_cli.client._remote_browser_targets", + lambda: [ + BrowserTarget("main", "host:main", "", remote="host:8765", token="secret"), + BrowserTarget("work", "host:work", "", remote="host:8765", token="secret"), + ], + ) + + assert remote_target_for_alias("host") is None + + def test_send_command_requires_browser_for_multiple_remote_targets(monkeypatch): monkeypatch.delenv("BROWSER_CLI_PROFILE", raising=False) monkeypatch.setattr( diff --git a/uv.lock b/uv.lock index 0e4da1d..ddd97d0 100644 --- a/uv.lock +++ b/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.10" [[package]] name = "browser-cli" -version = "0.8.3" +version = "0.8.4" source = { editable = "." } dependencies = [ { name = "click" },