Report Host access control failures
Use Agent Zero's shared notification system when Launcher gateway mutations fail, then refresh the popover state as before.
Alessandro committed
Jul 14, 2026 at 22:43 UTC
3271ff43e3510503ebe6c5eb979233a130160583
3 files changed
+20
-1
plugins/_a0_connector/AGENTS.md
+2
-1
@@ -42,7 +42,8 @@
42
not expose it. Keep its trigger icon-only at rest and reveal the status label
43
on hover, keyboard focus, or while open. Connected and disconnected states
44
share the computer glyph; the adjacent status dot communicates connectivity.
45
- Keep the open popover above the compact right-canvas rail.
45
+ Keep the open popover above the compact right-canvas rail and report control
46
+ failures through the shared notification system.
47
- File operation results may arrive as chunked JSON/base64
48
`connector_file_op_result` frames; resolve the pending file operation only
49
after all chunks for the `op_id` are assembled.
plugins/_a0_connector/webui/launcher-gateway-store.js
+5
@@ -1,5 +1,6 @@
1
import { createStore } from "/js/AlpineStore.js";
2
import { callJsonApi } from "/js/api.js";
3
+import { toastFrontendError } from "/components/notifications/notification-store.js";
4
5
const STATUS_API = "/plugins/_a0_connector/v1/launcher_gateway_status";
6
const CONTROL_API = "/plugins/_a0_connector/v1/launcher_gateway_control";
@@ -120,6 +121,10 @@ const model = {
121
this.status = response?.status || this.status;
122
} catch (error) {
123
console.error("Failed to control Launcher host:", error);
124
+ void toastFrontendError(
125
+ error?.message || "Host access change failed.",
126
+ "Host access",
127
+ );
128
await this.refresh();
129
} finally {
130
this.saving = false;
tests/test_a0_connector_launcher_gateway.py
+13
@@ -1,6 +1,7 @@
1
from __future__ import annotations
2
3
import asyncio
4
+from pathlib import Path
5
import uuid
6
7
from plugins._a0_connector.api.v1 import launcher_gateway_control
@@ -37,6 +38,18 @@ def test_launcher_gateway_features_are_negotiated_on_http_and_websocket() -> Non
38
assert LauncherGatewayStatus.requires_auth() is True
39
40
41
+def test_launcher_gateway_control_errors_use_webui_notifications() -> None:
42
+ source = (
43
+ Path(__file__).parents[1]
44
+ / "plugins"
45
+ / "_a0_connector"
46
+ / "webui"
47
+ / "launcher-gateway-store.js"
48
+ ).read_text(encoding="utf-8")
49
+ assert 'import { toastFrontendError }' in source
50
+ assert 'void toastFrontendError(' in source
51
+
52
+
53
def test_launcher_gateway_is_fallback_after_context_bound_cli() -> None:
54
context_id = f"ctx-{uuid.uuid4()}"
55
cli_sid = _sid("cli")