> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Automação de Navegador (@browser)

> Controle um Chrome/Chromium local de verdade pelo DevTools Protocol — abra uma página, leia-a como texto com elementos interativos numerados, clique, digite, rode JS, tire screenshot e inspecione console + rede. O loop de verificação para trabalho web. Sem chaves, zero dependência nova.

A tool **`@browser`** controla um **Chrome/Chromium local de verdade** para que o agente possa **ver e interagir com páginas web** como uma pessoa faria: abrir uma URL, ler a página renderizada como texto, clicar e digitar em elementos, rodar JavaScript, capturar screenshots e inspecionar a atividade de **console** e **rede** da página.

É o **loop de verificação** para trabalho web — o agente constrói ou altera um frontend, então **realmente olha para ele** e o depura a partir do que a página registrou e requisitou, em vez de adivinhar pelo código-fonte.

<Info>
  O `@browser` fala o **Chrome DevTools Protocol (CDP)** diretamente sobre o cliente websocket que o ChatCLI já embarca — **zero dependência nova**, sem driver, sem runtime baixado, sem chave de API. Só precisa de um **navegador da família Chromium instalado localmente** (Google Chrome, Chromium, Brave ou Edge).
</Info>

***

## Como funciona

```text theme={"system"}
@browser open http://localhost:3000
        │
        ▼
inicia um Chrome headless (primeiro uso) — reaproveitado a sessão inteira
        │
        ▼
conecta via CDP (websocket) → navega → aguarda o load
        │
        ▼
snapshot: título, URL, elementos interativos NUMERADOS, texto visível
        │
        ▼
click [n] / type [n] "texto" → snapshot de novo → console / network p/ depurar
        │
        ▼
close (ou morre automaticamente quando o ChatCLI encerra)
```

1. **Início preguiçoso** — o primeiro `open` inicia um navegador; todo comando seguinte reaproveita essa **sessão única com estado**.
2. **CDP sobre websocket** — navegação, leitura do DOM, screenshots e captura de eventos fluem pelo websocket do DevTools. Sem Selenium/Playwright, sem binário externo.
3. **Snapshot como texto** — a página é renderizada em texto amigável ao modelo, com cada elemento interativo **marcado e numerado** para o agente endereçá-los com precisão.
4. **Captura contínua** — mensagens de console (incluindo erros) e respostas de rede são capturadas em rings limitados, então você pode perguntar "o que a página registrou?" **depois do fato**.
5. **Visível sob demanda** — o navegador é headless por padrão, mas o agente pode colocar a janela **na sua tela** com `show` (ou `open --visible`) sempre que *você* precisar agir — logar, escolher uma conta, resolver um captcha — e depois recolhê-la com `hide`. A troca reinicia o navegador **no mesmo perfil**, então cookies e logins sobrevivem a ela.
6. **Morre com a sessão** — um navegador iniciado pelo ChatCLI nunca sobrevive a ele; é fechado no encerramento do CLI (ou explicitamente com `close`).

***

## Subcomandos

Invoque com um envelope JSON `{cmd, args}` ou a forma argv plana. O modelo chama `@browser` automaticamente em `/agent` e `/coder` quando precisa olhar uma página.

| Subcomando | O que faz | Args principais |
| :- | :- | :- |
| `open` | Navega para uma URL (inicia o navegador no primeiro uso) e retorna um **snapshot da página** | `url` (obr.), `--visible` |
| `show` | Torna a janela **visível na sua tela** (reinicia uma sessão headless no mesmo perfil — logins mantidos); opcionalmente navega | `url` (opcional) |
| `hide` | Volta ao headless; a janela some, a sessão e seus cookies ficam | — |
| `wait` | Bloqueia até a página chegar a um estado: URL contém, texto contém, um elemento existe e/ou a URL **muda** — a passagem de bastão depois do `show` | `--url`, `--text`, `--selector`, `--changed`, `--timeout` (120s, máx. 600s) |
| `snapshot` | A página atual como texto: título, URL, elementos interativos numerados, texto visível | `--max N` (limita o texto) |
| `click` | Clica um elemento pela sua **ref `[n]`** do último snapshot **ou** um seletor CSS | `target` (obr.) |
| `type` | Digita em um input; `--submit` pressiona Enter / envia o form | `target` (obr.), `text`, `--submit` |
| `press` | Envia uma tecla ao elemento focado: `Enter`, `Tab`, `Escape`, `ArrowDown`, um caractere ou um acorde como `Control+a` | `key` (obr.) |
| `hover` | Move o mouse sobre um elemento (abre menus de hover e tooltips) | `target` (obr.) |
| `select` | Escolhe uma opção de `<select>` por valor ou texto visível | `target` (obr.), `value` |
| `upload` | Anexa arquivo(s) local(is) a um `<input type=file>` — o seletor do SO nunca abre sob automação | `target` (obr.), `file` / `files` |
| `scroll` | Move a viewport | `down` · `up` · `top` · `bottom` · `--to target` |
| `eval` | Roda uma expressão JavaScript na página e retorna o valor | `javascript` (obr.) |
| `screenshot` | Captura a viewport — ou a **página inteira** com `--full` — como **PNG** | `--file path`, `--full` |
| `html` | O `outerHTML` de um elemento (ou do documento) para depurar markup | `target` (opcional), `--max N` |
| `pdf` | Salva a página como **PDF** (só headless) | `--file path` (opcional) |
| `resize` | Emula uma viewport (`--mobile` também liga touch) para verificar layouts responsivos | `width`, `height`, `--mobile` |
| `tabs` | Lista as abas abertas — popups como janelas de OAuth aparecem aqui | — |
| `tab` | Muda para a aba *n* da lista do `tabs` | `n` (obr.) |
| `cookies` | Lista cookies (**só nomes e domínios, nunca valores**) para checar se um login pegou; `--clear` desloga de tudo | `domain` (opcional), `--clear` |
| `console` | As mensagens de console capturadas (incluindo erros e diálogos aceitos automaticamente) | `--tail N` |
| `network` | As respostas de rede capturadas: método, status, URL | `--tail N` |
| `back` | Voltar no histórico | — |
| `status` | Se há uma sessão ativa, **visível ou headless**, que perfil usa e em que página está | — |
| `close` | Fecha a sessão do navegador | — |

