Skip to content

feat: wire WebView2 native↔SPA bridge in CanvasWindow#259

Open
AlexAlves87 wants to merge 1 commit intoopenclaw:masterfrom
AlexAlves87:feat/canvas-bridge-parity
Open

feat: wire WebView2 native↔SPA bridge in CanvasWindow#259
AlexAlves87 wants to merge 1 commit intoopenclaw:masterfrom
AlexAlves87:feat/canvas-bridge-parity

Conversation

@AlexAlves87
Copy link
Copy Markdown
Contributor

@AlexAlves87 AlexAlves87 commented May 1, 2026

Summary

Adds the bidirectional WebView2 bridge to CanvasWindow and removes the fragile ExecuteScriptAsync heuristic paths, closing the remaining item on the #191 checklist after #192 landed the WebChatWindow half.

Native → SPA

canvasWindow.PostBridgeMessage(WebBridgeMessage.TypeRecordingStart);

SPA → native

canvasWindow.BridgeMessageReceived += (_, msg) => { /* msg.Type, msg.PayloadJson */ };

Why

The #191 checklist had one item outstanding after #192:

[ ] Add equivalent bridge surface to CanvasWindow, replacing fragile ExecuteScriptAsync message paths where appropriate

SendA2UIMessageAsync and ResetA2UIAsync used 11 and 6 heuristic fallbacks respectively (window.__a2ui, window.a2ui, window.A2UI, dispatchEvent, postMessage…) to push messages into the SPA — the exact fragile pattern the issue calls out. Both methods had no active callers; the A2UI path is now served by the native A2UICanvasWindow renderer. They are removed and the bridge is the replacement.

Trust boundary

IsTrustedBridgeSource accepts messages from exactly two origins:

  • _trustedGatewayOrigin — the gateway configured via SetTrustedGatewayOrigin
  • https://openclaw-canvas.local — the local virtual host for canvas files

Everything else is rejected with a warning log entry.

What is not changed

  • EvalAsync — untouched; it is the canvas.eval agent API, not a messaging path
  • EnsureA2UIHostAsync — untouched; uses Navigate, not the heuristic pattern
  • NodeService — no changes
  • A2UICanvasWindow — not touched

Tests

Source-scan added in TrayMenuWindowMarkupTests asserting presence of BridgeMessageReceived, IsTrustedBridgeSource, openclaw-canvas.local, dispatcher marshaling, PostWebMessageAsJson, SanitizeBridgeLogValue, and WebMessageReceived cleanup in OnWindowClosed.

Validation

build.ps1 ✅ — OpenClaw.Shared.Tests 1100/1100 ✅ — OpenClaw.Tray.Tests 407/407 ✅

@AlexAlves87 AlexAlves87 force-pushed the feat/canvas-bridge-parity branch from 85c44b9 to aa449d2 Compare May 2, 2026 01:46
@AlexAlves87
Copy link
Copy Markdown
Contributor Author

The failing test (LocalCommandRunnerIntegrationTests.Run_WithEnvVars) doesn't seem to be exercised by this PR, as no changes touch LocalCommandRunner or env var handling.

I noticed a recent run on 0f54bc1 showing a different integration test failing in the same pattern, which suggests this might be intermittent CI flakiness rather than a regression.

Happy to trigger a re-run if that would help move this forward!

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

🤖 This is an automated response from Repo Assist.

The CI test failure here is not caused by this PR's changes. The failing test is:

LocalCommandRunnerIntegrationTests.Run_WithEnvVars [10 s] — exit code expected 0, got -1

This is a [IntegrationFact] that runs a real PowerShell process (Write-Output $env:TEST_OPENCLAW_VAR) with a 10 s timeout. Exit code -1 is the timeout sentinel — the process was killed rather than completing normally. This is a pre-existing flaky integration test and is unrelated to the CanvasWindow bridge changes in this PR.

The PR's own validation reports Shared.Tests 1100/1100 ✅ and Tray.Tests 407/407 ✅, which is consistent with a clean infrastructure-only failure in CI.

Generated by 🌈 Repo Assist, see workflow run.

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

Adds BridgeMessageReceived + PostBridgeMessage to CanvasWindow following
the same pattern as WebChatWindow (c7630fa), closing the CanvasWindow
item on the openclaw#191 checklist. Removes SendA2UIMessageAsync, ResetA2UIAsync,
and their heuristic ExecuteScriptAsync helpers; both had no active callers
and are replaced by the bridge. IsTrustedBridgeSource accepts only
_trustedGatewayOrigin and openclaw-canvas.local. Source-scan test added
in TrayMenuWindowMarkupTests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexAlves87 AlexAlves87 force-pushed the feat/canvas-bridge-parity branch from aa449d2 to 85a5c3f Compare May 6, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant