/web abre o ChatCLI no seu navegador, ao lado do terminal, na mesma sessão. O que você escreve no navegador continua no terminal, no MCP, no ACP e nos seus canais, e vice-versa, porque o navegador aciona exatamente o mesmo motor e as mesmas sessões salvas que as outras superfícies acionam. chatcli web a serve sem terminal.
É local por construção: o servidor escuta na interface de loopback numa porta livre, cada execução cria o próprio token, o token viaja num header que a página lê do endereço uma vez, e nada sai da sua máquina.

Um passeio pela página: o painel com status, o catálogo de tools com filtro, skills e comandos; / e @ abrem paletas no compositor; as abas de modo; o tema claro. (Dados sintéticos.)
Abrindo
/web funciona no meio de um turno, como o /dash. Um terminal que não está vinculado a uma sessão salva é vinculado a uma nova antes (web-<data>), para a conversa ter um nome que as duas superfícies acompanhem; um terminal já vinculado compartilha a sessão como está. O navegador abre exatamente com o que essa sessão tem: rode /web no meio de uma conversa e a página começa com esses turnos e sincroniza dali; rode num terminal que ainda não digitou nada e a página começa vazia. Ela nunca é preenchida com o espelho rolling mcp-web de uma execução anterior. Fechar o terminal encerra a web UI: o endereço carregava um token que só aquele processo entregou.
chatcli web sozinho faz o mesmo: sem --session ele vincula o navegador a uma sessão web-<data> nova, criada no primeiro turno concluído, então cada execução avulsa guarda a própria conversa em vez de sobrescrever o espelho rolling mcp-web. Nada é salvo “no fim”: cada turno concluído é gravado assim que termina, então Ctrl+C ou fechar a aba perde no máximo um turno que ainda estava em streaming. Um terminal vinculado a uma sessão nomeada, inclusive a web-<data> que o /web cria, é gravado uma última vez na saída e não é duplicado como arquivo autosave-.
O navegador só abre a partir de um terminal interativo.
chatcli web --no-browser, ou um pipe, imprime o endereço.Continuidade entre superfícies
A web UI não é um segundo motor. Ela roda sobre o backend RPC compartilhado em que o servidor MCP, o servidor ACP e o chat gateway rodam, e mantém a sessão do mesmo jeito:- o histórico ao vivo do navegador é vinculado a uma sessão salva e gravado após cada turno;
- antes de cada turno a sessão vinculada é relida quando outra superfície a mudou (o terminal, uma IDE por ACP, uma conversa de WhatsApp ou Telegram pelo gateway), então uma resposta dada em outro lugar já está na transcrição antes de você continuar;
- a thread do Conversation Hub do principal é retomada, exatamente como o
chatcli mcp-serverfaz.
web-<data> própria (o arquivo aparece no primeiro turno), então a conversa nova é salva e listada como qualquer outra; o terminal segue na sessão que tinha, e o cabeçalho mostra a sessão à qual a página está vinculada. Apagar é o mesmo /session delete que o terminal executa.
O que você vê
Modos e permissões
Turnos de chat transmitem token a token pelo caminho de streaming do provider. Turnos de coder e agent transmitem os eventos estruturados do loop: raciocínios, mensagens, cada chamada de tool ao começar e terminar, e o plano. Quando um loop chega a uma ação sob política (uma regraask, um comando perigoso), a página mostra o mesmo diálogo de permissão que a IDE recebe por ACP: permitir uma vez, permitir sempre, negar, negar sempre. Sem resposta dentro do timeout (CHATCLI_MCP_PERMISSION_TIMEOUT, padrão 10 minutos) a ação é negada uma vez, então um navegador abandonado nunca deixa um loop pendurado.
Um turno de cada vez, como no terminal: enquanto um turno roda, enviar outro é recusado com um aviso claro em vez de enfileirar em silêncio. Fechar a aba cancela a execução.
Provider e modelo
Os seletores mostram o que o motor alcança: providers com credenciais e, por provider, os modelos que o catálogo conhece mais o que a API do provider lista ao vivo. Escolher um define a rota dos turnos seguintes, sem mexer na seleção do terminal. Skills que fixam um modelo continuam vencendo nos turnos em que disparam.Mídia
Recursos não configurados ficam escondidos, não quebrados.
A API por trás da página
A página fala com uma pequena API JSON na mesma origem. Está documentada aqui porque um script pode acioná-la tão bem quanto a página, com o token do endereço:
Toda chamada carrega
X-Web-Token: <token>; o token nunca é aceito pela query, o Host precisa bater exatamente com o endereço vinculado (guarda contra DNS rebinding), e a página traz uma Content-Security-Policy estrita que não permite recurso externo algum.
Privacidade e segurança
- Só loopback. Um pedido para escutar em outra interface é recusado.
- Um token por execução, 128 bits, em memória. Pare o processo e o endereço morre.
- A web UI roda o motor desassistido como MCP e ACP: comandos perigosos seguem
CHATCLI_MCP_DANGER(blockos transforma em recusas em linha) e o diálogo de permissão cobre as regrasask./policyno terminal muda as regras para os dois. - A página é um único arquivo embutido. Sem CDN, sem fontes, sem analytics, funciona offline.
Configuração
/config web mostra se a web UI está rodando, o endereço, o processo filho, a sessão vinculada e o arquivo de log (~/.chatcli/web.log).
Relação com as outras superfícies
Dashboard ao vivo
O que cada processo está fazendo, como um grafo ao vivo. Abra do terminal da web UI com
/dash: a web UI aparece como janela própria web, com seus turnos, chamadas de modelo, tools e skills.Continuidade de sessão
Como uma sessão salva acompanha você pelo terminal, IDEs e canais.