***

## Refs vs. seletores CSS

Todo `snapshot` marca cada elemento interativo com um atributo `data-chatcli-ref` e retorna uma **listagem numerada**. `click` e `type` aceitam **tanto** esse número de ref `[n]` **quanto** um seletor CSS puro:

```text theme={"system"}
Elementos interativos:
  [1] link    "Docs"           → /docs
  [2] input   "Busca"          (type=search)
  [3] button  "Entrar"

@browser click 3          # pela ref (recomendado — sem adivinhar seletores)
@browser click #login-btn # por seletor CSS
```

<Note>
  As refs são estáveis **até a próxima navegação**. Depois de `open` numa nova URL ou de um `click` que dispara navegação, tire um `snapshot` novo antes de endereçar elementos por `[n]` de novo.
</Note>

***

## Deixe o usuário logar (passagem de bastão visível)

O navegador do agente nasce como um **perfil descartável**: nenhuma das sessões do seu Chrome do dia a dia existe lá. Então, quando uma tarefa esbarra numa tela de login, o agente entrega a janela a você em vez de adivinhar credenciais:

```text theme={"system"}
# O agente traz a página de login para a sua tela
@browser show https://app.example.com/login
  → Browser window is now VISIBLE on the user's screen. They can log in or
    interact directly; the session (cookies, logins) is shared with you…

# …e aguarda a página chegar à URL pós-login (até 5 minutos)
@browser wait --url /dashboard --timeout 300
  → Condition met after 42s: Dashboard (https://app.example.com/dashboard)

# A janela some; a sessão autenticada continua funcionando headless
@browser hide
@browser snapshot
```

`wait` aceita `--url`, `--text`, `--selector` e `--changed` (todas precisam valer quando combinadas). `--changed` dispara quando a URL sai da que estava no início da espera — a condição certa quando a página de destino não é previsível (o GitHub, por exemplo, ignora o `return_to` do login e cai na home). Um timeout é reportado como resultado, incluindo de onde a página saiu se ela se moveu, para o agente perguntar a você ou esperar de novo. Sem uma condição de página para esperar, o agente pergunta diretamente com [`@ask`](/pt/coder/interactive-ask). Logins feitos assim valem pelo **resto da sessão do ChatCLI**; para mantê-los entre execuções, defina `CHATCLI_BROWSER_PROFILE` (abaixo).

<Tip>
  Provedores de OAuth costumam abrir o fluxo de login em um **popup**. `tabs` o lista e `tab 2` deixa o agente controlá-lo — ou você o conclui na janela visível.
</Tip>

<Note>
  **Entrar com o Google.** O Google recusa login por senha em navegadores que detecta como automatizados ("Esse navegador ou app pode não ser seguro"). O ChatCLI inicia o Chrome com o marcador de automação desligado (`navigator.webdriver` é `false`), que é o que essa checagem olha. Se o Google ainda recusar, entre no site com senha ou passkey em vez do botão do Google, ou conecte o ChatCLI ao Chrome em que você já está logado com `CHATCLI_BROWSER_CDP_URL` (abaixo).
</Note>

Se você **fechar a aba ou a janela** enquanto o agente espera, o `wait` reporta isso em vez de falhar, e o próximo `open`/`show` anexa uma aba nova — a sessão do navegador continua rodando.

***

## Um exemplo prático

Construa uma página no `/coder`, então verifique-a de ponta a ponta:

```text theme={"system"}
# 1) Abra o app que o coder acabou de subir
@browser open http://localhost:3000
  → Page: My App — Home
    Elementos interativos:
      [1] link   "Produtos"
      [2] input  "Email"      (type=email)
      [3] button "Assinar"

# 2) Preencha o form e envie
@browser type 2 "user@example.com"
@browser click 3

# 3) Veja o que aconteceu
@browser snapshot
  → Page: My App — Obrigado!
    "Você está inscrito."

# 4) Algo estranho? Depure a partir da própria página
@browser console --tail 20
  → [error] Uncaught TypeError: cannot read 'id' of undefined (app.js:42)

@browser network --tail 10
  → 500 POST http://localhost:3000/api/subscribe (Fetch)
```

