Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
kuri — Automatisation de navigateur, exploration du web et contrôle d'appareils iOS + Android pour les agents IA. Instantanés CDP natifs Zig et économes en jetons, enregistrement HAR, client natif du protocole filaire adb et un fetcher autonome. | Kitploit
Outils/GitHubGitHub/justrach/kuri
Collecte d'InformationsSécurité WebTests d'IntrusionSécurité MobileCrawler
GitHubjustrach/kuri

kuri

Automatisation de navigateur, exploration du web et contrôle d'appareils iOS + Android pour les agents IA. Instantanés CDP natifs Zig et économes en jetons, enregistrement HAR, client natif du protocole filaire adb et un fetcher autonome.

Voir le dépôt
35018il y a 17 joursVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
Site web

Kuri

Kuri 🌰

Stable release License Zig node_modules status

Installation```sh

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

root@kitploit:~
macOS arm64/x86_64 et Linux x86_64/arm64. Binaire unique, aucune dépendance d'exécution.

Téléchargements directs : [macOS arm64](https://kuri.trilok.ai/download/v0.6.0/kuri-v0.6.0-aarch64-macos.tar.gz) · [macOS x86_64](https://kuri.trilok.ai/download/v0.6.0/kuri-v0.6.0-x86_64-macos.tar.gz) · [Linux x86_64](https://kuri.trilok.ai/download/v0.6.0/kuri-v0.6.0-x86_64-linux.tar.gz) · [Linux arm64](https://kuri.trilok.ai/download/v0.6.0/kuri-v0.6.0-aarch64-linux.tar.gz)

---

**Automatisation de navigateur et exploration web pour agents IA. Écrit en Zig. Zéro Node.js.**

Automatisation CDP · Instantanés A11y · Enregistrement HAR · Récupérateur autonome · Navigateur interactif dans le terminal · CLI agentique · Tests de sécurité · Contrôle d'appareils iOS + Android

[Démarrage rapide](#-quick-start) · [Benchmarks](#-benchmarks) · [kuri-agent](#-kuri-agent) · [Tests de sécurité](#-security-testing) · [API](#-http-api) · [Compétences](#-skills) · [Changelog](https://github.com/justrach/kuri/blob/HEAD/CHANGELOG.md)

> **Pourquoi les équipes passent à Kuri :** les builds `ReleaseFast` actuels pour Apple Silicon restent sous 2 Mo par binaire, et une nouvelle exécution Google Flights le 2026-04-23 a mesuré **3,392 tokens** pour une boucle complète `kuri-agent` (`go→snap→click→snap→eval`). Les écarts entre outils doivent être re-mesurés dans le même environnement avant de citer un pourcentage.

---

## Pourquoi Kuri gagne pour les agents

La plupart des outils de navigateur ont été conçus pour les ingénieurs QA. Kuri est conçu pour les boucles d'agents : lire la page, garder un coût en tokens faible, agir sur des références stables, et passer à la suite.

- **135 points de terminaison HTTP** — parité complète avec agent-browser et browser-use, de l'inspection React aux Core Web Vitals.
- **7 à 12 % de tokens en moins** qu'agent-browser sur des pages réelles grâce au format de référence `@eN` et au rendu sans préfixe.
- **Observations 44x plus légères** avec `/page/state` (48 tokens) contre un instantané complet (2,124 tokens) pour la même page Google Flights.
- **Exécution par lots** — `POST /batch` envoie N commandes en un seul appel HTTP, éliminant N-1 allers-retours et N-1 tours LLM.
- **Compatible React** — des événements souris CDP fiables et des événements clavier par caractère déclenchent les `onClick` et `onChange` de React 18/19.

### Tokens d'instantané : Google Flights `SIN → TPE`

Nouvelle exécution le 2026-05-24 dans cet espace de travail, mesurée avec `wc -c` et l'approximation `chars/4`.

| Outil / Mode | Chars | ~Tokens | Note |
|---|---:|---:|---|
| `kuri snap` (complet) | 8,499 | **2,124** | Tous les nœuds + références interactives |
| `kuri snap` (interactif uniquement) | ~3,000 | **~750** | Idéal pour les boucles d'agents |
| `kuri /page/state` | 190 | **48** | Observation légère (url, titre, scroll%, compteurs) |
| agent-browser snap (estimé) | ~9,183 | **~2,295** | Surcoût du format `[ref=e0]` |

### Efficacité des tokens : kuri vs agent-browser

| Page | Tokens kuri | Tokens agent-browser | Économies |
|---|---:|---:|---|
| example.com | 40 | 35 | -13 % (page triviale, agent-browser ignore la racine) |
| Hacker News | 386 | ~440 | **12 % de moins** |
| Google Flights SIN→TPE | 2,124 | ~2,295 | **7 % de moins** |

Les économies proviennent du format compact de kuri :
- Références `@e0` (3 caractères) contre `[ref=e0]` (9 caractères)
- Pas de préfixe `- ` par ligne (économise 2 caractères × nombre de lignes)
- Même indentation, même filtrage des nœuds

### Coût du workflow complet : `go → snap → click → snap → eval`

| Outil | Tokens par cycle |
|---|---:|
| **kuri-agent** | **~3,400** |
| Avec `/page/state` au lieu du second snap | **~1,700** |
| Avec `POST /batch` (tout en un seul appel) | **~1,700** (mêmes tokens, 1 appel HTTP au lieu de 5) |

### kuri vs libretto

[libretto](https://github.com/saffron-health/libretto) (Playwright + Node) est le concurrent le plus proche sur le coût de tokens par étape. Mesuré côte à côte le 2026-07-04 — même Chrome, même onglet, de vrais comptages `tiktoken` `o200k_base` (méthodologie complète et reproduction : **[benchmarks/libretto_comparison.md](https://github.com/justrach/kuri/blob/HEAD/benchmarks/libretto_comparison.md)**). La répartition honnête :

| Axe | Gagnant | Détail |
|---|---|---|
| Latence par appel | **kuri** | 4–117 ms contre 1,344–1,500 ms (**13–376× plus rapide** — serveur persistant contre Node par commande) |
| Tokens d'instantané, page typique | **kuri** | simple 61 contre 151 (2.5×), article 265 contre 363 (1.37×) — grammaire plus compacte |
| Tokens d'instantané, grande liste | partagé | kuri par défaut 4,424 contre 813 — kuri émet les 259 références, libretto tronque par défaut. Avec `limit=5`, kuri rend 555 tokens (**1.46× en dessous de libretto**), 34 références + marqueurs `… +45 more` |
| Trajectoire (flux, 9 clics) | **kuri**, de justesse | 898 contre 939 tokens (base `limit=5` + boucle de diff contre boucle exec) — parité à léger avantage ; la perte de 5.1× du matin provenait de la base non tronquée |
| Exécutions répétées | **libretto** | compile les trajectoires en script Playwright → re-exécutions à 0 token ; kuri repaye la boucle à chaque exécution |

**Ce que kuri a tiré de l'étude de libretto** (tout livré dans cette version) : une boucle diff-first (`take_snapshot_diff`, ~38 tokens/étape) ; un diff adaptatif qui retombe sur un instantané complet avec un en-tête `! page replaced` lors d'une navigation ; des lignes de suppression ne contenant que l'identité ; des captures d'écran écrites sur disque (le chemin est renvoyé, les octets n'entrent jamais dans le contexte) ; `get_page_state` via MCP ; et — après avoir réécrit `parseA11yNodes` comme un véritable parcours arborescent DFS — la **troncature de liste opt-in** (`/snapshot?limit=N`, une ligne `… +K more` par exécution plafonnée), la **re-capture ciblée** (`scope=@ref`) et l'**indentation de hiérarchie**, également exposées sous forme de `uid`/`limit` sur MCP `take_snapshot`. La trajectoire de flux à 9 clics qui coûtait 44,285 tokens avec des re-snapshots complets naïfs coûte **898** avec une base tronquée + diffs — 49× moins chère, et devant les 939 de libretto.

> Les tableaux plus anciens ci-dessus utilisent une approximation de tokens `chars/4` ; la comparaison libretto utilise de vrais comptages `tiktoken`. Re-mesurez les chiffres entre outils dans votre propre environnement avant de citer un pourcentage.

### Taille des binaires et mémoire

Mesuré sur Apple M4 Pro, macOS 26.4.1. Les binaires actuels ont été compilés avec `-Doptimize=ReleaseFast`.

| Binaire | Taille actuelle |
|---|---:|
| `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) |

### Le RSS est resté stable lors de la migration vers Zig 0.16

Mesuré sur le build `ReleaseFast` `v0.4.3` actuel avec `/usr/bin/time -l`.

| Commande | RSS max moyen `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 |

## Le problème

Chaque outil d'automatisation de navigateur entraîne Playwright (~300 Mo), un runtime Node.js et une cascade de dépendances npm. Votre agent IA veut simplement lire une page, cliquer sur un bouton et passer à la suite.
**Kuri est un binaire Zig unique.** Quatre modes, zéro 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)

📦 Installation

Installation en une ligne (macOS / Linux)```sh

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

root@kitploit:~
Détecte votre plateforme, télécharge le bon binaire, installe dans `~/.local/bin`.
Les téléchargements proviennent de la branche `release-channel` auto-gérée par Kuri. Les binaires macOS sont signés localement avec un certificat Developer ID. Les artefacts de la section Releases de GitHub reflètent ces mêmes archives.

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

Télécharge le binaire natif correct pour votre plateforme au moment de l'installation.

Canal de publication

Les binaires stables de Kuri se trouvent sur la branche release-channel et sont servis directement à partir des URL brutes de GitHub.

  • Installateur stable : https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh
  • Manifeste stable : https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/latest.json
  • Vue de la branche : https://github.com/justrach/kuri/tree/release-channel/stable
  • Modèle de téléchargement direct : https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/<version>/kuri-<version>-<target>.tar.gz

Manuel

Téléchargez l'archive tar pour votre plateforme à partir du manifeste de version stable ou de la page des versions GitHub et décompressez-la dans votre $PATH.

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

root@kitploit:~
Le manifeste inclut des URL d'actifs exactes ainsi que des sommes de contrôle SHA-256 pour `aarch64-linux`, `x86_64-linux`, `aarch64-macos` et `x86_64-macos`.

### Support de plateforme

