UI de Controle (navegador)
A UI de Controle é um pequeno app de página única Vite + Lit servido pelo Gateway:- padrão:
http://<host>:18789/ - prefixo opcional: defina
gateway.controlUi.basePath(ex.:/openclaw)
Abertura rápida (local)
Se o Gateway estiver em execução no mesmo computador, abra: Se a página não carregar, inicie o Gateway primeiro:openclaw gateway.
A autenticação é fornecida durante o handshake do WebSocket via:
connect.params.auth.tokenconnect.params.auth.passwordO painel de configurações do dashboard permite armazenar um token; senhas não são persistidas. O assistente de onboarding gera um token do gateway por padrão, então cole-o aqui na primeira conexão.
Pareamento de dispositivo (primeira conexão)
Quando você se conecta à UI de Controle a partir de um novo navegador ou dispositivo, o Gateway exige uma aprovação de pareamento única — mesmo se você estiver na mesma Tailnet comgateway.auth.allowTailscale: true. Isso é uma medida de segurança para evitar
acesso não autorizado.
O que você verá: “disconnected (1008): pairing required”
Para aprovar o dispositivo:
openclaw devices revoke --device <id> --role <role>. Veja
Devices CLI para rotação e revogação de tokens.
Notas:
- Conexões locais (
127.0.0.1) são aprovadas automaticamente. - Conexões remotas (LAN, Tailnet, etc.) exigem aprovação explícita.
- Cada perfil de navegador gera um ID de dispositivo único; portanto, trocar de navegador ou limpar os dados do navegador exigirá novo pareamento.
O que ela pode fazer (hoje)
- Conversar com o modelo via Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - Fazer streaming de chamadas de ferramentas + cartões de saída de ferramentas ao vivo no Chat (eventos do agente)
- Canais: status do WhatsApp/Telegram/Discord/Slack + canais de plugin (Mattermost, etc.) + login por QR + configuração por canal (
channels.status,web.login.*,config.patch) - Instâncias: lista de presença + atualização (
system-presence) - Sessões: lista + substituições de thinking/verbose por sessão (
sessions.list,sessions.patch) - Cron jobs: listar/adicionar/executar/habilitar/desabilitar + histórico de execuções (
cron.*) - Skills: status, habilitar/desabilitar, instalar, atualizações de chave de API (
skills.*) - Nós: lista + capacidades (
node.list) - Aprovações de exec: editar allowlists do gateway ou do nó + política de solicitação para
exec host=gateway/node(exec.approvals.*) - Configuração: visualizar/editar
~/.openclaw/openclaw.json(config.get,config.set) - Configuração: aplicar + reiniciar com validação (
config.apply) e acordar a última sessão ativa - Gravações de configuração incluem um guard de hash base para evitar sobrescrever edições concorrentes
- Esquema de configuração + renderização de formulários (
config.schema, incluindo esquemas de plugin + canal); o editor Raw JSON permanece disponível - Debug: snapshots de status/saúde/modelos + log de eventos + chamadas RPC manuais (
status,health,models.list) - Logs: tail ao vivo dos logs de arquivo do gateway com filtro/exportação (
logs.tail) - Atualização: executar uma atualização de pacote/git + reiniciar (
update.run) com um relatório de reinicialização
- Para jobs isolados, a entrega padrão é anunciar um resumo. Você pode alternar para nenhum se quiser execuções apenas internas.
- Os campos de canal/alvo aparecem quando anunciar é selecionado.
Comportamento do chat
chat.sendé não bloqueante: confirma imediatamente com{ runId, status: "started" }e a resposta é transmitida via eventoschat.- Reenviar com o mesmo
idempotencyKeyretorna{ status: "in_flight" }enquanto estiver em execução, e{ status: "ok" }após a conclusão. chat.injectadiciona uma nota do assistente ao transcript da sessão e transmite um eventochatapenas para atualizações de UI (sem execução do agente, sem entrega em canal).- Stop:
- Clique em Stop (chama
chat.abort) - Digite
/stop(oustop|esc|abort|wait|exit|interrupt) para abortar fora de banda chat.abortoferece suporte a{ sessionKey }(semrunId) para abortar todas as execuções ativas daquela sessão
- Clique em Stop (chama
Acesso via Tailnet (recomendado)
Tailscale Serve integrado (preferido)
Mantenha o Gateway em loopback e deixe o Tailscale Serve fazer o proxy com HTTPS:https://<magicdns>/(ou seugateway.controlUi.basePathconfigurado)
tailscale-user-login) quando gateway.auth.allowTailscale está true. O OpenClaw
verifica a identidade resolvendo o endereço x-forwarded-for com
tailscale whois e comparando com o cabeçalho, e só aceita isso quando a
requisição atinge o loopback com os cabeçalhos x-forwarded-* do Tailscale. Defina
gateway.auth.allowTailscale: false (ou force gateway.auth.mode: "password")
se você quiser exigir token/senha mesmo para tráfego do Serve.
Vincular à tailnet + token
http://<tailscale-ip>:18789/(ou seugateway.controlUi.basePathconfigurado)
connect.params.auth.token).
HTTP inseguro
Se você abrir o dashboard via HTTP simples (http://<lan-ip> ou http://<tailscale-ip>),
o navegador roda em um contexto não seguro e bloqueia o WebCrypto. Por padrão,
o OpenClaw bloqueia conexões da UI de Controle sem identidade do dispositivo.
Correção recomendada: use HTTPS (Tailscale Serve) ou abra a UI localmente:
https://<magicdns>/(Serve)http://127.0.0.1:18789/(no host do gateway)
Construindo a UI
O Gateway serve arquivos estáticos a partir dedist/control-ui. Compile-os com:
ws://127.0.0.1:18789).
Depuração/testes: servidor de dev + Gateway remoto
A UI de Controle é composta por arquivos estáticos; o destino do WebSocket é configurável e pode ser diferente da origem HTTP. Isso é útil quando você quer o servidor de dev do Vite localmente, mas o Gateway roda em outro lugar.- Inicie o servidor de dev da UI:
pnpm ui:dev - Abra uma URL como:
gatewayUrlé armazenado no localStorage após o carregamento e removido da URL.tokené armazenado no localStorage;passwordé mantido apenas na memória.- Quando
gatewayUrlestá definido, a UI não faz fallback para credenciais de configuração ou de ambiente. Forneçatoken(oupassword) explicitamente. A ausência de credenciais explícitas é um erro. - Use
wss://quando o Gateway estiver atrás de TLS (Tailscale Serve, proxy HTTPS, etc.). gatewayUrlsó é aceito em uma janela de nível superior (não incorporada) para evitar clickjacking.- Para configurações de dev com cross-origin (ex.:
pnpm ui:devpara um Gateway remoto), adicione a origem da UI agateway.controlUi.allowedOrigins.