macOS: auto-start gateway for Canvas actions

This commit is contained in:
Peter Steinberger
2025-12-17 17:36:40 +01:00
parent c1985443fd
commit 9c7d51429e
3 changed files with 50 additions and 9 deletions

View File

@@ -682,7 +682,7 @@ private final class HoverChromeContainerView: NSView {
v.state = .active
v.appearance = NSAppearance(named: .vibrantDark)
v.wantsLayer = true
v.layer?.cornerRadius = 11
v.layer?.cornerRadius = 10
v.layer?.masksToBounds = true
v.layer?.borderWidth = 1
v.layer?.borderColor = NSColor.white.withAlphaComponent(0.22).cgColor
@@ -695,7 +695,7 @@ private final class HoverChromeContainerView: NSView {
}()
private let closeButton: NSButton = {
let cfg = NSImage.SymbolConfiguration(pointSize: 9, weight: .semibold)
let cfg = NSImage.SymbolConfiguration(pointSize: 8, weight: .semibold)
let img = NSImage(systemSymbolName: "xmark", accessibilityDescription: "Close")?
.withSymbolConfiguration(cfg)
?? NSImage(size: NSSize(width: 18, height: 18))
@@ -744,13 +744,13 @@ private final class HoverChromeContainerView: NSView {
self.closeBackground.centerXAnchor.constraint(equalTo: self.closeButton.centerXAnchor),
self.closeBackground.centerYAnchor.constraint(equalTo: self.closeButton.centerYAnchor),
self.closeBackground.widthAnchor.constraint(equalToConstant: 22),
self.closeBackground.heightAnchor.constraint(equalToConstant: 22),
self.closeBackground.widthAnchor.constraint(equalToConstant: 20),
self.closeBackground.heightAnchor.constraint(equalToConstant: 20),
self.closeButton.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -9),
self.closeButton.topAnchor.constraint(equalTo: self.topAnchor, constant: 9),
self.closeButton.widthAnchor.constraint(equalToConstant: 18),
self.closeButton.heightAnchor.constraint(equalToConstant: 18),
self.closeButton.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -8),
self.closeButton.topAnchor.constraint(equalTo: self.topAnchor, constant: 8),
self.closeButton.widthAnchor.constraint(equalToConstant: 16),
self.closeButton.heightAnchor.constraint(equalToConstant: 16),
self.resizeHandle.trailingAnchor.constraint(equalTo: self.trailingAnchor),
self.resizeHandle.bottomAnchor.constraint(equalTo: self.bottomAnchor),

View File

@@ -94,7 +94,29 @@ actor GatewayConnection {
guard let client else {
throw NSError(domain: "Gateway", code: 0, userInfo: [NSLocalizedDescriptionKey: "gateway not configured"])
}
return try await client.request(method: method, params: params, timeoutMs: timeoutMs)
do {
return try await client.request(method: method, params: params, timeoutMs: timeoutMs)
} catch {
// Auto-recover in local mode by spawning/attaching a gateway and retrying a few times.
// Canvas interactions should "just work" even if the local gateway isn't running yet.
let isLocal = await MainActor.run { AppStateStore.shared.connectionMode == .local }
guard isLocal else { throw error }
await MainActor.run { GatewayProcessManager.shared.setActive(true) }
var lastError: Error = error
for delayMs in [150, 400, 900] {
try await Task.sleep(nanoseconds: UInt64(delayMs) * 1_000_000)
do {
return try await client.request(method: method, params: params, timeoutMs: timeoutMs)
} catch {
lastError = error
}
}
throw lastError
}
}
func requestRaw(

View File

@@ -0,0 +1,19 @@
# Canvas / A2UI
## Goal
- A2UI rendering works out-of-the-box (no per-user toggles).
- A2UI button clicks always reach the agent automatically.
- Canvas chrome (close button) stays readable on any content.
## Current behavior
- Canvas can show a bundled A2UI shell at `/__clawdis__/a2ui/` when no session `index.html` exists.
- The A2UI shell forwards `a2ui.action` button clicks to native via `WKScriptMessageHandler` (`clawdisCanvasA2UIAction`).
- Native forwards the click to the gateway as an agent invocation.
## Fixes (2025-12-17)
- Close button: render a small vibrancy/material pill behind the “x” and reduce the button size for less visual weight.
- Click reliability: `GatewayConnection` auto-starts the local gateway (and retries briefly) when a request fails in `.local` mode, so Canvas actions dont silently fail if the gateway isnt running yet.
## Follow-ups
- Add a small “action sent / failed” debug overlay in the A2UI shell (dev-only) to make failures obvious.
- Decide whether non-local Canvas content should ever be allowed to emit A2UI actions (current stance: no, for safety).