3.5 KiB
summary, read_when
| summary | read_when | |||
|---|---|---|---|---|
| Refactor: host A2UI from the Gateway (HTTP), remove app-bundled shells |
|
Canvas / A2UI — HTTP-hosted from Gateway
Status: Implemented · Date: 2025-12-20
Goal
- Make the Gateway (TypeScript) the single owner of A2UI.
- Remove app-bundled A2UI shells (macOS, iOS, Android).
- A2UI renders only when the Gateway is reachable (acceptable failure mode).
Decision
All A2UI HTML/JS assets are served by the Gateway HTTP server (single port, same as the Gateway WebSocket). Nodes (mac/iOS/Android) navigate to the Gateway URL before applying A2UI messages. No local custom-scheme or bundled fallback remains.
Why
- One source of truth (TS) for A2UI rendering.
- Faster iteration (no app release required for A2UI updates).
- iOS/Android/macOS all behave identically.
New behavior (summary)
canvas.a2ui.*on any node:- Ensure Canvas is visible.
- Navigate the node WebView to the Gateway A2UI URL.
- Apply/reset A2UI messages once the page is ready.
- If Gateway is unreachable:
- A2UI fails with an explicit error (no fallback).
Gateway changes
Serve A2UI assets
Add A2UI HTML/JS to the Gateway Canvas host (same HTTP server as the Gateway WS), e.g.:
/__clawdis__/a2ui/ -> index.html
/__clawdis__/a2ui/a2ui.bundle.js -> bundled A2UI runtime
Serve Canvas files at /__clawdis__/canvas/ and A2UI at /__clawdis__/a2ui/.
Use the shared Canvas host handler (src/canvas-host/server.ts) to serve these
assets and inject the action bridge + live reload if desired.
Derive HTTP host from WebSocket
Nodes derive the Canvas host URL from the Gateway WS URL:
ws://host:port -> http://host:port
wss://host:port -> https://host:port
The Gateway exposes a canonical canvasHostUrl in hello/bridge payloads
so nodes don’t need to guess.
Node changes (mac/iOS/Android)
Navigation path
Before applying A2UI:
- Navigate to
${canvasHostUrl}/__clawdis__/a2ui/.
Remove bundled shells
Remove all fallback logic that serves A2UI from local bundles:
- macOS: remove custom-scheme fallback for
/__clawdis__/a2ui/ - iOS/Android: remove packaged A2UI assets and "default scaffold" assumptions
Error behavior
If canvasHostUrl is missing or unreachable:
canvas.a2ui.push/resetreturns a clear error:A2UI_HOST_UNAVAILABLEorA2UI_HOST_NOT_CONFIGURED
Security / transport
- For non-TLS Gateway URLs (http), iOS/Android will need ATS exceptions.
- For TLS (https), prefer WSS + HTTPS with a valid cert.
Implementation plan
- Gateway
- Add A2UI assets under
src/canvas-host/. - Serve them at
/__clawdis__/a2ui/(align with existing naming). - Serve Canvas files at
/__clawdis__/canvas/on the Gateway port. - Expose
canvasHostUrlin handshake + bridge hello payloads.
- Add A2UI assets under
- Node runtimes
- Update
canvas.a2ui.*to navigate tocanvasHostUrl. - Remove custom-scheme A2UI fallback and bundled assets.
- Update
- Tests
- TS: verify
/__clawdis__/a2ui/responds with HTML + JS. - Node: verify A2UI fails when host is unreachable and succeeds when reachable.
- TS: verify
- Docs
- Update
docs/mac/canvas.md,docs/ios/spec.md,docs/android/connect.mdto remove local fallback assumptions and point to gateway-hosted A2UI.
- Update
Notes
- iOS/Android may still require ATS exceptions for
http://canvas hosts.