Skip to content

[Repo Assist] feat: wire WebView2 bidirectional native↔SPA bridge in WebChatWindow#192

Draft
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/feat-webchat-webview2-bridge-2026-04-21-f5724c21afd19b9c
Draft

[Repo Assist] feat: wire WebView2 bidirectional native↔SPA bridge in WebChatWindow#192
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/feat-webchat-webview2-bridge-2026-04-21-f5724c21afd19b9c

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This is an automated PR from Repo Assist.

Implements the Windows side of the WebView2 bridge proposed in issue #191.

What changed

OpenClaw.SharedWebBridgeMessage

New WebBridgeMessage record defining the bridge message contract:

{ "type": "...", "payload": { ... } }

WebChatWindow.xaml.cs

SPA → native (incoming messages):

// Subscribe in InitializeWebViewAsync, unsubscribed in OnWindowClosed
WebView.CoreWebView2.WebMessageReceived += _webMessageReceivedHandler;
// Callers subscribe to:
public event EventHandler<WebBridgeMessage>? BridgeMessageReceived;

The SPA sends via window.chrome.webview.postMessage({ type, payload })window.chrome.webview is automatically available in WebView2-hosted pages.

Native → SPA (outgoing messages):

public void PostBridgeMessage(string type, object? payload = null)

The SPA receives via window.chrome.webview.addEventListener('message', e => { const msg = e.data; ... }).

Handler is stored in _webMessageReceivedHandler and unregistered in OnWindowClosed — no event-handler leak.

Why this matters

From issue #191 — three open PRs need this infrastructure:

PR / Feature What it unlocks
#120 Voice Mode (NichUK) Replace fragile DOM scraping with voice-start/voice-stop bridge messages
#159 Screen recording (AlexAlves87) Show recording indicator in SPA via recording-start/recording-stop
Future Push draft text to chat input via draft-text bridge message

What's NOT in scope

  • Gateway/SPA side: adding window.chrome.webview.addEventListener in the gateway SPA (tracked in [Proposal] Add a formal WebView2 bridge for native ↔ SPA communication #191 as a separate repo concern)
  • CanvasWindow: already has ExecuteScriptAsync channel; bridge upgrade can be a separate PR
  • NodeService wiring: posting recording-start from ScreenCapability is a follow-on once the SPA side is ready

Test Status

  • dotnet test OpenClaw.Shared.Tests648 passed, 20 skipped (↑15 from 633; 15 new WebBridgeMessageTests)
  • dotnet test OpenClaw.Tray.Tests — 122 passed (unchanged)

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

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

Implements the WebView2 bridge proposed in issue #191.

## Changes

### OpenClaw.Shared — WebBridgeMessage
- New `WebBridgeMessage` record: wire format `{"type":"...","payload":{...}}`
- Well-known type constants: recording-start/stop, voice-start/stop, draft-text, ready
- `TryParse(string?)` — null-safe parser, returns null on malformed input
- `ToJson(object?)` — serialiser, optional runtime payload overrides stored one

### WebChatWindow.xaml.cs
- Subscribe `CoreWebView2.WebMessageReceived` → fire `BridgeMessageReceived` event
  (SPA sends via `window.chrome.webview.postMessage({type, payload})`)
- Add `PostBridgeMessage(string type, object? payload = null)` for native→SPA
  (SPA receives via `window.chrome.webview.addEventListener('message', ...)`)
- Handler stored and unregistered in `OnWindowClosed` (no leak)
- Uses existing `using OpenClaw.Shared;` import — no new dependencies

### Tests (+15)
- `WebBridgeMessageTests`: parse valid/invalid/edge cases; ToJson; round-trip for
  all well-known types; payload override

## Test Status
- `dotnet test OpenClaw.Shared.Tests` — **648 passed, 20 skipped** (↑15 from 633)
- `dotnet test OpenClaw.Tray.Tests` — 122 passed (unchanged)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AlexAlves87
Copy link
Copy Markdown
Contributor

Thanks for picking up the Windows host side of the bridge from #191.

I opened the matching SPA-side draft PR here: openclaw/openclaw#69633

That PR adds the window.chrome.webview listener/ready-handshake layer on the frontend side, so both halves of the bridge can be reviewed together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant