feat: harden remote serve and reuse connections
Testing / remote-protocol-compat (0.9.5) (push) Successful in 56s
Testing / remote-protocol-compat (0.9.3) (push) Successful in 59s
Testing / test (push) Successful in 1m1s
Build & Publish Package / publish (push) Successful in 33s
Package Extension / package-extension (push) Successful in 36s

- Gate TCP serve commands with safe-by-default policies, per-key allow tokens, per-key rate limiting, and audit labels.
- Reuse authenticated encrypted remote sessions and parallelize/caches multi-browser fanout to reduce repeated handshake roundtrips.
- Increase paged native-host batch size with extension-side byte budgeting to speed large tab listings safely.
- Point install output at public Chrome Web Store / Firefox AMO listings by default, with --dev preserving unpacked workflows.
- Share search-engine metadata between CLI and SDK and bump the package/extension version to 0.16.0.
- Cover the new security, pooling, paging, install, and fanout behavior with expanded Python and extension tests.
This commit is contained in:
2026-06-18 14:24:15 +02:00
parent 8dece7800f
commit 6fa931aa36
49 changed files with 3407 additions and 1878 deletions
+16 -10
View File
@@ -32,6 +32,12 @@ GROUP_DATA = {
"tabCount": 3,
}
def tab_close_args(tab_id: int):
return {"tabId": tab_id, "tabIds": None, "inactive": False, "duplicates": False, "gentleMode": "auto"}
def group_close_args(group_id: int):
return {"groupId": group_id, "gentleMode": "auto"}
@pytest.fixture()
def mock_send():
"""Patch send_command for the duration of one test.
@@ -454,7 +460,7 @@ class TestTabs:
assert mock_send.call_args_list == [
call("tabs.list", {}, profile="default"),
call("tabs.list", {}, profile="work"),
call("tabs.close", {"tabId": 11}, profile="work", remote=None, key=None),
call("tabs.close", tab_close_args(11), profile="work", remote=None, key=None),
]
def test_tabs_list_remote_uses_only_requested_remote_and_binds_actions(self, mock_send):
@@ -473,7 +479,7 @@ class TestTabs:
assert [tab.browser for tab in tabs] == ["work"]
assert mock_send.call_args_list == [
call("tabs.list", {}, profile="work", remote="host:8765", key=None),
call("tabs.close", {"tabId": 10}, profile="work", remote="host:8765", key=None),
call("tabs.close", tab_close_args(10), profile="work", remote="host:8765", key=None),
]
def test_tabs_list_remote_bound_actions_preserve_key(self, mock_send):
@@ -488,7 +494,7 @@ class TestTabs:
assert mock_send.call_args_list == [
call("tabs.list", {}, profile="work", remote="browser-host.example", key="agent"),
call("tabs.close", {"tabId": 10}, profile="work", remote="browser-host.example", key="agent"),
call("tabs.close", tab_close_args(10), profile="work", remote="browser-host.example", key="agent"),
]
def test_tabs_list_browser_host_alias_fans_out_to_remote_targets(self, mock_send):
@@ -510,7 +516,7 @@ class TestTabs:
assert mock_send.call_args_list == [
call("tabs.list", {}, profile="main", remote="browser-host.example:8765", key="agent"),
call("tabs.list", {}, profile="work", remote="browser-host.example:8765", key="agent"),
call("tabs.close", {"tabId": 11}, profile="work", remote="browser-host.example:8765", key="agent"),
call("tabs.close", tab_close_args(11), profile="work", remote="browser-host.example:8765", key="agent"),
]
def test_tabs_active_returns_active_tab(self, b, mock_send):
@@ -690,7 +696,7 @@ class TestGroups:
assert mock_send.call_args_list == [
call("group.list", {}, profile="default"),
call("group.list", {}, profile="work"),
call("group.close", {"groupId": 99}, profile="work", remote=None, key=None),
call("group.close", group_close_args(99), profile="work", remote=None, key=None),
]
def test_group_list_remote_uses_only_requested_remote_and_binds_actions(self, mock_send):
@@ -709,7 +715,7 @@ class TestGroups:
assert [group.browser for group in groups] == ["work"]
assert mock_send.call_args_list == [
call("group.list", {}, profile="work", remote="host:8765", key=None),
call("group.close", {"groupId": 42}, profile="work", remote="host:8765", key=None),
call("group.close", group_close_args(42), profile="work", remote="host:8765", key=None),
]
def test_group_list_remote_bound_actions_preserve_key(self, mock_send):
@@ -724,7 +730,7 @@ class TestGroups:
assert mock_send.call_args_list == [
call("group.list", {}, profile="work", remote="browser-host.example", key="agent"),
call("group.close", {"groupId": 42}, profile="work", remote="browser-host.example", key="agent"),
call("group.close", group_close_args(42), profile="work", remote="browser-host.example", key="agent"),
]
def test_group_count_multi_browser_returns_browser_counts(self, b, mock_send):
@@ -954,7 +960,7 @@ class TestTabModel:
def test_close(self, tab, mock_send):
tab.close()
mock_send.assert_called_once_with("tabs.close", {"tabId": 10}, profile=None, remote=None, key=None)
mock_send.assert_called_once_with("tabs.close", tab_close_args(10), profile=None, remote=None, key=None)
def test_activate(self, tab, mock_send):
tab.activate()
@@ -1043,7 +1049,7 @@ class TestGroupModel:
def test_close(self, group, mock_send):
group.close()
mock_send.assert_called_once_with("group.close", {"groupId": 42}, profile=None, remote=None, key=None)
mock_send.assert_called_once_with("group.close", group_close_args(42), profile=None, remote=None, key=None)
def test_tabs(self, group, mock_send):
mock_send.return_value = [TAB_DATA]
@@ -1115,7 +1121,7 @@ class TestSDKDecorators:
remote=None,
key=None,
),
call("tabs.close", {"tabId": 123}, profile=None, remote=None, key=None),
call("tabs.close", tab_close_args(123), profile=None, remote=None, key=None),
]
def test_wait_for_selector_runs_before_function_and_can_inject_result(self, b, mock_send):