Control UI (browser)
The Control UI is a small Vite + Lit single-page app served by the Gateway:- default:
http://<host>:18789/ - optional prefix: set
gateway.controlUi.basePath(e.g./clawdia)
Quick open (local)
If the Gateway is running on the same computer, open: If the page fails to load, start the Gateway first:clawdia gateway.
Auth is supplied during the WebSocket handshake via:
connect.params.auth.tokenconnect.params.auth.passwordThe dashboard settings panel lets you store a token; passwords are not persisted. The onboarding wizard generates a gateway token by default, so paste it here on first connect.
What it can do (today)
- Chat with the model via Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - Stream tool calls + live tool output cards in Chat (agent events)
- Channels: WhatsApp/Telegram/Discord/Slack + plugin channels (Mattermost, etc.) status + QR login + per-channel config (
channels.status,web.login.*,config.patch) - Instances: presence list + refresh (
system-presence) - Sessions: list + per-session thinking/verbose overrides (
sessions.list,sessions.patch) - Cron jobs: list/add/run/enable/disable + run history (
cron.*) - Skills: status, enable/disable, install, API key updates (
skills.*) - Nodes: list + caps (
node.list) - Exec approvals: edit gateway or node allowlists + ask policy for
exec host=gateway/node(exec.approvals.*) - Config: view/edit
~/.nelsonmuntz-c/clawdia.json(config.get,config.set) - Config: apply + restart with validation (
config.apply) and wake the last active session - Config writes include a base-hash guard to prevent clobbering concurrent edits
- Config schema + form rendering (
config.schema, including plugin + channel schemas); Raw JSON editor remains available - Debug: status/health/models snapshots + event log + manual RPC calls (
status,health,models.list) - Logs: live tail of gateway file logs with filter/export (
logs.tail) - Update: run a package/git update + restart (
update.run) with a restart report
Chat behavior
chat.sendis non-blocking: it acks immediately with{ runId, status: "started" }and the response streams viachatevents.- Re-sending with the same
idempotencyKeyreturns{ status: "in_flight" }while running, and{ status: "ok" }after completion. chat.injectappends an assistant note to the session transcript and broadcasts achatevent for UI-only updates (no agent run, no channel delivery).- Stop:
- Click Stop (calls
chat.abort) - Type
/stop(orstop|esc|abort|wait|exit|interrupt) to abort out-of-band chat.abortsupports{ sessionKey }(norunId) to abort all active runs for that session
- Click Stop (calls
Tailnet access (recommended)
Integrated Tailscale Serve (preferred)
Keep the Gateway on loopback and let Tailscale Serve proxy it with HTTPS:https://<magicdns>/(or your configuredgateway.controlUi.basePath)
tailscale-user-login) when gateway.auth.allowTailscale is true. Clawdia
only accepts these when the request hits loopback with Tailscale’s
x-forwarded-* headers. Set gateway.auth.allowTailscale: false (or force
gateway.auth.mode: "password") if you want to require a token/password even
for Serve traffic.
Bind to tailnet + token
http://<tailscale-ip>:18789/(or your configuredgateway.controlUi.basePath)
connect.params.auth.token).
Insecure HTTP
If you open the dashboard over plain HTTP (http://<lan-ip> or http://<tailscale-ip>),
the browser runs in a non-secure context and blocks WebCrypto. By default,
Clawdia blocks Control UI connections without device identity.
Recommended fix: use HTTPS (Tailscale Serve) or open the UI locally:
https://<magicdns>/(Serve)http://127.0.0.1:18789/(on the gateway host)
Building the UI
The Gateway serves static files fromdist/control-ui. Build them with:
ws://127.0.0.1:18789).
Debugging/testing: dev server + remote Gateway
The Control UI is static files; the WebSocket target is configurable and can be different from the HTTP origin. This is handy when you want the Vite dev server locally but the Gateway runs elsewhere.- Start the UI dev server:
pnpm ui:dev - Open a URL like:
gatewayUrlis stored in localStorage after load and removed from the URL.tokenis stored in localStorage;passwordis kept in memory only.- Use
wss://when the Gateway is behind TLS (Tailscale Serve, HTTPS proxy, etc.).
