Control UI (Canvas)
One-line summary
The Control UI is a Lit-based single-page web application that provides a real-time operator dashboard for managing agents, sessions, channels, skills, cron jobs, and chat — all over a single WebSocket connection to the Gateway.
Responsibilities
- Provide a browser-based control panel for all Gateway operations (chat, config, channels, agents, sessions, usage, cron, skills, debug, logs)
- Maintain a persistent WebSocket connection with Ed25519 device authentication and automatic reconnection
- Render real-time streaming chat with Markdown, tool use indicators, and file attachments
- Offer a dynamic config editor driven by the server-side Zod schema
- Support internationalization (en, pt-BR, zh-CN, zh-TW) and mobile-responsive layout
Architecture diagram
Key source files
Data flow
WebSocket protocol
All communication uses a single WebSocket connection with three message types:
Authentication handshake
Key RPC methods
Event types (Server → Client)
Page structure
4 tab groups, 13 tabs total:
Technology stack
State management
No external state library. Uses Lit's built-in reactive system:
- 100+ reactive properties on
OpenClawApp— single source of truth - Views are pure functions that receive
AppViewStateand returnTemplateResult - Controllers handle user actions, call Gateway RPC, and update
@state()properties - LocalStorage persists theme, selected tab, and device settings
- IndexedDB stores Ed25519 device identity (persistent across sessions)
Reconnection strategy
How it connects to other modules
-
Depends on:
gateway/— WebSocket server hosts the Control UI and handles all RPC methods- Gateway serves the built
dist/control-ui/files on port18789+1
-
Depended by:
- None — the Control UI is a leaf node, purely a client
Build and deployment
The Gateway auto-discovers and serves the built Control UI — no separate deployment needed.
My blind spots
- Exact WebSocket message types for all 13 tabs — I've documented the main ones but each tab likely has additional RPC methods
- How the dynamic config form in
config.ts(820 lines) maps server-side Zod schema to form fields — need to trace the full schema → form pipeline - Whether the event sequence gap detection triggers a full reload or a selective resync
- How
exec-approval.tsworks — the operator approval flow for tool execution - Canvas A2UI integration details — how the WebView-based canvas protocol works from the UI side
Change frequency
app.ts: Medium — new state properties added as features shipgateway.ts: Low — WebSocket protocol is stableapp-render.ts: Medium — layout changes and new tab additionsviews/: High — individual views change as features evolvecontrollers/: High — business logic tied to feature development