Polish Launcher host access popover

Use the standard compact panel radius and present the emergency gateway action as Disconnect. Keep the plugin contract and focused UI regression coverage aligned.

Alessandro committed Jul 15, 2026 at 15:29 UTC e2fd320ac62310f24c14e81fbf6e67666529c0a8
3 files changed +9 -5
plugins/_a0_connector/AGENTS.md
+3 -2
@@ -32,7 +32,8 @@
32 socket with the same ID replaces stale state; distinct simultaneous IDs fail
33 closed as Multiple hosts.
34 - `connector_gateway_control` and `connector_gateway_control_result` cover
35 - master state, complete scope replacement, and emergency disconnect. Protected
35 + master state, complete scope replacement, and Disconnect
36 + (`emergency_disconnect` on the wire). Protected
37 WebUI mutations require CSRF, await the matching acknowledgement, and return
38 refreshed status. Never let the WebUI select a host folder or personal
39 browser profile.
@@ -41,7 +42,7 @@
42 older gateway declarations without `file_write` read/write compatible.
43 - The `sync-status-end` Launcher gateway extension renders only when the user agent
44 includes `A0-Launcher/`. It may show status, master/scope controls,
44 - preparation errors, and Emergency disconnect; standard browser sessions must
45 + preparation errors, and Disconnect; standard browser sessions must
46 not expose it. Keep its trigger inside the existing sync indicator, render one
47 computer glyph per connected Launcher gateway, and retain one muted glyph
48 while disconnected so the control remains reachable. Do not add a native
plugins/_a0_connector/extensions/webui/sync-status-end/launcher-gateway.html
+2 -2
@@ -113,7 +113,7 @@
113 x-show="$store.launcherGateway.gateway"
114 :disabled="$store.launcherGateway.saving"
115 @click="$store.launcherGateway.emergencyDisconnect()"
116 - >Emergency disconnect</button>
116 + >Disconnect</button>
117 </section>
118 </div>
119
@@ -136,7 +136,7 @@
136 .launcher-gateway-host-icon.is-placeholder { opacity: .55; }
137 .launcher-gateway-popover {
138 position: absolute; top: calc(100% + .45rem); right: 0; z-index: 1200; width: min(20rem, calc(100vw - 2rem));
139 - padding: .8rem; border: 1px solid var(--color-border); border-radius: var(--border-radius);
139 + padding: .8rem; border: 1px solid var(--color-border); border-radius: var(--border-radius-sm);
140 background: var(--color-panel); box-shadow: 0 16px 42px rgba(0, 0, 0, .24);
141 }
142 .launcher-gateway-header { display: flex; justify-content: space-between; gap: .75rem; align-items: flex-start; }
tests/test_a0_connector_launcher_gateway.py
+4 -1
@@ -78,7 +78,10 @@ def test_launcher_gateway_indicator_joins_sync_status_without_visual_noise() ->
78 assert "launcher-gateway-trigger-label" not in source
79 assert "launcher-gateway-dot" not in source
80 assert ":title=" not in source
81 - assert "border-radius: var(--border-radius);" in source
81 + assert ">Disconnect</button>" in source
82 + assert "Emergency disconnect" not in source
83 + popover_css = source.split(".launcher-gateway-popover {", 1)[1].split("}", 1)[0]
84 + assert "border-radius: var(--border-radius-sm);" in popover_css
85
86
87 def test_launcher_gateway_is_fallback_after_context_bound_cli() -> None: