Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
kuri — Automação de navegador, rastreamento web e controle de dispositivos iOS + Android para agentes de IA. Snapshots de CDP nativos em Zig e eficientes em tokens, gravação de HAR, cliente nativo do protocolo de rede adb e um fetcher independente. | Kitploit
Ferramentas/GitHubGitHub/justrach/kuri
Coleta de InformaçõesSegurança WebTestes de PenetraçãoSegurança MóvelRastreador
GitHubjustrach/kuri

kuri

Automação de navegador, rastreamento web e controle de dispositivos iOS + Android para agentes de IA. Snapshots de CDP nativos em Zig e eficientes em tokens, gravação de HAR, cliente nativo do protocolo de rede adb e um fetcher independente.

Ver Repositório
3501844há 11 diasRevisado pelo Kitploit
Site

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
<p align="center">
  <img src="https://assets.kitploit.com/production/public/readmes/13639/7915bba5fb25229c11f59482cfcd4a0eaf2945ee066dbf5cec395df880b53268.png" alt="Kuri" width="200" />
</p>

<h1 align="center">Kuri 🌰</h1>

<p align="center">
  <a href="https://kuri.trilok.ai/download/latest.json"><img src="https://img.shields.io/badge/stable-v0.6.1-brightgreen?style=flat-square" alt="Stable release"></a>
  <a href="https://github.com/justrach/kuri/blob/main/LICENSE"><img src="https://img.shields.io/github/license/justrach/kuri?style=flat-square" alt="License"></a>
  <img src="https://img.shields.io/badge/zig-0.16.0-f7a41d?style=flat-square" alt="Zig">
  <img src="https://img.shields.io/badge/node__modules-0_files-brightgreen?style=flat-square" alt="node_modules">
  <img src="https://img.shields.io/badge/status-stable-brightgreen?style=flat-square" alt="status">
</p>

## Instalação

```sh
curl -fsSL https://kuri.trilok.ai/download | sh
```

macOS arm64/x86_64 e Linux x86_64/arm64. Binário único, sem dependências de runtime.