O agente agora sabe que o botão funcionou na UI mas o backend retornou **500**, e o erro exato do console — o loop completo de verificar-e-corrigir sem sair do ChatCLI.

***

## Variáveis de ambiente

| Variável | Descrição | Default |
| :- | :- | :- |
| `CHATCLI_BROWSER_BIN` | Caminho do binário do navegador a usar | auto-detecta Chrome/Chromium/Brave/Edge |
| `CHATCLI_BROWSER_HEADLESS` | Rodar headless (`true`) ou abrir uma **janela visível** (`false`) para a sessão inteira — `show`/`hide` alternam por chamada de qualquer forma | `true` |
| `CHATCLI_BROWSER_PROFILE` | Onde cookies e logins vivem. Sem valor = perfil descartável apagado ao fechar. `true` = perfil persistente do ChatCLI em `~/.chatcli/browser/profile`; um caminho = esse diretório. Nunca o perfil do seu Chrome do dia a dia | *(descartável)* |
| `CHATCLI_BROWSER_CDP_URL` | **Conecta a um navegador que você já tem aberto** em vez de iniciar um — `http://127.0.0.1:9222` (inicie o Chrome com `--remote-debugging-port=9222`) ou uma URL `ws://` do DevTools. O ChatCLI abre uma aba própria lá e fecha só essa aba ao sair; a janela é sua, então é sempre visível e nunca morta | *(inicia o próprio navegador)* |

```bash theme={"system"}
# Assistir o agente controlar uma janela de verdade a sessão inteira
export CHATCLI_BROWSER_HEADLESS=false

# Manter logins entre execuções do ChatCLI (perfil do próprio ChatCLI)
export CHATCLI_BROWSER_PROFILE=true

# Usar o Chrome em que você já está logado
# (inicie-o uma vez com: google-chrome --remote-debugging-port=9222)
export CHATCLI_BROWSER_CDP_URL=http://127.0.0.1:9222

# Apontar para um navegador específico
export CHATCLI_BROWSER_BIN="/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
```

***

## Segurança

Comandos de observação são **read-only** e pulam a confirmação — o agente pode olhar à vontade: `open`, `show`, `hide`, `wait`, `snapshot`, `screenshot`, `html`, `pdf`, `resize`, `tabs`, `tab`, `cookies` (listagem), `console`, `network`, `scroll`, `back`, `status`, `close`.

Comandos que **agem** sobre a página — `click`, `type`, `press`, `hover`, `select`, `upload`, `eval` e `cookies --clear` — podem disparar ações reais em sites remotos (ou deslogar você de tudo), então passam pelo **gate de segurança** padrão como qualquer outra tool que muta estado. Veja [Segurança do Modo Coder](/pt/coder/coder-security).

`cookies` nunca retorna os **valores** dos cookies: o agente consegue saber que existe um cookie de sessão para um domínio, mas um token nunca cai na transcrição.

<Warning>
  O `@browser` controla um navegador de verdade logado no perfil em que roda. O perfil descartável default é a escolha segura para páginas não confiáveis; um perfil persistente (`CHATCLI_BROWSER_PROFILE`) ou o seu próprio navegador (`CHATCLI_BROWSER_CDP_URL`) entrega ao agente todo login guardado ali — trate `click`/`type`/`eval` em sites externos como as operações com efeito colateral que são.
</Warning>

***

## Notas

* **Uma sessão por processo**, iniciada preguiçosamente no primeiro `open` e reaproveitada em toda chamada.
* Console e rede são capturados **continuamente** em rings limitados — `console`/`network` leem o histórico recente, não precisam ser "armados" antes.
* `screenshot` grava um PNG (default no diretório temporário, ou `--file path`). Combine com [`@view`](/pt/usage/vision-input) para o modelo **olhar o screenshot** que acabou de tirar.
* Diálogos `alert()`, `confirm()` e `prompt()` são **aceitos automaticamente** (senão congelariam a página) e registrados no `console` como entradas `[dialog]`.
* Um navegador iniciado pelo ChatCLI é **sempre** fechado no encerramento; um Chrome headless perdido nunca sobrevive à sessão. Um navegador conectado (`CHATCLI_BROWSER_CDP_URL`) só perde a aba que o ChatCLI abriu.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Entrada de Imagem (@view)" icon="eye" href="/pt/usage/vision-input">
    Anexe um screenshot que o `@browser` capturou para o modelo ver com os próprios olhos.
  </Card>

  <Card title="Plugin @coder" icon="hammer" href="/pt/coder/coder-plugin">
    Ler, escrever, aplicar patch e executar — combine com `@browser` para construir e então verificar.
  </Card>

  <Card title="Plugins Agênticos" icon="plug" href="/pt/agents/agentic-plugins">
    O catálogo completo de tools builtin e como o agente as usa.
  </Card>

  <Card title="Web Tools" icon="globe" href="/pt/tools/web-tools">
    `@webfetch`, `@websearch` e o cliente HTTP endurecido compartilhado.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.