| Plateforme | Statut |
|---|---|
| macOS (`aarch64`, `x86_64`) | Binaires précompilés, signés + notarisés |
| Linux (`aarch64`, `x86_64`) | Binaires précompilés |
| Windows (`x86_64`) | **Expérimental — compilation croisée uniquement.** `zig build -Dtarget=x86_64-windows-gnu` est vérifié par CI, mais l'automatisation de Chrome, la démonisation, l'arrêt par signaux, l'enregistrement HAR et le stockage d'authentification sur fichier sont tous des stubs avec `error.UnsupportedOnWindows` à l'exécution. Utilisez **WSL2** si vous avez besoin de l'ensemble des fonctionnalités réelles. Suivi dans [#153](https://github.com/justrach/kuri/issues/153). |

Kuri s'appuie sur des primitives POSIX (`fork`, `clock_gettime`, sockets bruts) à plusieurs endroits, donc un portage Windows natif complet représente un vrai travail. La base de référence au niveau compilation ci-dessus permet aux chemins `--version`/`--help` et aux opérations purement en mémoire de fonctionner ; les parties épineuses (Chrome, sockets, daemonize) nécessitent de véritables implémentations Win32 avant de pouvoir être retirées de la liste des stubs. Si vous voulez vous attaquer à l'un de ces points, +1 sur [#153](https://github.com/justrach/kuri/issues/153) ou ouvrez une PR.

### Compiler à partir des sources

Nécessite [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

⚡ Démarrage rapide

Prérequis : Zig ≥ 0.16.0 · Chrome/Chromium (pour le mode 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)

root@kitploit:~
### Première exécution, plus court chemin```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

Boucle d'agent privilégiant la session

Pour une utilisation HTTP de type agent, privilégiez un en-tête de session ainsi que /tab/new, /page/info et /snapshot plutôt que de répéter tab_id à chaque appel.```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"

root@kitploit:~
Il existe également un wrapper expérimental léger dans `tools/kuri_harness.py` si vous souhaitez des helpers Python par-dessus la même interface HTTP.

Si vous avez déjà Chrome lancé avec le débogage à distance, définissez `CDP_URL` sur l'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

Parcourir vercel.com en 4 commandes```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"}, ...]

root@kitploit:~
---

## 🌐 API HTTP

Tous les points de terminaison renvoient du JSON. Authentification facultative via la variable d'environnement `KURI_SECRET`. **135 points de terminaison** — parité complète avec agent-browser et browser-use.

### Cœur

| Chemin | Description |
|------|-------------|
| `GET /health` | État du serveur, nombre d'onglets, version |
| `GET /tabs` | Liste tous les onglets enregistrés |
| `GET /discover` | Découvre automatiquement les onglets Chrome via CDP |
| `GET /tab/current` | Obtient ou définit l'onglet courant pour une `X-Kuri-Session` |
| `GET /page/info` | URL/titre/état de préparation/viewport/défilement en direct pour l'onglet actif |
| `GET /page/state` | Observation compacte de la page : url, titre, scroll%, viewport, nombre de formulaires/liens/images/champs de saisie |
| `POST /batch` | Exécute plusieurs commandes en un seul appel HTTP — renvoie un tableau de résultats |
| `GET /browdie` | 🌰 (œuf de Pâques) |

### Contrôle du navigateur

| Chemin | Paramètres | Description |
|------|--------|-------------|
| `GET /navigate` | `tab_id`, `url` | Navigue l'onglet vers l'URL |
| `GET /tab/new` | `url`, `activate`, `wait` | Crée un nouvel onglet et hydrate/définit éventuellement l'onglet courant |
| `GET /tab/close` | `tab_id` | Ferme un onglet |
| `GET /window/new` | `url`, `activate`, `wait` | Crée une nouvelle cible de fenêtre/onglet |
| `GET /snapshot` | `tab_id`, `filter`, `format` | Instantané de l'arbre d'accessibilité avec références `eN`. Utilisez `filter=interactive&format=compact` pour les boucles d'agent à faible consommation de jetons. |
| `GET /text` | `tab_id` | Extrait le texte de la page |
| `GET /screenshot` | `tab_id`, `format`, `quality`, `save` | Capture d'écran (base64) ; `save=true` écrit le PNG dans `STATE_DIR/screenshots` et renvoie `{path,bytes}` à la place |
| `GET /screenshot/annotated` | `tab_id` | Capture d'écran avec étiquettes d'éléments numérotées |
| `GET /screenshot/diff` | `tab_id`, `baseline` | Diff visuel entre la capture courante et la capture de référence |
| `GET /action` | `tab_id`, `ref`, `action`, `value` | Click/type/fill/select/scroll/hover/dblclick/check/uncheck/blur par référence |
| `GET /evaluate` | `tab_id`, `expression` | Exécute du JavaScript |
| `GET /evalhandle` | `tab_id`, `expression` | Exécute du JS, renvoie un handle objectId (pas la valeur) |
| `GET /close` | `tab_id` | Ferme l'onglet + nettoyage |
| `GET /bringtofront` | `tab_id` | Amène l'onglet au premier plan |

### Actions

| Chemin | Paramètres | Description |
|------|--------|-------------|
| `GET /clear` | `ref` | Efface la valeur d'un champ de saisie |
| `GET /selectall` | `ref` | Sélectionne tout le texte dans une entrée/contenu éditable |
| `GET /setvalue` | `ref`, `value` | Définit directement la valeur de saisie (contourne les événements clavier) |
| `GET /dispatch` | `ref`, `type` | Déclenche un événement DOM personnalisé sur l'élément |
| `GET /boundingbox` | `ref` | Obtient le rectangle englobant de l'élément (x, y, width, height, centerX, centerY) |
| `GET /getattribute` | `ref`, `name` | Obtient un attribut d'élément par son nom |
| `GET /inputvalue` | `ref` | Obtient la valeur actuelle de l'élément de saisie |
| `GET /element/state` | `ref`, `check` | Booléen rapide : `exists`, `visible`, `enabled`, `checked` |
| `GET /find-element` | `text`/`role`/`label`/`placeholder`/`testid` | Localisateur sémantique — trouve un élément sans instantané |
| `GET /highlight` | `ref` ou `selector` | Met en surbrillance l'élément avec un overlay |

### Souris et tactile

| Chemin | Paramètres | Description |
|------|--------|-------------|
| `GET /mouse/move` | `x`, `y` | Déplace la souris aux coordonnées |
| `GET /mouse/down` | `x`, `y`, `button` | Enfonce le bouton de la souris |
| `GET /mouse/up` | `x`, `y`, `button` | Relâche le bouton de la souris |
| `GET /mouse/wheel` | `x`, `y`, `deltaX`, `deltaY` | Défilement à la molette |
| `GET /tap` | `x`, `y` | Toucher (touchStart + touchEnd) |
| `GET /swipe` | `startX`, `startY`, `endX`, `endY` | Geste de balayage tactile |
| `GET /drag` | `src_ref`, `tgt_ref` | Glisse l'élément vers la cible |

### Clavier

| Chemin | Paramètres | Description |
|------|--------|-------------|
| `GET /keyboard/type` | `tab_id`, `text` | Saisit du texte via des événements clavier |
| `GET /keyboard/inserttext` | `tab_id`, `text` | Insère du texte directement |
| `GET /keydown` | `tab_id`, `key` | Événement touche enfoncée |
| `GET /keyup` | `tab_id`, `key` | Événement touche relâchée |

### Extraction de contenu

| Chemin | Description |
|------|-------------|
| `GET /markdown` | Convertit la page en Markdown |
| `GET /links` | Extrait tous les liens |
| `GET /dom/query` | Requête de sélecteur CSS |
| `GET /dom/html` | Obtient le HTML de l'élément |
| `GET /dom/attributes` | Obtient les attributs de l'élément |
| `GET /pdf` | Imprime la page en PDF |
| `GET /find` | Recherche de texte dans la page |

### Attente

| Chemin | Paramètres | Description |
|------|--------|-------------|
| `GET /wait` | `selector`, `text`, `url`, `state`, `visible`, `timeout` | Attend un sélecteur/texte/motif d'URL/networkidle/état de chargement |
| `GET /wait/function` | `expression`, `timeout` | Attend qu'une expression JS quelconque soit vraie |
| `GET /wait/download` | `timeout` | Attend la fin du téléchargement d'un fichier |

### Gestion des dialogues

| Chemin | Description |
|------|-------------|
| `GET /dialog/auto` | Gère automatiquement toutes les boîtes de dialogue JS (accepter ou fermer) |
| `GET /dialog/accept` | Accepte la boîte de dialogue courante (avec texte d'invite facultatif) |
| `GET /dialog/dismiss` | Ferme la boîte de dialogue courante |

### Réseau et HAR

| Chemin | Description |
|------|-------------|
| `GET /har/start` | Démarre l'enregistrement du trafic réseau |
| `GET /har/stop` | Arrête et renvoie le JSON HAR 1.2 |
| `GET /har/status` | État de l'enregistrement + nombre d'entrées |
| `GET /har/replay` | Carte API avec extraits de code curl/fetch/python |
| `GET /cookies` | Obtient les cookies |
| `GET /cookies/set` | Définit les cookies |
| `GET /cookies/delete` | Supprime les cookies |
| `GET /cookies/clear` | Efface tous les cookies |
| `GET /headers` | Définit des en-têtes de requête personnalisés |
| `GET /intercept/start` | Démarre l'interception de requêtes |
| `GET /intercept/stop` | Arrête l'interception de requêtes |
| `GET /intercept/requests` | Liste les requêtes interceptées |
| `GET /request/detail` | Obtient le corps de réponse pour un ID de requête |
| `GET /response/body` | Récupère une URL et renvoie le corps de réponse |
| `GET /network` | Statistiques du trafic réseau |
| `GET /download` | Déclenche le téléchargement d'un fichier |

### Navigation et état

| Chemin | Description |
|------|-------------|
| `GET /back` | Précédent dans le navigateur |
| `GET /forward` | Suivant dans le navigateur |
| `GET /reload` | Recharge la page |
| `GET /stop` | Arrête le chargement de la page |
| `GET /pushstate` | Navigation SPA via history.pushState |
| `GET /storage/local` | Obtient/définit localStorage |
| `GET /storage/session` | Obtient/définit sessionStorage |
| `GET /storage/local/clear` | Efface localStorage |
| `GET /storage/session/clear` | Efface sessionStorage |
| `GET /session/save` | Enregistre la session du navigateur |
| `GET /session/load` | Restaure la session du navigateur |
| `GET /session/list` | Liste les sessions enregistrées |
| `GET /setcontent` | Définit directement le HTML de la page (POST) |

### Profils d'authentification

| Chemin | Description |
|------|-------------|
| `GET /auth/profile/save` | Enregistre cookies + stockage en tant que profil d'authentification nommé |
| `GET /auth/profile/load` | Restaure un profil d'authentification nommé dans un onglet |
| `GET /auth/profile/list` | Liste les profils d'authentification enregistrés |
| `GET /auth/profile/delete` | Supprime un profil d'authentification enregistré |
| `GET /auth/extract` | Extrait les jetons d'authentification (JWT, cookies, en-têtes) |
| `GET /set/credentials` | Définit les identifiants d'authentification HTTP de base |

Sur macOS, les secrets des profils d'authentification sont stockés dans le Trousseau de l'utilisateur.

### Émulation

| Chemin | Paramètres | Description |
|------|--------|-------------|
| `GET /emulate` | type d'appareil, taille d'écran | Émulation d'appareil |
| `GET /set/viewport` | `width`, `height` | Définit la taille du viewport |
| `GET /set/useragent` | `ua` | Définit le user agent |
| `GET /set/media` | `media` | Émule le type de média |
| `GET /set/offline` | `offline` | Active/désactive le mode hors ligne |
| `GET /geolocation` | `lat`, `lng` | Remplace la géolocalisation |
| `GET /timezone` | `timezone` | Remplace le fuseau horaire (p. ex. `America/New_York`) |
| `GET /locale` | `locale` | Remplace la locale (p. ex. `en-US`) |
| `GET /permissions` | `name`, `state` | Accorde/refuse les permissions (géolocalisation, notifications, presse-papiers) |

### Scripts et injection

| Chemin | Description |
|------|-------------|
| `GET /script/inject` | Injecte du JavaScript dans la page (persiste à travers les navigations) |
| `GET /initscript/remove` | Supprime un script d'initialisation injecté précédemment |
| `GET /addstyle` | Injecte une feuille de style CSS |
| `GET /expose` | Expose une fonction nommée au contexte JS de la page |

### Inspection React

| Chemin | Description |
|------|-------------|
| `GET /react/tree` | Arbre de composants React via le hook DevTools |
| `GET /react/inspect` | Props et état des composants React |
| `GET /react/renders` | Suivi des rendus React (démarrage/arrêt) |
| `GET /react/suspense` | Statut des limites de suspense React |

### Enregistrement et performance

| Chemin | Description |
|------|-------------|
| `GET /recording/start` | Enregistre les actions utilisateur (clic, saisie, navigation) |
| `GET /recording/stop` | Arrête l'enregistrement + renvoie le journal des actions |
| `GET /vitals` | Core Web Vitals (LCP, CLS, FID, TTFB, FCP, domInteractive) |
| `GET /perf/lcp` | Timing du Largest Contentful Paint |
| `GET /trace/start` | Démarre le traçage des performances |
| `GET /trace/stop` | Arrête le traçage |
| `GET /profiler/start` | Démarre le profileur JS |
| `GET /profiler/stop` | Arrête le profileur |

### Débogage

| Chemin | Description |
|------|-------------|
| `GET /debug/enable` | Active le HUD de débogage intégré à la page et le mode gel facultatif |
| `GET /debug/disable` | Désactive le HUD de débogage intégré à la page |
| `GET /inspect` | Inspection d'élément |
| `GET /errors` | Collecte les erreurs JS |
| `GET /console` | Lit les journaux de la console |
| `GET /frames` | Liste les frames de la page |
| `GET /frame` | Bascule vers le contexte iframe par nom ou URL |
| `GET /mainframe` | Revient au frame principal |
| `GET /diff/snapshot` | Diff compact `+`/`~`/`-` par rapport à l'appel précédent pour cet onglet — la boucle d'action économe en jetons (alias `/snapshot/changes`). Revient à un instantané complet avec un en-tête `! page replaced` en cas de changement massif. |
| `GET /diff/url` | Compare deux URL côte à côte (naviguer, instantané, diff) |

### Streaming

| Chemin | Description |
|------|-------------|
| `GET /screencast/start` | Démarre l'enregistrement d'écran |
| `GET /screencast/stop` | Arrête l'enregistrement d'écran |
| `GET /video/start` | Démarre la capture vidéo |
| `GET /video/stop` | Arrête la capture vidéo |
| `GET /ws/start` | Démarre le tunnel WebSocket |
| `GET /ws/stop` | Arrête le tunnel WebSocket |

### Boucle adaptée aux agents

La boucle serveur la plus fluide est :

1. `GET /tab/new?url=...`
2. `GET /page/state` (léger) ou `GET /snapshot?filter=interactive&format=compact` (complet)
3. `GET /action?action=click&ref=eN`
4. Répétez — ou utilisez `POST /batch` pour des opérations en plusieurs étapes en un seul appel

Les paramètres de requête `url` et `expression` sont décodés en pourcentage. Envoyez `X-Kuri-Session: my-agent` pour conserver le contexte de l'onglet côté serveur.

---

## 🧠 Compétences

Le dépôt inclut un espace de compétences extensible par l'utilisateur :

- `skills/kuri-skill.md` est la compétence de base de l'agent HTTP Kuri
- `skills/custom/` est réservé à vos propres compétences spécifiques au projet
- `skills/custom/hackernews-page-2.md` est un exemple concret de compétence personnalisée
- `.claude/skills/kuri-server/SKILL.md` reste synchronisé pour les compétences de dépôt de type Claude

La compétence de base explique désormais également quelle méthode de navigation utiliser :

- `kuri` HTTP API : automatisation Chrome/CDP de production avec sessions, instantanés, actions, HAR, cookies et captures d'écran
- `kuri-fetch` : extraction de texte/fetch autonome sans Chrome
- `kuri-browse` : navigation interactive dans le terminal
- `kuri-agent` : automatisation CLI scriptable contre le serveur Kuri
- `kuri-browser/` : runtime navigateur expérimental distinct en Zig natif pour les travaux de parité

Pour la CLI du navigateur expérimental :```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 expose la découverte HTTP de type Chrome ainsi qu'un routeur JSON-RPC WebSocket minimal pour les tests de fumée du protocole. L'évaluation à l'exécution renvoie des objets distants CDP de forme V8 adossés à QuickJS ; cela n'ajoute pas de dépendance V8 et ne constitue pas encore une compatibilité complète avec Playwright/Puppeteer.

Les captures d'écran dans kuri-browser délèguent actuellement au rendu principal Kuri/CDP. Lancez d'abord ./zig-out/bin/kuri, puis :```bash cd kuri-browser zig build run -- screenshot https://example.com --out example.jpg --compress --kuri-base http://127.0.0.1:8080

root@kitploit:~
`--compress` capture une ligne de base PNG et une candidate JPEG, écrit le fichier le plus petit et rapporte les octets économisés. Mesure locale actuelle sur `https://example.com` : `20 523` octets PNG contre `18 183` octets JPEG qualité 50, soit `2 340` octets économisés ou `11 %`.

### Avancé

| Chemin | Description |
|------|-------------|
| `GET /diff/snapshot` | Delta compact `+`/`~`/`-` par rapport à l'instantané précédent (boucle d'action de l'agent) |
| `GET /emulate` | Émulation d'appareil |
| `GET /geolocation` | Définir la géolocalisation |
| `POST /upload` | Téléversement de fichier |
| `GET /script/inject` | Injecter du JavaScript |
| `GET /intercept/start` | Démarrer l'interception des requêtes |
| `GET /intercept/stop` | Arrêter l'interception |
| `GET /screenshot/annotated` | Capture d'écran avec annotations d'éléments |
| `GET /screenshot/diff` | Diff visuel entre captures d'écran |
| `GET /screencast/start` | Démarrer le screencast |
| `GET /screencast/stop` | Arrêter le screencast |
| `GET /video/start` | Démarrer l'enregistrement vidéo |
| `GET /video/stop` | Arrêter l'enregistrement vidéo |
| `GET /console` | Obtenir les messages console |
| `GET /stop` | Arrêter le chargement de la page |
| `GET /get` | Requête HTTP directe (côté serveur) |
| `GET /scrollintoview` | Faire défiler un élément référencé pour l'afficher |
| `GET /drag` | Glisser d'une référence à une autre |
| `GET /keyboard/type` | Saisir du texte avec des événements clavier |
| `GET /keyboard/inserttext` | Insérer du texte directement |
| `GET /keydown` | Déclencher un événement keydown |
| `GET /keyup` | Déclencher un événement keyup |
| `GET /wait` | Attendre l'état prêt ou des conditions sur les éléments |
| `GET /tab/close` | Fermer un onglet |
| `GET /highlight` | Mettre en surbrillance un élément par référence ou sélecteur |
| `GET /errors` | Obtenir les erreurs de page/exécution |
| `GET /set/offline` | Activer/désactiver l'émulation réseau hors ligne |
| `GET /set/media` | Définir les fonctionnalités média émulées |
| `GET /set/credentials` | Définir les identifiants d'authentification de base HTTP |
| `GET /find` | Rechercher des correspondances de texte dans la page actuelle |
| `GET /trace/start` | Démarrer le tracing Chrome |
| `GET /trace/stop` | Arrêter le tracing et renvoyer les données de trace |
| `GET /profiler/start` | Démarrer le profileur JS |
| `GET /profiler/stop` | Arrêter le profileur JS |
| `GET /inspect` | Inspecter un élément ou l'état de la page |
| `GET /set/viewport` | Définir la taille du viewport |
| `GET /set/useragent` | Remplacer le user agent |
| `GET /dom/attributes` | Obtenir les attributs des éléments |
| `GET /frames` | Lister l'arborescence des frames |
| `GET /network` | Inspecter l'état/les requêtes réseau |

---

## 🛡️ Furtivité & évasion des bots

Kuri applique automatiquement des correctifs anti-détection au démarrage — aucune configuration manuelle n'est nécessaire.

### Ce qui est appliqué

- **`Page.addScriptToEvaluateOnNewDocument`** — les correctifs de furtivité s'exécutent avant tout JS de la page
- **navigator.webdriver = false** — masque le drapeau d'automatisation au niveau de Chromium (`--disable-blink-features=AutomationControlled`)
- **Spoofing WebGL/Canvas/AudioContext** — neutralise la détection basée sur l'empreinte numérique
- **Rotation d'UA** — 5 user agents réalistes Chrome/Safari/Firefox
- **chrome.csi/chrome.loadTimes** — stubs pour les vérifications spécifiques à Akamai

### Détection de blocage anti-bot

Navigate détecte automatiquement les blocages et renvoie un repli structuré :```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

Détecte : Akamai, Cloudflare, PerimeterX, DataDome, captcha générique.

Prise en charge des proxys```bash

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

root@kitploit:~
### Sites testés

| Site | Protection | Résultat |
|------|-----------|--------|
| Singapore Airlines | Akamai WAF | ✅ Contourné (était bloqué avant v0.4.0) |
| Shopee SG | Anti-fraude personnalisé | ✅ La page se charge, redirige vers la connexion |
| Google Flights | Aucune | ✅ Interaction complète |
| Booking.com | PerimeterX | ⚠️ Nécessite un proxy |

---

## 🔧 kuri-fetch

Récupérateur HTTP autonome — pas de Chrome, pas de Playwright, pas de npm. Livré sous forme de binaire de ~2 Mo avec QuickJS intégré pour l'exécution de JS.```bash
zig build fetch    # build + run

# Default: convert to Markdown
kuri-fetch https://example.com

# Extract links
kuri-fetch -d links https://news.ycombinator.com

# Structured JSON output
kuri-fetch --json https://example.com

# Execute inline scripts via QuickJS
kuri-fetch --js https://example.com

# Write to file, quiet mode
kuri-fetch -o page.md -q https://example.com

# Pipe-friendly: content → stdout, status → stderr
kuri-fetch -d text https://example.com | wc -w

Fonctionnalités

  • 5 modes de sortie — markdown, html, links, text, json
  • Moteur JS QuickJS — --js exécute les balises <script> inline
  • Stubs DOM — document.querySelector, getElementById, window.location, document.title, console.log, setTimeout (style SSR)
  • Défense SSRF — bloque les IP privées, les endpoints de métadonnées, les schémas non-HTTP
  • Sortie colorée — respecte NO_COLOR, , , détection TTY

🌐 kuri-browse

Navigateur terminal interactif — parcourez le web depuis votre terminal. Pas besoin de Chrome.```bash zig build browse # build + run

kuri-browse https://example.com

root@kitploit:~
I don't see any content to translate. The input after "INPUT:" is empty. Please provide the chunk text.```
🌰 kuri-browse — terminal browser
→ loading https://example.com

# Example Domain
This domain is for use in documentation examples...
Learn more [1]

───── Links ─────
  [1] https://iana.org/domains/example

✓ 528 bytes, 1 links (133ms)
[nav] https://example.com> 1     ← type 1 to follow the link

Commandes

Fonctionnalités

  • Rendu markdown en couleur — titres, liens, blocs de code, gras, citations
  • Liens numérotés — chaque lien reçoit [N], tapez le numéro pour le suivre
  • Historique de navigation — retour/avant comme un vrai navigateur
  • Recherche dans la page — /term surligne toutes les correspondances
  • Résolution des URL relatives — suit les liens naturellement entre les pages
  • Filtrage intelligent — ignore les hrefs javascript: et mailto:

🤖 kuri-agent

CLI scriptable pour l'automatisation de Chrome — pilote le navigateur commande par commande depuis votre terminal ou vos scripts shell. Partage l'état de la session entre les invocations via ~/.kuri/session.json.```bash zig build agent # build kuri-agent

1. Find a Chrome tab

kuri-agent tabs

→ ws://127.0.0.1:9222/devtools/page/ABC123 https://example.com

2. Attach to it

kuri-agent use ws://127.0.0.1:9222/devtools/page/ABC123

3. Navigate + interact

kuri-agent go https://example.com kuri-agent snap --interactive # → [{"ref":"e0","role":"link","name":"More info"}] kuri-agent click e0 kuri-agent shot # saves ~/.kuri/screenshots/.png

root@kitploit:~
### Commandes

| Commande | Description |
|---------|-------------|
| `tabs [--port N]` | Lister les onglets Chrome |
| `use <ws_url>` | Se rattacher à un onglet (enregistre la session) |
| `open [url] [--port N]` | Ouvrir un nouvel onglet (accédant éventuellement à l'url) |
| `status` | Afficher la session en cours |
| `go <url>` | Accéder à l'URL |
| `snap [--interactive] [--json] [--text] [--depth N]` | Instantané d'accessibilité, enregistre les réfs `eN` |
| `click <ref>` | Cliquer sur un élément par réf (événements de souris CDP, compatible React) |
| `type <ref> <text>` | Saisir dans un élément (événements de clavier par caractère, compatible React) |
| `fill <ref> <text>` | Renseigner la valeur d'une entrée |
| `select <ref> <value>` | Sélectionner une option de liste déroulante |
| `hover <ref>` | Survoler un élément |
| `focus <ref>` | Mettre l'élément au focus |
| `scroll` | Faire défiler la page |
| `viewport [width height]` | Obtenir ou définir les dimensions du viewport |
| `eval <js>` | Évaluer du JavaScript |
| `text [selector]` | Obtenir le texte de la page |
| `shot [--out file.png]` | Capture d'écran |
| `back` | Naviguer en arrière |
| `forward` | Naviguer en avant |
| `reload` | Recharger la page actuelle |
| `cookies` | Lister les cookies avec les indicateurs de sécurité |
| `headers` | Vérifier les en-têtes de réponse de sécurité |
| `audit` | Audit de sécurité complet |
| `storage [local\|session\|all]` | Extraire localStorage / sessionStorage |
| `jwt` | Extraire et décoder les JWT des cookies et du stockage |
| `fetch <method> <url> [--data <json>]` | Fetch authentifié avec les cookies de la page |
| `probe <url-template> <start> <end>` | Sonde IDOR : parcourt les IDs numériques dans l'URL |
| `grab <ref>` | Clique la réf, intercepte `window.open`, suit la redirection dans l'onglet |
| `wait-for-tab [--port N]` | Interroge en continu un nouvel onglet, bascule automatiquement de session |
| `stealth` | Appliquer des correctifs anti-détection |
| `set-header <name> <value>` | Ajouter un en-tête personnalisé à toutes les requêtes |
| `show-headers` | Afficher les en-têtes supplémentaires stockés |
| `clear-headers` | Supprimer tous les en-têtes supplémentaires |
---

## 📱 kuri-mobile (iOS + Android)

CLI Zig natif pour piloter les simulateurs iOS, les iPhone réels (liste + lancement/terminaison), ainsi que les appareils/émulateurs Android — inspiré de [`mobile-device-mcp`](https://github.com/srmorete/mobile-device-mcp), réimplémenté en Zig sans Bun/Node/Gradle/Xcode dans le chemin de build.```bash
cd kuri-mobile && zig build && cp zig-out/bin/kuri-mobile ../zig-out/bin/

# The main `kuri` binary forwards android/ios subcommands to kuri-mobile:
kuri ios list-devices                              # sims + real devices (usbmuxd, native)
kuri ios openurl https://example.com               # navigate Safari
kuri ios screenshot out.png                        # auto-picks booted sim
kuri ios launch com.apple.Preferences

kuri android list-devices                          # native Zig adb wire-protocol client
kuri android tap 540 1200
kuri android swipe 100 1500 100 500
kuri android screenshot phone.png
kuri android uitree                                # flat element list via uiautomator dump

Ce qui est natif Zig : protocole hôte adb (sockets libc, cadrage hexadécimal à 4 chiffres sur host:transport:/shell:/exec:), analyseur de l'arbre XML de l'UI Android, client plist usbmuxd ListDevices. Ce qui délègue à des commandes externes : xcrun simctl (Simulateur iOS), xcrun devicectl (lancement/arrêt d'appareils iOS réels). Sans pilote par conception : aucune application sur l'appareil n'est installée, donc les sandboxes run_code et le tap/uitree basé sur XCUITest sur de vrais appareils iOS ne sont intentionnellement pas disponibles. Voir kuri-mobile/README.md pour la matrice de parité complète par rapport à la version amont.


🔒 Tests de sécurité

kuri-agent prend en charge les trajectoires de sécurité natives du navigateur — connectez-vous une fois, puis lancez la reconnaissance et les audits d'en-têtes/cookies sans quitter le terminal.

Trajectoires

Énumérer → Inspecter — après authentification, extraire les cookies d'authentification et vérifier les drapeaux de sécurité :```bash kuri-agent go https://target.example.com/login kuri-agent snap --interactive kuri-agent fill e2 myuser kuri-agent fill e3 mypassword kuri-agent click e4 # submit login

kuri-agent cookies

cookies (3):

session_id domain=.example.com path=/ [Secure] [HttpOnly] [SameSite=Strict]

csrf_token domain=.example.com path=/ [Secure] [!HttpOnly]

tracking domain=.example.com path=/ [!Secure] [!HttpOnly]

root@kitploit:~
**Audit des en-têtes** — vérifie quels en-têtes de sécurité la cible envoie :```bash
kuri-agent go https://target.example.com
kuri-agent headers
# → {"url":"https://...","status":200,"headers":{
#     "content-security-policy":"default-src 'self'",
#     "strict-transport-security":"max-age=31536000",
#     "x-frame-options":"(missing)",
#     "x-content-type-options":"nosniff", ...}}

Audit complet — HTTPS, en-têtes manquants, cookies visibles en JS en une seule fois :```bash kuri-agent audit

→ {"protocol":"https:","url":"https://...","score":6,

"issues":["MISSING:x-frame-options","COOKIES_EXPOSED_TO_JS:2"],

"headers":{"content-security-policy":"default-src 'self'", ...}}

root@kitploit:~
**Trajectoire inter-comptes** — utilisez `eval` pour rejouer les appels API avec différents jetons :```bash
# After login, grab the auth token from localStorage
kuri-agent eval "localStorage.getItem('token')"

# Probe a resource ID with the current session
kuri-agent eval "fetch('/api/assessments/42').then(r=>r.status)"

# Check for IDOR: does a different user's resource return 200 or 403?
kuri-agent eval "fetch('/api/assessments/99').then(r=>r.status)"

Format du rapport de trajectoire

kuri-agent émet du JSON adapté à l'intégration dans un pipeline. Chaque commande de sécurité génère une seule ligne JSON — à faire passer par jq pour le triage :```bash kuri-agent audit | jq '.issues[]' kuri-agent cookies | head -20 kuri-agent headers | jq '.headers | to_entries[] | select(.value == "(missing)") | .key'

root@kitploit:~
---


## 🏗 Architecture```
┌──────────────────────────────────────────────────────────┐
│                     HTTP API Layer                        │
│         (std.http.Server, thread-per-connection)          │
├──────────────┬──────────────────┬────────────────────────┤
│   Browser    │  Crawler Engine  │   kuri-fetch / browse   │
│   Bridge     │                  │   (standalone CLIs)     │
├──────────────┼──────────────────┼────────────────────────┤
│ CDP Client   │ URL Validator    │ std.http.Client         │
│ Tab Registry │ HTML→Markdown    │ QuickJS JS Engine       │
│ A11y Snapshot│ Link Extractor   │ DOM Stubs (Layer 3)     │
│ Ref Cache    │ Text Extractor   │ SSRF Validator          │
│ HAR Recorder │                  │ Colored Renderer        │
│ Stealth JS   │                  │ History + REPL          │
├──────────────┴──────────────────┴────────────────────────┤
│  Chrome Lifecycle Manager                                 │
│  (launch, health-check, auto-restart, port detection)     │
└──────────────────────────────────────────────────────────┘

Modèle mémoire

  • Arena-per-request — toute la mémoire par requête est libérée en un seul appel deinit()
  • Pas de GC — GeneralPurposeAllocator en mode débogage détecte chaque fuite
  • Chaînes de nettoyage appropriées — Launcher → Bridge → CdpClients → HarRecorders → Snapshots → Tabs
  • Protections errdefer — les échecs partiels sont proprement annulés

Cycle de vie de Chrome

ModeComportement
Géré (pas de CDP_URL)Lance Chrome en mode headless, trouve un port CDP libre, supervise, redémarre automatiquement en cas de crash (3 tentatives max), tue à l'arrêt
( défini)

📁 Structure```

kuri/ ├── build.zig # Build system (Zig 0.16.0) ├── build.zig.zon # Package manifest + QuickJS dep ├── src/ │ ├── main.zig # CDP server entry point │ ├── fetch_main.zig # kuri-fetch CLI entry point │ ├── browse_main.zig # kuri-browse CLI entry point │ ├── js_engine.zig # QuickJS wrapper + DOM stubs │ ├── bench.zig # Benchmark harness │ ├── chrome/ │ │ └── launcher.zig # Chrome lifecycle manager │ ├── server/ │ │ ├── router.zig # HTTP route dispatch (40+ endpoints) │ │ ├── middleware.zig # Auth (constant-time comparison) │ │ └── response.zig # JSON response helpers │ ├── bridge/ │ │ ├── bridge.zig # Central state (tabs, CDP, HAR, snapshots) │ │ └── config.zig # Env var configuration │ ├── cdp/ │ │ ├── client.zig # CDP WebSocket client │ │ ├── websocket.zig # WebSocket frame codec │ │ ├── protocol.zig # CDP method constants │ │ ├── actions.zig # High-level CDP actions │ │ ├── stealth.zig # Bot detection bypass │ │ └── har.zig # HAR 1.2 recorder │ ├── snapshot/ │ │ ├── a11y.zig # A11y tree with interactive filter │ │ ├── diff.zig # Snapshot delta diffing │ │ └── ref_cache.zig # eN ref → node ID cache │ ├── crawler/ │ │ ├── validator.zig # SSRF defense, URL validation │ │ ├── markdown.zig # HTML → Markdown (SIMD tag counting) │ │ ├── fetcher.zig # Page fetching │ │ ├── extractor.zig # Readability extraction │ │ └── pipeline.zig # Parallel crawl pipeline │ ├── storage/ │ │ ├── local.zig # Local file writer │ │ └── r2.zig # R2/S3 uploader │ ├── util/ │ │ └── json.zig # JSON helpers │ └── test/ │ ├── harness.zig # Test HTTP client │ ├── integration.zig # Integration tests │ └── merjs_e2e.zig # E2E tests ├── js/ │ ├── stealth.js # Bot detection bypass │ └── readability.js # Content extraction ├── kuri-browser/ # Native Zig rendering experiments └── kuri-mobile/ # iOS + Android device control (Zig-native adb + usbmuxd) ├── src/ │ ├── common/ # io helpers, unified UI tree parser │ ├── android/ # adb wire protocol client, driver, CLI │ └── ios/ # simctl, usbmuxd, devicectl, CLI └── README.md # Full parity matrix vs mobile-device-mcp

root@kitploit:~
---

## ⚙️ Configuration

| Variable d'environnement | Défaut | Description |
|---------|---------|-------------|
| `HOST` | `127.0.0.1` | Adresse de liaison du serveur |
| `PORT` | `8080` | Port du serveur |
| `CDP_URL` | *(none)* | Connexion à un Chrome existant (`ws://...` ou `http://127.0.0.1:9222`) |
| `KURI_SECRET` | *(none)* | Secret d'authentification pour les requêtes API |
| `STATE_DIR` | `.kuri` | Répertoire d'état de la session |
| `REQUEST_TIMEOUT_MS` | `30000` | Délai d'expiration des requêtes HTTP |
| `NAVIGATE_TIMEOUT_MS` | `30000` | Délai d'expiration de la navigation |
| `STALE_TAB_INTERVAL_S` | `30` | Intervalle de nettoyage des onglets obsolètes |
| `NO_COLOR` | *(none)* | Désactiver la sortie CLI colorée |

---

## 💰 Coût en tokens

Pour une tâche de surveillance de 50 pages (d'après les benchmarks de Pinchtab) :

| Méthode | Tokens | Coût ($) | Idéal pour |
|--------|--------|----------|----------|
| `/text` | ~40,000 | $0.20 | Lecture intensive (13× moins cher que les captures d'écran) |
| `/snapshot?filter=interactive&format=compact` | ~40,000 | $0.20 | Interaction d'éléments à faible consommation de tokens |
| `/snapshot` (complet) | ~525,000 | $2.63 | Compréhension complète de la page |
| `/screenshot` | ~100,000 | $1.00 | Vérification visuelle |

---

## 🤝 Contribution

Ouvrez une issue avant de soumettre une grosse PR afin que nous puissions nous aligner sur l'approche.```bash
git clone https://github.com/justrach/kuri.git
cd kuri
zig build test         # 252+ tests must pass
zig build test-fetch   # kuri-fetch tests (69 tests)
zig build test-browse  # kuri-browse tests (22 tests)

See CONTRIBUTORS.md pour les directives.


Crédits

Licence

Apache-2.0

Télécharger l’outil
TERM=dumb
--no-color
  • Sortie fichier — -o / --output avec comptage d'octets + résumé temporel
  • UA personnalisé — option --user-agent
  • Mode silencieux — -q supprime les statuts stderr
  • CommandeAction
    <number>Suivre le lien [N]
    <url>Naviguer (si contient .)
    :go <url>Naviguer vers l'URL
    :back, :bRevenir en arrière dans l'historique
    :forward, :fAller de l'avant
    :reload, :rRecharger la page actuelle
    :links, :lAfficher l'index des liens
    /<term>Rechercher dans la page (surligne les correspondances)
    :search <t>Rechercher dans la page
    :n, :nextRe-surligner la recherche
    :historyAfficher l'historique de navigation
    :help, :hAfficher toutes les commandes
    :quit, :qQuitter
    Externe
    CDP_URL
    Se connecte à un Chrome existant, vérifie l'état via /json/version, ne le tue PAS à l'arrêt
    ProjetCe que nous avons emprunté
    agent-browserSystème de référence @eN, diff de snapshots, patterns d'enregistrement HAR
    PinchtabArchitecture de contrôle de navigateur pour agents IA
    PathikPatterns de crawling haute performance
    QuickJS-ng via mitchellh/zig-quickjs-ngMoteur JS pour kuri-fetch
    LightpandaPionnier des navigateurs headless natifs Zig, patterns de compatibilité CDP
    Zig 0.16.0Tout le stack