Downloads diretos: [macOS arm64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-aarch64-macos.tar.gz) · [macOS x86_64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-x86_64-macos.tar.gz) · [Linux x86_64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-x86_64-linux.tar.gz) · [Linux arm64](https://kuri.trilok.ai/download/v0.6.1/kuri-v0.6.1-aarch64-linux.tar.gz)

---

**Automação de navegador e web crawling para agentes de IA. Escrito em Zig. Zero Node.js.**

Automação CDP · Snapshots A11y · Gravação HAR · Fetcher autônomo · Navegador de terminal interativo · CLI agêntica · Testes de segurança · Controle de dispositivos iOS + Android

[Início Rápido](#-quick-start) · [Benchmarks](#-benchmarks) · [kuri-agent](#-kuri-agent) · [Testes de Segurança](#-security-testing) · [API](#-http-api) · [Skills](#-skills) · [Changelog](https://github.com/justrach/kuri/blob/main/CHANGELOG.md)

> **Por que as equipes migram para o Kuri:** as builds atuais `ReleaseFast` para Apple Silicon permanecem abaixo de 2 MB por binário, e uma nova execução do Google Flights em 2026-04-23 mediu **3.392 tokens** para um ciclo completo do `kuri-agent` (`go→snap→click→snap→eval`). Deltas entre ferramentas devem ser reexecutados no mesmo ambiente antes de citar uma porcentagem.

---

## Por que o Kuri Vence para Agentes

A maioria das ferramentas de navegador foi criada para engenheiros de QA. O Kuri foi criado para ciclos de agentes: ler a página, manter o custo de tokens baixo, agir sobre refs estáveis e seguir em frente.

- **135 endpoints HTTP** — paridade total com agent-browser e browser-use, da inspeção React aos Core Web Vitals.
- **7-12% menos tokens** que o agent-browser em páginas reais graças ao formato de ref `@eN` e renderização sem prefixo.
- **Observações 44x mais leves** com `/page/state` (48 tokens) vs snapshot completo (2.124 tokens) para a mesma página do Google Flights.
- **Execução em lote** — `POST /batch` envia N comandos em uma única chamada HTTP, eliminando N-1 round-trips e N-1 turnos do LLM.
- **Compatível com React** — eventos de mouse CDP confiáveis e eventos de tecla por caractere disparam `onClick` e `onChange` do React 18/19.

### Tokens de snapshot: Google Flights `SIN → TPE`

Nova execução em 2026-05-24 neste workspace, medida com `wc -c` e aproximação `chars/4`.

| Ferramenta / Modo | Chars | ~Tokens | Nota |
|---|---:|---:|---|
| `kuri snap` (completo) | 8.499 | **2.124** | Todos os nós + refs interativas |
| `kuri snap` (somente interativo) | ~3.000 | **~750** | Melhor para ciclos de agentes |
| `kuri /page/state` | 190 | **48** | Observação leve (url, title, scroll%, contagens) |
| agent-browser snap (estimado) | ~9.183 | **~2.295** | Overhead do formato `[ref=e0]` |

### Eficiência de tokens: kuri vs agent-browser

| Página | tokens kuri | tokens agent-browser | Economia |
|---|---:|---:|---|
| example.com | 40 | 35 | -13% (página trivial, agent-browser pula a raiz) |
| Hacker News | 386 | ~440 | **12% menos** |
| Google Flights SIN→TPE | 2.124 | ~2.295 | **7% menos** |

A economia vem do formato compacto do kuri:
- refs `@e0` (3 chars) vs `[ref=e0]` (9 chars)
- Sem prefixo `- ` por linha (economiza 2 chars × número de linhas)
- Mesma indentação, mesma filtragem de nós

### Custo do fluxo completo: `go → snap → click → snap → eval`

| Ferramenta | Tokens por ciclo |
|---|---:|
| **kuri-agent** | **~3.400** |
| Com `/page/state` em vez do segundo snap | **~1.700** |
| Com `POST /batch` (tudo em uma chamada) | **~1.700** (mesmos tokens, 1 chamada HTTP em vez de 5) |

### kuri vs libretto

[libretto](https://github.com/saffron-health/libretto) (Playwright + Node) é o concorrente mais próximo em custo de tokens por passo. Medido frente a frente em 2026-07-04 — mesmo Chrome, mesma aba, contagens reais de `tiktoken` `o200k_base` (metodologia completa e reprodução: **[benchmarks/libretto_comparison.md](https://github.com/justrach/kuri/blob/main/benchmarks/libretto_comparison.md)**). A divisão honesta:

| Eixo | Vencedor | Detalhe |
|---|---|---|
| Latência por chamada | **kuri** | 4–117 ms vs 1.344–1.500 ms (**13–376× mais rápido** — servidor persistente vs Node-por-comando) |
| Tokens de snapshot, página típica | **kuri** | simples 61 vs 151 (2,5×), artigo 265 vs 363 (1,37×) — gramática mais enxuta |
| Tokens de snapshot, lista grande | dividido | kuri padrão 4.424 vs 813 — kuri emite todas as 259 refs, libretto trunca por padrão. Com `limit=5` kuri renderiza 555 tokens (**1,46× abaixo do libretto**), 34 refs + marcadores `… +45 more` |
| Trajetória (feed, 9 cliques) | **kuri**, por pouco | 898 vs 939 tokens (base `limit=5` + loop de diff vs loop exec) — paridade a leve vantagem; a perda de 5,1× da manhã era a base não truncada |
| Execuções repetidas | **libretto** | compila trajetórias para um script Playwright → replays de 0 token; kuri repaga o loop a cada execução |

**O que o kuri ganhou ao estudar o libretto** (tudo lançado nesta versão): um loop diff-first (`take_snapshot_diff`, ~38 tokens/passo); um diff adaptativo que recorre a um snapshot completo com cabeçalho `! page replaced` na navegação; linhas de remoção apenas de identidade; screenshots gravados em disco (caminho retornado, bytes nunca entram no contexto); `get_page_state` via MCP; e — após reescrever `parseA11yNodes` como uma verdadeira travessia DFS de árvore — **truncamento de lista opt-in** (`/snapshot?limit=N`, uma linha `… +K more` por execução limitada), **recaptura com escopo** (`scope=@ref`) e **indentação de hierarquia**, também expostos como `uid`/`limit` no `take_snapshot` do MCP. A trajetória de feed com 9 cliques que custava 44.285 tokens com re-snapshots completos ingênuos custa **898** com base truncada + diffs — 49× mais barato, e superando os 939 do libretto.

> As tabelas mais antigas acima usam uma aproximação de tokens `chars/4`; a comparação com o libretto usa contagens reais de `tiktoken`. Reexecute os números entre ferramentas no seu próprio ambiente antes de citar uma porcentagem.

### Tamanho do binário e memória

Medido em Apple M4 Pro, macOS 26.4.1. Os binários atuais foram compilados com `-Doptimize=ReleaseFast`.

| Binário | Tamanho atual |
|---|---:|
| `kuri` | 1.093.840 B (1,04 MiB) |
| `kuri-agent` | 629.904 B (615 KiB) |
| `kuri-browse` | 1.089.120 B (1,04 MiB) |
| `kuri-fetch` | 2.063.488 B (1,97 MiB) |

### RSS permaneceu estável durante a migração para Zig 0.16

Medido com a build atual `v0.4.3` `ReleaseFast` usando `/usr/bin/time -l`.

| Comando | RSS máx. médio `v0.4.3` |
|---|---:|
| `kuri-fetch --version` | ~2,45 MiB |
| `kuri-browse --version` | ~2,45 MiB |
| `kuri-fetch --quiet --dump markdown http://example.com/` | ~9,17 MiB |

## O Problema

Toda ferramenta de automação de navegador arrasta o Playwright (~300 MB), um runtime Node.js e uma cascata de dependências npm. Seu agente de IA só quer ler uma página, clicar em um botão e seguir em frente.
**Kuri é um único binário Zig.** Quatro modos, zero runtime:

```
kuri           →  CDP server (Chrome automation, a11y snapshots, HAR)
kuri-fetch     →  standalone fetcher (no Chrome, QuickJS for JS, ~2 MB)
kuri-browse    →  interactive terminal browser (navigate, follow links, search)
kuri-agent     →  agentic CLI (scriptable Chrome automation + security testing)
```

---
## 📦 Instalação

### Instalação em uma linha (macOS / Linux)

```sh
curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh
```

Detecta a sua plataforma, descarrega o binário correto, instala em `~/.local/bin`.
Os downloads vêm do branch `release-channel` autogerido do Kuri. Os binários macOS são assinados localmente com um certificado Developer ID. Os assets do GitHub Release espelham estes mesmos tarballs.

### bun / npm

```sh
bun install -g kuri-agent
# or: npm install -g kuri-agent
```

Baixa o binário nativo correto para a sua plataforma no momento da instalação.

### Canal de lançamento

Os binários estáveis do Kuri residem no branch `release-channel` e são servidos diretamente a partir de URLs raw do GitHub.

- Instalador estável: `https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh`
- Manifesto estável: `https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/latest.json`
- Visualização do branch: `https://github.com/justrach/kuri/tree/release-channel/stable`
- Padrão de download direto: `https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/<version>/kuri-<version>-<target>.tar.gz`

### Manual

Baixe o tarball para a sua plataforma a partir do [manifesto de lançamento estável](https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/latest.json) ou da [página de Releases do GitHub](https://github.com/justrach/kuri/releases) e descompacte-o no seu `$PATH`.

URL de instalação estável:

```sh
curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh
```

O manifesto inclui URLs exatas dos assets, além de checksums SHA-256 para `aarch64-linux`, `x86_64-linux`, `aarch64-macos` e `x86_64-macos`.

### Suporte de plataforma

| Plataforma | Status |
|---|---|
| macOS (`aarch64`, `x86_64`) | Binários pré-compilados, assinados + notarizados |
| Linux (`aarch64`, `x86_64`) | Binários pré-compilados |
| Windows (`x86_64`) | **Experimental — apenas cross-compile.** `zig build -Dtarget=x86_64-windows-gnu` é verificado pela CI, mas a automação do Chrome, daemonização, encerramento baseado em sinais, gravação de HAR e o armazenamento de autenticação baseado em arquivo estão todos stubados com `error.UnsupportedOnWindows` em tempo de execução. Use **WSL2** se precisar do conjunto real de funcionalidades. Acompanhado em [#153](https://github.com/justrach/kuri/issues/153). |

O Kuri depende de primitivas POSIX (`fork`, `clock_gettime`, sockets brutos) em vários pontos, então uma porta nativa completa para Windows é trabalho de verdade. A base em nível de compilação acima permite que os caminhos de `--version`/`--help` e operações puramente em memória rodem; as partes complicadas (Chrome, sockets, daemonize) precisam de implementações reais de Win32 antes de saírem da lista de stubs. Se você quiser assumir alguma delas, dê +1 em [#153](https://github.com/justrach/kuri/issues/153) ou abra um PR.

### Compilar a partir do código-fonte

Requer [Zig ≥ 0.16.0](https://ziglang.org/download/).

```bash
git clone https://github.com/justrach/kuri.git
cd kuri
zig build -Doptimize=ReleaseFast
# Binaries in zig-out/bin/: kuri  kuri-agent  kuri-fetch  kuri-browse
```

---

## ⚡ Início Rápido

**Requisitos:** [Zig ≥ 0.16.0](https://ziglang.org/download/) · Chrome/Chromium (para o modo CDP)

```bash
git clone https://github.com/justrach/kuri.git
cd kuri

zig build              # build everything
zig build test         # run 252+ tests

# CDP mode — launches Chrome automatically
./zig-out/bin/kuri

# Standalone mode — no Chrome needed
./zig-out/bin/kuri-fetch https://example.com

# Interactive browser — browse from your terminal
./zig-out/bin/kuri-browse https://example.com

# Experimental standalone browser runtime — separate build, not production
(cd kuri-browser && zig build run -- render https://example.com)
(cd kuri-browser && zig build run -- bench --offline)
```

### Primeira execução, caminho mais curto

```bash
# start the server; if CDP_URL is unset, kuri launches managed Chrome for you
./zig-out/bin/kuri

# discover tabs from that managed browser
curl -s http://127.0.0.1:8080/discover

# inspect the discovered tab list
curl -s http://127.0.0.1:8080/tabs
```

### Loop de agente com sessão em primeiro lugar

Para uso HTTP no estilo de agente, prefira um cabeçalho de sessão mais `/tab/new`, `/page/info` e `/snapshot` em vez de repetir `tab_id` em cada chamada.

```bash
SESSION=hn-demo
BASE=http://127.0.0.1:8080

curl -s -H "X-Kuri-Session: $SESSION" \
  "$BASE/tab/new?url=https%3A%2F%2Fnews.ycombinator.com"

curl -s -H "X-Kuri-Session: $SESSION" "$BASE/page/info"
SNAP=$(curl -s -H "X-Kuri-Session: $SESSION" "$BASE/snapshot?filter=interactive&format=compact")
MORE_REF=$(printf '%s' "$SNAP" | python3 -c 'import re,sys; print(re.search(r"\"More\" @(e\\d+)", sys.stdin.read()).group(1))')
curl -s -H "X-Kuri-Session: $SESSION" "$BASE/action?action=click&ref=$MORE_REF"
curl -s -H "X-Kuri-Session: $SESSION" "$BASE/page/info"
```

Há também um wrapper experimental leve em `tools/kuri_harness.py` se você quiser helpers Python sobre a mesma superfície HTTP.

Se você já tem o Chrome em execução com depuração remota, defina `CDP_URL` para o endpoint WebSocket ou HTTP:

```bash
CDP_URL=ws://127.0.0.1:9222/devtools/browser/... ./zig-out/bin/kuri
# or
CDP_URL=http://127.0.0.1:9222 ./zig-out/bin/kuri
```

### Navegue em vercel.com em 4 comandos

```bash
# 1. Discover Chrome tabs
curl -s http://localhost:8080/discover
# → {"discovered":1,"total_tabs":1}

# 2. Get tab ID
curl -s http://localhost:8080/tabs
# → [{"id":"ABC123","url":"chrome://newtab/","title":"New Tab"}]

# 3. Navigate
curl -s "http://localhost:8080/navigate?tab_id=ABC123&url=https://vercel.com"

# 4. Get accessibility snapshot (token-optimized for LLMs)
curl -s "http://localhost:8080/snapshot?tab_id=ABC123&filter=interactive"
# → [{"ref":"e0","role":"link","name":"VercelLogotype"},
#    {"ref":"e1","role":"button","name":"Ask AI"}, ...]
```

---

## 🌐 API HTTP

Todos os endpoints retornam JSON. Autenticação opcional via variável de ambiente `KURI_SECRET`. **135 endpoints** — paridade total com agent-browser e browser-use.

### Núcleo

| Caminho | Descrição |
|------|-------------|
| `GET /health` | Estado do servidor, contagem de abas, versão |
| `GET /tabs` | Lista todas as abas registadas |
| `GET /discover` | Descobre automaticamente abas do Chrome via CDP |
| `GET /tab/current` | Obtém ou define a aba atual para um `X-Kuri-Session` |
| `GET /page/info` | URL/título/estado de prontidão/viewport/scroll em tempo real para a aba ativa |
| `GET /page/state` | Observação compacta da página: url, título, % de scroll, viewport, contagens de formulários/links/imagens/inputs |
| `POST /batch` | Executa múltiplos comandos numa única chamada HTTP — retorna um array de resultados |
| `GET /browdie` | 🌰 (easter egg) |

### Controlo do Navegador

| Caminho | Parâmetros | Descrição |
|------|--------|-------------|
| `GET /navigate` | `tab_id`, `url` | Navega a aba para o URL |
| `GET /tab/new` | `url`, `activate`, `wait` | Cria uma nova aba e opcionalmente hidrata/define a aba atual |
| `GET /tab/close` | `tab_id` | Fecha uma aba |
| `GET /window/new` | `url`, `activate`, `wait` | Cria um novo alvo de janela/aba |
| `GET /snapshot` | `tab_id`, `filter`, `format` | Snapshot da árvore de acessibilidade com referências `eN`. Usa `filter=interactive&format=compact` para loops de agente com poucos tokens. |
| `GET /text` | `tab_id` | Extrai o texto da página |
| `GET /screenshot` | `tab_id`, `format`, `quality`, `save` | Captura screenshot (base64); `save=true` escreve o PNG em `STATE_DIR/screenshots` e retorna `{path,bytes}` em vez disso |
| `GET /screenshot/annotated` | `tab_id` | Screenshot com etiquetas de elementos numeradas |
| `GET /screenshot/diff` | `tab_id`, `baseline` | Diferença visual entre screenshots atual e de referência |
| `GET /action` | `tab_id`, `ref`, `action`, `value` | Click/type/fill/select/scroll/hover/dblclick/check/uncheck/blur por referência |
| `GET /evaluate` | `tab_id`, `expression` | Executa JavaScript |
| `GET /evalhandle` | `tab_id`, `expression` | Executa JS, retorna handle objectId (não o valor) |
| `GET /close` | `tab_id` | Fecha a aba + limpeza |
| `GET /bringtofront` | `tab_id` | Traz a aba para a frente |

### Ações

| Caminho | Parâmetros | Descrição |
|------|--------|-------------|
| `GET /clear` | `ref` | Limpa o valor do campo de input |
| `GET /selectall` | `ref` | Seleciona todo o texto no input/contenteditable |
| `GET /setvalue` | `ref`, `value` | Define o valor do input diretamente (ignora eventos de tecla) |
| `GET /dispatch` | `ref`, `type` | Despacha um evento DOM personalizado no elemento |
| `GET /boundingbox` | `ref` | Obtém o retângulo delimitador do elemento (x, y, width, height, centerX, centerY) |
| `GET /getattribute` | `ref`, `name` | Obtém o atributo do elemento por nome |
| `GET /inputvalue` | `ref` | Obtém o valor atual do elemento de input |
| `GET /element/state` | `ref`, `check` | Booleano rápido: `exists`, `visible`, `enabled`, `checked` |
| `GET /find-element` | `text`/`role`/`label`/`placeholder`/`testid` | Localizador semântico — encontra o elemento sem snapshot |
| `GET /highlight` | `ref` ou `selector` | Realça o elemento com uma sobreposição |

### Rato e Toque

| Caminho | Parâmetros | Descrição |
|------|--------|-------------|
| `GET /mouse/move` | `x`, `y` | Move o rato para as coordenadas |
| `GET /mouse/down` | `x`, `y`, `button` | Botão do rato pressionado |
| `GET /mouse/up` | `x`, `y`, `button` | Botão do rato libertado |
| `GET /mouse/wheel` | `x`, `y`, `deltaX`, `deltaY` | Scroll com a roda do rato |
| `GET /tap` | `x`, `y` | Toque (touchStart + touchEnd) |
| `GET /swipe` | `startX`, `startY`, `endX`, `endY` | Gesto de swipe tátil |
| `GET /drag` | `src_ref`, `tgt_ref` | Arrasta o elemento para o alvo |

### Teclado

| Caminho | Parâmetros | Descrição |
|------|--------|-------------|
| `GET /keyboard/type` | `tab_id`, `text` | Escreve texto via eventos de tecla |
| `GET /keyboard/inserttext` | `tab_id`, `text` | Insere texto diretamente |
| `GET /keydown` | `tab_id`, `key` | Evento de tecla pressionada |
| `GET /keyup` | `tab_id`, `key` | Evento de tecla libertada |

### Extração de Conteúdo

| Caminho | Descrição |
|------|-------------|
| `GET /markdown` | Converte a página para Markdown |
| `GET /links` | Extrai todos os links |
| `GET /dom/query` | Consulta por seletor CSS |
| `GET /dom/html` | Obtém o HTML do elemento |
| `GET /dom/attributes` | Obtém os atributos do elemento |
| `GET /pdf` | Imprime a página para PDF |
| `GET /find` | Pesquisa de texto na página |

### Espera

| Caminho | Parâmetros | Descrição |
|------|--------|-------------|
| `GET /wait` | `selector`, `text`, `url`, `state`, `visible`, `timeout` | Espera por seletor/texto/padrão de URL/networkidle/estado de carregamento |
| `GET /wait/function` | `expression`, `timeout` | Espera que uma expressão JS arbitrária seja verdadeira |
| `GET /wait/download` | `timeout` | Espera que o download do ficheiro termine |

### Tratamento de Diálogos

| Caminho | Descrição |
|------|-------------|
| `GET /dialog/auto` | Trata automaticamente todos os diálogos JS (aceitar ou dispensar) |
| `GET /dialog/accept` | Aceita o diálogo atual (com texto de prompt opcional) |
| `GET /dialog/dismiss` | Dispensa o diálogo atual |

### Rede e HAR

| Caminho | Descrição |
|------|-------------|
| `GET /har/start` | Inicia a gravação do tráfego de rede |
| `GET /har/stop` | Para + retorna HAR 1.2 JSON |
| `GET /har/status` | Estado da gravação + contagem de entradas |
| `GET /har/replay` | Mapa da API com snippets de código curl/fetch/python |
| `GET /cookies` | Obtém cookies |
| `GET /cookies/set` | Define cookies |
| `GET /cookies/delete` | Elimina cookies |
| `GET /cookies/clear` | Limpa todos os cookies |
| `GET /headers` | Define cabeçalhos de pedido personalizados |
| `GET /intercept/start` | Inicia a interceção de pedidos |
| `GET /intercept/stop` | Para a interceção de pedidos |
| `GET /intercept/requests` | Lista os pedidos intercetados |
| `GET /request/detail` | Obtém o corpo da resposta para um ID de pedido |
| `GET /response/body` | Obtém o URL e retorna o corpo da resposta |
| `GET /network` | Estatísticas do tráfego de rede |
| `GET /download` | Despoleta o download de um ficheiro |

### Navegação e Estado

| Caminho | Descrição |
|------|-------------|
| `GET /back` | Retroceder no navegador |
| `GET /forward` | Avançar no navegador |
| `GET /reload` | Recarregar a página |
| `GET /stop` | Parar o carregamento da página |
| `GET /pushstate` | Navegação SPA via history.pushState |
| `GET /storage/local` | Obtém/define localStorage |
| `GET /storage/session` | Obtém/define sessionStorage |
| `GET /storage/local/clear` | Limpa o localStorage |
| `GET /storage/session/clear` | Limpa o sessionStorage |
| `GET /session/save` | Guarda a sessão do navegador |
| `GET /session/load` | Restaura a sessão do navegador |
| `GET /session/list` | Lista as sessões guardadas |
| `GET /setcontent` | Define o HTML da página diretamente (POST) |

### Perfis de Autenticação

| Caminho | Descrição |
|------|-------------|
| `GET /auth/profile/save` | Guarda cookies + storage como um perfil de autenticação nomeado |
| `GET /auth/profile/load` | Restaura um perfil de autenticação nomeado numa aba |
| `GET /auth/profile/list` | Lista os perfis de autenticação guardados |
| `GET /auth/profile/delete` | Elimina um perfil de autenticação guardado |
| `GET /auth/extract` | Extrai tokens de autenticação (JWT, cookies, cabeçalhos) |
| `GET /set/credentials` | Define credenciais de autenticação básica HTTP |

No macOS, os segredos dos perfis de autenticação são armazenados no Keychain do utilizador.

### Emulação

| Caminho | Parâmetros | Descrição |
|------|--------|-------------|
| `GET /emulate` | tipo de dispositivo, tamanho de ecrã | Emulação de dispositivo |
| `GET /set/viewport` | `width`, `height` | Define o tamanho do viewport |
| `GET /set/useragent` | `ua` | Define o user agent |
| `GET /set/media` | `media` | Emula o tipo de media |
| `GET /set/offline` | `offline` | Alterna o modo offline |
| `GET /geolocation` | `lat`, `lng` | Substitui a geolocalização |
| `GET /timezone` | `timezone` | Substitui o fuso horário (ex.: `America/New_York`) |
| `GET /locale` | `locale` | Substitui o locale (ex.: `en-US`) |
| `GET /permissions` | `name`, `state` | Concede/nega permissões (geolocalização, notificações, clipboard) |

### Scripts e Injeção

| Caminho | Descrição |
|------|-------------|
| `GET /script/inject` | Injeta JavaScript na página (persiste entre navegações) |
| `GET /initscript/remove` | Remove um init script previamente injetado |
| `GET /addstyle` | Injeta uma folha de estilos CSS |
| `GET /expose` | Expõe uma função nomeada ao contexto JS da página |

### Inspeção React

| Caminho | Descrição |
|------|-------------|
| `GET /react/tree` | Árvore de componentes React via hook do DevTools |
| `GET /react/inspect` | Props e estado do componente React |
| `GET /react/renders` | Rastreamento de renders React (iniciar/parar) |
| `GET /react/suspense` | Estado do limite Suspense do React |

### Gravação e Desempenho

| Caminho | Descrição |
|------|-------------|
| `GET /recording/start` | Grava ações do utilizador (click, input, navigate) |
| `GET /recording/stop` | Para a gravação + retorna o registo de ações |
| `GET /vitals` | Core Web Vitals (LCP, CLS, FID, TTFB, FCP, domInteractive) |
| `GET /perf/lcp` | Temporização do Largest Contentful Paint |
| `GET /trace/start` | Inicia o trace de desempenho |
| `GET /trace/stop` | Para o trace |
| `GET /profiler/start` | Inicia o profiler JS |
| `GET /profiler/stop` | Para o profiler |

### Depuração

| Caminho | Descrição |
|------|-------------|
| `GET /debug/enable` | Ativa o HUD de depuração na página e o modo de congelamento opcional |
| `GET /debug/disable` | Desativa o HUD de depuração na página |
| `GET /inspect` | Inspeção de elementos |
| `GET /errors` | Recolhe erros JS |
| `GET /console` | Lê os logs da consola |
| `GET /frames` | Lista os frames da página |
| `GET /frame` | Muda para o contexto do iframe por nome ou URL |
| `GET /mainframe` | Volta ao frame principal |
| `GET /diff/snapshot` | Diff compacto `+`/`~`/`-` em relação à chamada anterior para esta aba — o loop de ações eficiente em tokens (com alias `/snapshot/changes`). Recorre a um snapshot completo com um cabeçalho `! page replaced` em caso de alteração massiva. |
| `GET /diff/url` | Compara dois URLs lado a lado (navigate, snapshot, diff) |

### Streaming

| Caminho | Descrição |
|------|-------------|
| `GET /screencast/start` | Inicia a gravação do ecrã |
| `GET /screencast/stop` | Para a gravação do ecrã |
| `GET /video/start` | Inicia a captura de vídeo |
| `GET /video/stop` | Para a captura de vídeo |
| `GET /ws/start` | Inicia o túnel WebSocket |
| `GET /ws/stop` | Para o túnel WebSocket |

### Loop amigável para agentes

O loop de servidor com menos fricção é:

1. `GET /tab/new?url=...`
2. `GET /page/state` (leve) ou `GET /snapshot?filter=interactive&format=compact` (completo)
3. `GET /action?action=click&ref=eN`
4. Repetir — ou usar `POST /batch` para operações multi-passo numa única chamada

Os parâmetros de consulta `url` e `expression` são descodificados em percentagem. Envia `X-Kuri-Session: my-agent` para persistir o contexto da aba no lado do servidor.
---

## 🧠 Skills

O repositório inclui uma área de skills extensível pelo utilizador:

- `skills/kuri-skill.md` é a skill base de agente HTTP do Kuri
- `skills/custom/` está reservada para as tuas próprias skills específicas do projeto
- `skills/custom/hackernews-page-2.md` é um exemplo concreto de skill personalizada
- `.claude/skills/kuri-server/SKILL.md` mantém-se sincronizado para skills de repositório ao estilo Claude

A skill base explica agora também qual o caminho de navegador a usar:

- `kuri` API HTTP: automação de produção Chrome/CDP com sessões, snapshots, ações, HAR, cookies e screenshots
- `kuri-fetch`: extração de texto/fetch autónoma sem Chrome
- `kuri-browse`: navegação interativa no terminal
- `kuri-agent`: automação CLI programável contra o servidor Kuri
- `kuri-browser/`: runtime de navegador nativo Zig separado e experimental para trabalho de paridade

Para a CLI do navegador experimental:

```bash
cd kuri-browser
zig build run -- render https://news.ycombinator.com --selector ".titleline a" --dump text
zig build run -- render https://todomvc.com/examples/react/dist/ --js --wait-eval "document.querySelectorAll('.todo-list li').length >= 1"
zig build run -- parity --offline
zig build run -- bench --offline
zig build run -- serve-cdp --port 9333
```

`kuri-browser serve-cdp` expõe descoberta HTTP no estilo Chrome, além de um roteador WebSocket JSON-RPC mínimo para testes de fumaça de protocolo. A avaliação em tempo de execução retorna objetos remotos CDP no formato V8 suportados pelo QuickJS; isso não adiciona uma dependência do V8 e ainda não é compatibilidade total com Playwright/Puppeteer.

As capturas de tela em `kuri-browser` atualmente delegam ao renderizador principal Kuri/CDP. Inicie `./zig-out/bin/kuri` primeiro, depois:

```bash
cd kuri-browser
zig build run -- screenshot https://example.com --out example.jpg --compress --kuri-base http://127.0.0.1:8080
```

`--compress` captura uma linha de base PNG e um candidato JPEG, grava o arquivo menor e reporta a economia em bytes. Medição local atual em `https://example.com`: `20,523` bytes PNG para `18,183` bytes JPEG qualidade 50, economizando `2,340` bytes ou `11%`.

### Avançado

| Caminho | Descrição |
|------|-------------|
| `GET /diff/snapshot` | Delta compacto `+`/`~`/`-` em relação ao snapshot anterior (loop de ação do agente) |
| `GET /emulate` | Emulação de dispositivo |
| `GET /geolocation` | Definir geolocalização |
| `POST /upload` | Upload de arquivo |
| `GET /script/inject` | Injetar JavaScript |
| `GET /intercept/start` | Iniciar interceptação de requisições |
| `GET /intercept/stop` | Parar interceptação |
| `GET /screenshot/annotated` | Captura de tela com anotações de elementos |
| `GET /screenshot/diff` | Diff visual entre capturas de tela |
| `GET /screencast/start` | Iniciar screencast |
| `GET /screencast/stop` | Parar screencast |
| `GET /video/start` | Iniciar gravação de vídeo |
| `GET /video/stop` | Parar gravação de vídeo |
| `GET /console` | Obter mensagens do console |
| `GET /stop` | Parar carregamento da página |
| `GET /get` | Busca HTTP direta (server-side) |
| `GET /scrollintoview` | Rolar um elemento referenciado para a visualização |
| `GET /drag` | Arrastar de uma ref para outra |
| `GET /keyboard/type` | Digitar texto com eventos de tecla |
| `GET /keyboard/inserttext` | Inserir texto diretamente |
| `GET /keydown` | Disparar um evento keydown |
| `GET /keyup` | Disparar um evento keyup |
| `GET /wait` | Aguardar estado de prontidão ou condições de elemento |
| `GET /tab/close` | Fechar uma aba |
| `GET /highlight` | Destacar um elemento por ref ou seletor |
| `GET /errors` | Obter erros de página/runtime |
| `GET /set/offline` | Alternar emulação de rede offline |
| `GET /set/media` | Definir recursos de mídia emulados |
| `GET /set/credentials` | Definir credenciais de autenticação básica HTTP |
| `GET /find` | Encontrar correspondências de texto na página atual |
| `GET /trace/start` | Iniciar rastreamento do Chrome |
| `GET /trace/stop` | Parar rastreamento e retornar dados do trace |
| `GET /profiler/start` | Iniciar profiler JS |
| `GET /profiler/stop` | Parar profiler JS |
| `GET /inspect` | Inspecionar um elemento ou estado da página |
| `GET /set/viewport` | Definir tamanho do viewport |
| `GET /set/useragent` | Substituir user agent |
| `GET /dom/attributes` | Obter atributos do elemento |
| `GET /frames` | Listar árvore de frames |
| `GET /network` | Inspecionar estado/requisições de rede |

---

## 🛡️ Stealth & Evasão de Bots

Kuri aplica patches anti-detecção automaticamente na inicialização — nenhuma configuração manual necessária.

### O que é aplicado

- **`Page.addScriptToEvaluateOnNewDocument`** — patches stealth executam antes de qualquer JS da página
- **navigator.webdriver = false** — oculta o flag de automação no nível do Chromium (`--disable-blink-features=AutomationControlled`)
- **Spoofing de WebGL/Canvas/AudioContext** — derrota detecção baseada em fingerprint
- **Rotação de UA** — 5 user agents realistas de Chrome/Safari/Firefox
- **chrome.csi/chrome.loadTimes** — stubs para verificações específicas do Akamai

### Detecção de bloqueio de bot

Navigate detecta bloqueios automaticamente e retorna fallback estruturado:

```bash
curl -s "http://localhost:8080/navigate?tab_id=ABC&url=https://protected-site.com"
# If blocked:
# {"blocked":true,"blocker":"akamai","ref_code":"0.7d...",
#  "fallback":{"suggestions":["Open URL directly in browser","Use KURI_PROXY"]}}
# If ok: normal CDP response
```

Detecta: **Akamai**, **Cloudflare**, **PerimeterX**, **DataDome**, captcha genérico.

### Suporte a proxy

```bash
KURI_PROXY=socks5://user:pass@residential-proxy:1080 ./zig-out/bin/kuri
KURI_PROXY=http://proxy:8080 ./zig-out/bin/kuri
```

### Sites testados

| Site | Proteção | Resultado |
|------|-----------|--------|
| Singapore Airlines | Akamai WAF | ✅ Contornado (estava bloqueado antes da v0.4.0) |
| Shopee SG | Anti-fraude personalizado | ✅ Página carrega, redireciona para login |
| Google Flights | Nenhuma | ✅ Interação completa |
| Booking.com | PerimeterX | ⚠️ Precisa de proxy |

---

## 🔧 kuri-fetch

---

[Read more](https://github.com/justrach/kuri)
Baixar ferramenta