Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
kuri — 面向 AI 智能体的浏览器自动化、网页爬取,以及 iOS + Android 设备控制。Zig 原生、token 高效的 CDP 快照、HAR 录制、原生 adb 线协议客户端,以及独立抓取器。 | Kitploit
工具/GitHubGitHub/justrach/kuri
信息收集Web安全渗透测试移动安全网络爬虫
GitHubjustrach/kuri

kuri

面向 AI 智能体的浏览器自动化、网页爬取,以及 iOS + Android 设备控制。Zig 原生、token 高效的 CDP 快照、HAR 录制、原生 adb 线协议客户端,以及独立抓取器。

查看仓库
3501816天前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

Kuri

Kuri 🌰

稳定版 许可证 Zig node_modules 状态

安装```sh

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

root@kitploit:~
支持 macOS arm64/x86_64 与 Linux x86_64/arm64。单二进制文件,无运行时依赖。

直接下载:[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)

---

**面向 AI 智能体的浏览器自动化与网页爬取。使用 Zig 编写。零 Node.js 依赖。**

CDP 自动化 · A11y 快照 · HAR 录制 · 独立抓取器 · 交互式终端浏览器 · Agentic CLI · 安全测试 · iOS + Android 设备控制

[快速开始](#-quick-start) · [基准测试](#-benchmarks) · [kuri-agent](#-kuri-agent) · [安全测试](#-security-testing) · [API](#-http-api) · [技能](#-skills) · [更新日志](https://github.com/justrach/kuri/blob/HEAD/CHANGELOG.md)

> **为什么团队转向 Kuri:** 当前 Apple Silicon 的 `ReleaseFast` 构建每个二进制文件保持在 2 MB 以下,2026-04-23 在 Google Flights 上的全新复测测得完整 `kuri-agent` 循环(`go→snap→click→snap→eval`)消耗 **3,392 个 token**。在引用百分比之前,应在相同环境中重新运行跨工具对比。

---

## 为什么 Kuri 适合智能体

大多数浏览器工具是为 QA 工程师构建的。Kuri 是为智能体循环而构建的:读取页面、保持 token 成本低廉、基于稳定引用执行操作,然后继续前进。

- **135 个 HTTP 端点** — 与 agent-browser 和 browser-use 完全对等,涵盖从 React 检视到 Core Web Vitals。
- **比 agent-browser 节省 7-12% 的 token**,得益于 `@eN` 引用格式和零前缀渲染。
- **轻 44 倍的观察** — 同一 Google Flights 页面,使用 `/page/state`(48 个 token)对比完整快照(2,124 个 token)。
- **批量执行** — `POST /batch` 在一次 HTTP 调用中发送 N 条命令,消除 N-1 次往返和 N-1 次 LLM 轮次。
- **React 兼容** — 受信任的 CDP 鼠标事件和逐字符按键事件可触发 React 18/19 的 `onClick` 和 `onChange`。

### 快照 token 数:Google Flights `SIN → TPE`

2026-05-24 在本工作区全新复测,使用 `wc -c` 和 `chars/4` 近似值衡量。

| 工具 / 模式 | 字符数 | 约 token 数 | 备注 |
|---|---:|---:|---|
| `kuri snap`(完整) | 8,499 | **2,124** | 所有节点 + 交互式引用 |
| `kuri snap`(仅交互) | ~3,000 | **~750** | 最适合智能体循环 |
| `kuri /page/state` | 190 | **48** | 轻量观察(url、标题、滚动百分比、计数) |
| agent-browser snap(估算) | ~9,183 | **~2,295** | `[ref=e0]` 格式开销 |

### token 效率:kuri vs agent-browser

| 页面 | kuri token 数 | agent-browser token 数 | 节省 |
|---|---:|---:|---|
| example.com | 40 | 35 | -13%(简单页面,agent-browser 跳过根节点) |
| Hacker News | 386 | ~440 | **减少 12%** |
| Google Flights SIN→TPE | 2,124 | ~2,295 | **减少 7%** |

节省来源于 kuri 的紧凑格式:
- `@e0` 引用(3 字符)对比 `[ref=e0]`(9 字符)
- 每行无 `- ` 前缀(节省 2 字符 × 行数)
- 相同缩进,相同节点过滤

### 完整工作流成本:`go → snap → click → snap → eval`

| 工具 | 每轮循环 token 数 |
|---|---:|
| **kuri-agent** | **~3,400** |
| 使用 `/page/state` 代替第二次 snap | **~1,700** |
| 使用 `POST /batch`(全部一次调用) | **~1,700**(相同 token 数,1 次 HTTP 调用代替 5 次) |

### kuri vs libretto

[libretto](https://github.com/saffron-health/libretto)(Playwright + Node)是每步 token 成本上最接近的竞争对手。2026-07-04 进行了同台对比 — 相同的 Chrome、相同的标签页、真实的 `tiktoken` `o200k_base` 计数(完整方法与复现:**[benchmarks/libretto_comparison.md](https://github.com/justrach/kuri/blob/HEAD/benchmarks/libretto_comparison.md)**)。诚实的对比结果:

| 维度 | 胜者 | 详情 |
|---|---|---|
| 每次调用的延迟 | **kuri** | 4–117 ms 对比 1,344–1,500 ms(**快 13–376 倍** — 常驻服务器对比每条命令一个 Node 进程) |
| 快照 token 数,典型页面 | **kuri** | 简单页面 61 对比 151(2.5 倍),文章 265 对比 363(1.37 倍)— 更紧凑的语法 |
| 快照 token 数,大型列表 | 平分 | kuri 默认 4,424 对比 813 — kuri 输出全部 259 个引用,libretto 默认截断。使用 `limit=5` 时 kuri 渲染 555 个 token(**比 libretto 少 1.46 倍**),34 个引用 + `… +45 more` 标记 |
| 轨迹(feed,9 次点击) | **kuri**,勉强 | 898 对比 939 个 token(`limit=5` 基线 + 差异循环对比执行循环)— 持平到微弱优势;早间 5.1 倍的劣势来自未截断的基线 |
| 重复运行 | **libretto** | 将轨迹编译为 Playwright 脚本 → 0 token 重放;kuri 每次运行都要重新支付循环成本 |

**kuri 从研究 libretto 中获得的改进**(均随本版本发布):差异优先循环(`take_snapshot_diff`,约 38 个 token/步);自适应差异在导航时回退为带 `! page replaced` 头部的完整快照;只含身份信息的删除行;截图写入磁盘(返回路径,字节永不进入上下文);通过 MCP 提供 `get_page_state`;以及在将 `parseA11yNodes` 重写为真正的 DFS 树遍历之后 — **可选列表截断**(`/snapshot?limit=N`,每次截断运行输出一行 `… +K more`)、**限定作用域的重新捕获**(`scope=@ref`)和**层级缩进**,这些同时以 `uid`/`limit` 形式暴露在 MCP `take_snapshot` 中。那个用朴素的完整重新快照需要 44,285 个 token 的 9 次点击 feed 轨迹,使用截断基线 + 差异后只需 **898** 个 token — 便宜 49 倍,并超过了 libretto 的 939。

> 上方的旧表格使用 `chars/4` token 近似值;libretto 对比使用真实 `tiktoken` 计数。在引用百分比之前,请在您自己的环境中重新运行跨工具数据。

### 二进制体积与内存

在 Apple M4 Pro、macOS 26.4.1 上测得。当前二进制文件使用 `-Doptimize=ReleaseFast` 构建。

| 二进制文件 | 当前体积 |
|---|---:|
| `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 在 Zig 0.16 迁移期间保持平稳

以当前 `v0.4.3` `ReleaseFast` 构建为基准,使用 `/usr/bin/time -l` 测量。

| 命令 | `v0.4.3` 平均最大 RSS |
|---|---:|
| `kuri-fetch --version` | ~2.45 MiB |
| `kuri-browse --version` | ~2.45 MiB |
| `kuri-fetch --quiet --dump markdown http://example.com/` | ~9.17 MiB |

## 问题所在

每个浏览器自动化工具都会拖入 Playwright(约 300 MB)、Node.js 运行时和一整套 npm 依赖。您的 AI 智能体只想读取页面、点击按钮,然后继续前进。
**Kuri 是单个 Zig 二进制文件。** 四种模式,零运行时:```
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)

📦 安装

一行安装(macOS / Linux)```sh

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

root@kitploit:~
检测您的平台,下载正确的二进制文件,并安装到 `~/.local/bin`。
下载内容来自 Kuri 自行管理的 `release-channel` 分支。macOS 二进制文件使用开发者 ID 证书进行本地签名。GitHub Release 资产镜像了这些相同的 tarball。

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

在安装时,为您的平台下载正确的原生二进制文件。

发布通道

Kuri 的稳定二进制文件位于 release-channel 分支上,并直接从 GitHub raw URL 提供。

  • 稳定安装程序:https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh
  • 稳定清单:https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/latest.json
  • 分支视图:https://github.com/justrach/kuri/tree/release-channel/stable
  • 直接下载模式:https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/<version>/kuri-<version>-<target>.tar.gz

手动安装

从 稳定发布清单 或 GitHub Releases 页面 下载适用于您平台的 tarball,并将其解压到您的 $PATH 中。

稳定安装 URL:```sh curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh

root@kitploit:~
The manifest includes exact asset URLs plus SHA-256 checksums for `aarch64-linux`, `x86_64-linux`, `aarch64-macos`, and `x86_64-macos`.

### Platform support

| Platform | Status |
|---|---|
| macOS (`aarch64`, `x86_64`) | Prebuilt binaries, signed + notarized |
| Linux (`aarch64`, `x86_64`) | Prebuilt binaries |
| Windows (`x86_64`) | **Experimental — cross-compile only.** `zig build -Dtarget=x86_64-windows-gnu` is CI-verified, but Chrome automation, daemonization, signal-based shutdown, HAR recording, and the file-backed auth store are all stubbed with `error.UnsupportedOnWindows` at runtime. Use **WSL2** if you need the real feature set. Tracked at [#153](https://github.com/justrach/kuri/issues/153). |

Kuri leans on POSIX primitives (`fork`, `clock_gettime`, raw sockets) in several spots, so a full native Windows port is real work. The compile-level baseline above lets the `--version`/`--help` paths and pure in-memory operations run; the gnarly bits (Chrome, sockets, daemonize) need real Win32 implementations before they come off the stub list. If you want to take any of those on, +1 [#153](https://github.com/justrach/kuri/issues/153) or open a PR.

### Build from source

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

The manifest includes exact asset URLs plus SHA-256 checksums for `aarch64-linux`, `x86_64-linux`, `aarch64-macos`, and `x86_64-macos`.

### 平台支持

| 平台 | 状态 |
|---|---|
| macOS(`aarch64`、`x86_64`) | 预构建二进制,已签名并公证 |
| Linux(`aarch64`、`x86_64`) | 预构建二进制 |
| Windows(`x86_64`) | **实验性 — 仅支持交叉编译。** `zig build -Dtarget=x86_64-windows-gnu` 已经 CI 验证,但 Chrome 自动化、守护进程化、基于信号的关闭、HAR 录制以及基于文件的认证存储都在运行时以 `error.UnsupportedOnWindows` 桩实现。如果你需要完整功能,请使用 **WSL2**。跟踪于 [#153](https://github.com/justrach/kuri/issues/153)。 |

Kuri 在多个地方依赖 POSIX 原语(`fork`、`clock_gettime`、原始套接字),因此完整的原生 Windows 移植是一项艰巨的工作。上述编译级基线允许 `--version`/`--help` 路径和纯内存操作运行;而棘手的部分(Chrome、套接字、守护进程化)需要真正的 Win32 实现才能从桩列表中移除。如果你想承担其中任何一项,请给 [#153](https://github.com/justrach/kuri/issues/153) +1 或提交 PR。

### 从源码构建

需要 [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

⚡ 快速开始

要求: Zig ≥ 0.16.0 · Chrome/Chromium(用于 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:~
### 首次运行,最短路径```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

以会话优先的代理循环

对于代理风格的 HTTP 使用,优先使用会话头加上 /tab/new、/page/info 和 /snapshot,而不是在每次调用中重复 tab_id。```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:~
在 `tools/kuri_harness.py` 处还有一个轻量级实验性包装器,如果你想在相同的 HTTP 接口之上使用 Python 辅助函数。

如果你已经通过远程调试运行 Chrome,可以将 `CDP_URL` 设置为 WebSocket 或 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

用 4 条命令浏览 vercel.com```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:~
---

## 🌐 HTTP API

所有端点均返回 JSON。可通过 `KURI_SECRET` 环境变量进行可选身份验证。**135 个端点** — 与 agent-browser 和 browser-use 完全对齐。

### 核心

| Path | 描述 |
|------|-------------|
| `GET /health` | 服务器状态、标签页数量、版本 |
| `GET /tabs` | 列出所有已注册的标签页 |
| `GET /discover` | 通过 CDP 自动发现 Chrome 标签页 |
| `GET /tab/current` | 获取或设置某个 `X-Kuri-Session` 的当前标签页 |
| `GET /page/info` | 活动标签页的实时 URL/标题/就绪状态/视口/滚动位置 |
| `GET /page/state` | 紧凑页面观测:url、标题、滚动百分比、视口、表单/链接/图片/输入框数量 |
| `POST /batch` | 在一次 HTTP 调用中执行多个命令 — 返回结果数组 |
| `GET /browdie` | 🌰(彩蛋) |

### 浏览器控制

| Path | 参数 | 描述 |
|------|--------|-------------|
| `GET /navigate` | `tab_id`、`url` | 将标签页导航到 URL |
| `GET /tab/new` | `url`、`activate`、`wait` | 创建新标签页,并可选择初始化/设为当前标签页 |
| `GET /tab/close` | `tab_id` | 关闭标签页 |
| `GET /window/new` | `url`、`activate`、`wait` | 创建新的窗口/标签页目标 |
| `GET /snapshot` | `tab_id`、`filter`、`format` | 带有 `eN` 引用的 A11y 树快照。使用 `filter=interactive&format=compact` 实现低 token 的代理循环。 |
| `GET /text` | `tab_id` | 提取页面文本 |
| `GET /screenshot` | `tab_id`、`format`、`quality`、`save` | 捕获截图(base64);`save=true` 会将 PNG 写入 `STATE_DIR/screenshots` 并改为返回 `{path,bytes}` |
| `GET /screenshot/annotated` | `tab_id` | 带编号元素标签的截图 |
| `GET /screenshot/diff` | `tab_id`、`baseline` | 当前截图与基线截图之间的视觉差异 |
| `GET /action` | `tab_id`、`ref`、`action`、`value` | 按引用执行点击/输入/填充/选择/滚动/悬停/双击/勾选/取消勾选/失焦 |
| `GET /evaluate` | `tab_id`、`expression` | 执行 JavaScript |
| `GET /evalhandle` | `tab_id`、`expression` | 执行 JS,返回 objectId 句柄(而非值) |
| `GET /close` | `tab_id` | 关闭标签页 + 清理 |
| `GET /bringtofront` | `tab_id` | 将标签页置于前台 |

### 操作

| Path | 参数 | 描述 |
|------|--------|-------------|
| `GET /clear` | `ref` | 清空输入字段的值 |
| `GET /selectall` | `ref` | 选中输入框/可编辑内容中的所有文本 |
| `GET /setvalue` | `ref`、`value` | 直接设置输入值(绕过键盘事件) |
| `GET /dispatch` | `ref`、`type` | 在元素上派发自定义 DOM 事件 |
| `GET /boundingbox` | `ref` | 获取元素边界矩形(x、y、width、height、centerX、centerY) |
| `GET /getattribute` | `ref`、`name` | 按名称获取元素属性 |
| `GET /inputvalue` | `ref` | 获取当前输入元素的值 |
| `GET /element/state` | `ref`、`check` | 快速布尔判断:`exists`、`visible`、`enabled`、`checked` |
| `GET /find-element` | `text`/`role`/`label`/`placeholder`/`testid` | 语义定位器 — 无需快照即可查找元素 |
| `GET /highlight` | `ref` 或 `selector` | 使用覆盖层高亮元素 |

### 鼠标与触摸

| Path | 参数 | 描述 |
|------|--------|-------------|
| `GET /mouse/move` | `x`、`y` | 将鼠标移动到坐标 |
| `GET /mouse/down` | `x`、`y`、`button` | 按下鼠标按键 |
| `GET /mouse/up` | `x`、`y`、`button` | 松开鼠标按键 |
| `GET /mouse/wheel` | `x`、`y`、`deltaX`、`deltaY` | 鼠标滚轮滚动 |
| `GET /tap` | `x`、`y` | 触摸点击(touchStart + touchEnd) |
| `GET /swipe` | `startX`、`startY`、`endX`、`endY` | 触摸滑动手势 |
| `GET /drag` | `src_ref`、`tgt_ref` | 将元素拖到目标位置 |

### 键盘

| Path | 参数 | 描述 |
|------|--------|-------------|
| `GET /keyboard/type` | `tab_id`、`text` | 通过键盘事件输入文本 |
| `GET /keyboard/inserttext` | `tab_id`、`text` | 直接插入文本 |
| `GET /keydown` | `tab_id`、`key` | 按键按下事件 |
| `GET /keyup` | `tab_id`、`key` | 按键松开事件 |

### 内容提取

| Path | 描述 |
|------|-------------|
| `GET /markdown` | 将页面转换为 Markdown |
| `GET /links` | 提取所有链接 |
| `GET /dom/query` | CSS 选择器查询 |
| `GET /dom/html` | 获取元素 HTML |
| `GET /dom/attributes` | 获取元素属性 |
| `GET /pdf` | 将页面打印为 PDF |
| `GET /find` | 页内文本搜索 |

### 等待

| Path | 参数 | 描述 |
|------|--------|-------------|
| `GET /wait` | `selector`、`text`、`url`、`state`、`visible`、`timeout` | 等待选择器/文本/URL 模式/网络空闲/加载状态 |
| `GET /wait/function` | `expression`、`timeout` | 等待任意 JS 表达式为真 |
| `GET /wait/download` | `timeout` | 等待文件下载完成 |

### 对话框处理

| Path | 描述 |
|------|-------------|
| `GET /dialog/auto` | 自动处理所有 JS 对话框(接受或取消) |
| `GET /dialog/accept` | 接受当前对话框(可带提示文本) |
| `GET /dialog/dismiss` | 取消当前对话框 |

### 网络与 HAR

| Path | 描述 |
|------|-------------|
| `GET /har/start` | 开始记录网络流量 |
| `GET /har/stop` | 停止并返回 HAR 1.2 JSON |
| `GET /har/status` | 记录状态 + 条目数量 |
| `GET /har/replay` | 带 curl/fetch/python 代码片段的 API 映射 |
| `GET /cookies` | 获取 cookies |
| `GET /cookies/set` | 设置 cookies |
| `GET /cookies/delete` | 删除 cookies |
| `GET /cookies/clear` | 清除所有 cookies |
| `GET /headers` | 设置自定义请求头 |
| `GET /intercept/start` | 开始请求拦截 |
| `GET /intercept/stop` | 停止请求拦截 |
| `GET /intercept/requests` | 列出被拦截的请求 |
| `GET /request/detail` | 获取某个请求 ID 的响应体 |
| `GET /response/body` | 获取 URL 并返回响应体 |
| `GET /network` | 网络流量统计 |
| `GET /download` | 触发文件下载 |

### 导航与状态

| Path | 描述 |
|------|-------------|
| `GET /back` | 浏览器后退 |
| `GET /forward` | 浏览器前进 |
| `GET /reload` | 重新加载页面 |
| `GET /stop` | 停止页面加载 |
| `GET /pushstate` | 通过 history.pushState 进行 SPA 导航 |
| `GET /storage/local` | 获取/设置 localStorage |
| `GET /storage/session` | 获取/设置 sessionStorage |
| `GET /storage/local/clear` | 清除 localStorage |
| `GET /storage/session/clear` | 清除 sessionStorage |
| `GET /session/save` | 保存浏览器会话 |
| `GET /session/load` | 恢复浏览器会话 |
| `GET /session/list` | 列出已保存的会话 |
| `GET /setcontent` | 直接设置页面 HTML(POST) |

### 认证配置文件

| Path | 描述 |
|------|-------------|
| `GET /auth/profile/save` | 将 cookies + 存储保存为命名认证配置文件 |
| `GET /auth/profile/load` | 将命名认证配置文件恢复到标签页中 |
| `GET /auth/profile/list` | 列出已保存的认证配置文件 |
| `GET /auth/profile/delete` | 删除已保存的认证配置文件 |
| `GET /auth/extract` | 提取认证令牌(JWT、cookies、headers) |
| `GET /set/credentials` | 设置 HTTP 基本身份验证凭据 |

在 macOS 上,认证配置文件机密存储在用户钥匙串(Keychain)中。

### 模拟

| Path | 参数 | 描述 |
|------|--------|-------------|
| `GET /emulate` | 设备类型、屏幕尺寸 | 设备模拟 |
| `GET /set/viewport` | `width`、`height` | 设置视口尺寸 |
| `GET /set/useragent` | `ua` | 设置用户代理 |
| `GET /set/media` | `media` | 模拟媒体类型 |
| `GET /set/offline` | `offline` | 切换离线模式 |
| `GET /geolocation` | `lat`、`lng` | 覆盖地理位置 |
| `GET /timezone` | `timezone` | 覆盖时区(例如 `America/New_York`) |
| `GET /locale` | `locale` | 覆盖区域设置(例如 `en-US`) |
| `GET /permissions` | `name`、`state` | 授予/拒绝权限(地理位置、通知、剪贴板) |

### 脚本与注入

| Path | 描述 |
|------|-------------|
| `GET /script/inject` | 向页面注入 JavaScript(跨导航持久保留) |
| `GET /initscript/remove` | 移除先前注入的初始化脚本 |
| `GET /addstyle` | 注入 CSS 样式表 |
| `GET /expose` | 向页面 JS 上下文暴露一个命名函数 |

### React 检查

| Path | 描述 |
|------|-------------|
| `GET /react/tree` | 通过 DevTools 钩子获取 React 组件树 |
| `GET /react/inspect` | React 组件的 props 和 state |
| `GET /react/renders` | React 渲染跟踪(开始/停止) |
| `GET /react/suspense` | React Suspense 边界状态 |

### 录制与性能

| Path | 描述 |
|------|-------------|
| `GET /recording/start` | 记录用户操作(点击、输入、导航) |
| `GET /recording/stop` | 停止录制并返回操作日志 |
| `GET /vitals` | 核心 Web Vitals(LCP、CLS、FID、TTFB、FCP、domInteractive) |
| `GET /perf/lcp` | Largest Contentful Paint 时间 |
| `GET /trace/start` | 开始性能跟踪 |
| `GET /trace/stop` | 停止跟踪 |
| `GET /profiler/start` | 启动 JS 分析器 |
| `GET /profiler/stop` | 停止分析器 |

### 调试

| Path | 描述 |
|------|-------------|
| `GET /debug/enable` | 启用页面内调试 HUD 和可选的冻结模式 |
| `GET /debug/disable` | 禁用页面内调试 HUD |
| `GET /inspect` | 元素检查 |
| `GET /errors` | 收集 JS 错误 |
| `GET /console` | 读取控制台日志 |
| `GET /frames` | 列出页面框架 |
| `GET /frame` | 按名称或 URL 切换到 iframe 上下文 |
| `GET /mainframe` | 切回主框架 |
| `GET /diff/snapshot` | 与该标签页上次调用的紧凑 `+`/`~`/`-` 差异对比 — token 高效的操作循环(别名为 `/snapshot/changes`)。当发生大规模变化时,回退到带有 `! page replaced` 头部的完整快照。 |
| `GET /diff/url` | 并排比较两个 URL(导航、快照、差异) |

### 流式传输

| Path | 描述 |
|------|-------------|
| `GET /screencast/start` | 开始屏幕录制 |
| `GET /screencast/stop` | 停止屏幕录制 |
| `GET /video/start` | 开始视频捕获 |
| `GET /video/stop` | 停止视频捕获 |
| `GET /ws/start` | WebSocket 隧道启动 |
| `GET /ws/stop` | WebSocket 隧道停止 |

### 代理友好的循环

最简单顺畅的服务器循环是:

1. `GET /tab/new?url=...`
2. `GET /page/state`(轻量)或 `GET /snapshot?filter=interactive&format=compact`(完整)
3. `GET /action?action=click&ref=eN`
4. 重复 — 或使用 `POST /batch` 在一次调用中完成多步操作

`url` 和 `expression` 查询参数会进行百分号解码。发送 `X-Kuri-Session: my-agent` 可在服务器端持久化标签页上下文。
---

## 🧠 技能

该仓库包含一个用户可扩展的技能区域:

- `skills/kuri-skill.md` 是基础的 Kuri HTTP 代理技能
- `skills/custom/` 保留给你自己项目特定的技能
- `skills/custom/hackernews-page-2.md` 是一个具体的自定义技能示例
- `.claude/skills/kuri-server/SKILL.md` 与 Claude 风格的仓库技能保持同步

基础技能现在还说明了应使用哪种浏览器路径:

- `kuri` HTTP API:使用会话、快照、操作、HAR、cookies 和截图的生产级 Chrome/CDP 自动化
- `kuri-fetch`:独立的不依赖 Chrome 的 fetch/文本提取
- `kuri-browse`:交互式终端浏览
- `kuri-agent`:面向 Kuri 服务器的可脚本化 CLI 自动化
- `kuri-browser/`:用于一致性工作的实验性独立 Zig 原生浏览器运行时

对于实验性浏览器 CLI:```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 暴露了 Chrome 风格的 HTTP 发现机制,以及一个用于协议冒烟测试的最小 WebSocket JSON-RPC 路由器。运行时求值返回由 QuickJS 支持的 V8 形态的 CDP 远程对象;这不会引入 V8 依赖,也尚不完全兼容 Playwright/Puppeteer。

kuri-browser 中的截图目前委托给主 Kuri/CDP 渲染器。先启动 ./zig-out/bin/kuri,然后:```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` 捕获 PNG 基线和 JPEG 候选文件,写入较小的文件,并报告节省的字节数。当前在 `https://example.com` 上的本地测量:`20,523` 字节 PNG 对比 `18,183` 字节 JPEG 质量 50,节省 `2,340` 字节,即 `11%`。

### 高级

| Path | 描述 |
|------|-------------|
| `GET /diff/snapshot` | 与上一个快照的紧凑 `+`/`~`/`-` 差异(代理操作循环) |
| `GET /emulate` | 设备模拟 |
| `GET /geolocation` | 设置地理位置 |
| `POST /upload` | 文件上传 |
| `GET /script/inject` | 注入 JavaScript |
| `GET /intercept/start` | 开始请求拦截 |
| `GET /intercept/stop` | 停止拦截 |
| `GET /screenshot/annotated` | 带元素注释的截图 |
| `GET /screenshot/diff` | 截图之间的视觉差异 |
| `GET /screencast/start` | 开始屏幕录制 |
| `GET /screencast/stop` | 停止屏幕录制 |
| `GET /video/start` | 开始视频录制 |
| `GET /video/stop` | 停止视频录制 |
| `GET /console` | 获取控制台消息 |
| `GET /stop` | 停止页面加载 |
| `GET /get` | 直接 HTTP 获取(服务端) |
| `GET /scrollintoview` | 将引用的元素滚动到视图中 |
| `GET /drag` | 从一个引用拖到另一个引用 |
| `GET /keyboard/type` | 使用按键事件输入文本 |
| `GET /keyboard/inserttext` | 直接插入文本 |
| `GET /keydown` | 派发 keydown 事件 |
| `GET /keyup` | 派发 keyup 事件 |
| `GET /wait` | 等待就绪状态或元素条件 |
| `GET /tab/close` | 关闭标签页 |
| `GET /highlight` | 按引用或选择器高亮元素 |
| `GET /errors` | 获取页面/运行时错误 |
| `GET /set/offline` | 切换离线网络模拟 |
| `GET /set/media` | 设置模拟媒体特性 |
| `GET /set/credentials` | 设置 HTTP 基本认证凭据 |
| `GET /find` | 在当前页面中查找文本匹配 |
| `GET /trace/start` | 开始 Chrome 跟踪 |
| `GET /trace/stop` | 停止跟踪并返回跟踪数据 |
| `GET /profiler/start` | 启动 JS 分析器 |
| `GET /profiler/stop` | 停止 JS 分析器 |
| `GET /inspect` | 检查元素或页面状态 |
| `GET /set/viewport` | 设置视口大小 |
| `GET /set/useragent` | 覆盖用户代理 |
| `GET /dom/attributes` | 获取元素属性 |
| `GET /frames` | 列出框架树 |
| `GET /network` | 检查网络状态/请求 |

---

## 🛡️ 隐身与机器人规避

Kuri 在启动时自动应用反检测补丁——无需手动配置。

### 应用的内容

- **`Page.addScriptToEvaluateOnNewDocument`** — 隐身补丁在任何页面 JS 之前运行
- **navigator.webdriver = false** — 在 Chromium 层面隐藏自动化标志(`--disable-blink-features=AutomationControlled`)
- **WebGL/Canvas/AudioContext 伪装** — 破解基于指纹的检测
- **UA 轮换** — 5 个真实的 Chrome/Safari/Firefox 用户代理
- **chrome.csi/chrome.loadTimes** — 针对 Akamai 特定检查的存根

### 机器人拦截检测

Navigate 自动检测拦截并返回结构化回退:```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

检测:Akamai、Cloudflare、PerimeterX、DataDome、通用验证码。

代理支持```bash

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

root@kitploit:~
### 已测试站点

| 站点 | 防护 | 结果 |
|------|-----------|--------|
| Singapore Airlines | Akamai WAF | ✅ 已绕过(v0.4.0 之前曾被拦截) |
| Shopee SG | 自定义反欺诈 | ✅ 页面加载,重定向至登录 |
| Google Flights | 无 | ✅ 完整交互 |
| Booking.com | PerimeterX | ⚠️ 需要代理 |

---

## 🔧 kuri-fetch

独立的 HTTP 抓取器 — 无需 Chrome、无需 Playwright、无需 npm。以约 2 MB 的二进制文件发布,内置 QuickJS 用于执行 JavaScript。```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

功能

  • 5 种输出模式 — markdown, html, links, text, json
  • QuickJS JS 引擎 — --js 执行内联 <script> 标签
  • DOM 存根 — document.querySelector, getElementById, window.location, document.title, console.log, setTimeout(SSR 风格)
  • SSRF 防御 — 阻止私有 IP、元数据端点、非 HTTP 协议
  • 彩色输出 — 支持 NO_COLOR, , , TTY 检测

🌐 kuri-browse

交互式终端浏览器 — 从终端浏览网页。无需 Chrome。```bash zig build browse # build + run

kuri-browse https://example.com

root@kitploit:~
I'm ready to translate the content, but no actual Markdown content was provided in the input after "INPUT:". Please provide the chunk text to translate, and I'll proceed with the translation into Chinese following all the specified rules.```
🌰 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

命令

功能

  • 彩色 Markdown 渲染 — 标题、链接、代码块、粗体、引用块
  • 编号链接 — 每个链接都有 [N],输入数字即可跟随
  • 导航历史 — 像真实浏览器一样后退/前进
  • 页内搜索 — /term 高亮所有匹配项
  • 相对 URL 解析 — 跨页面自然地跟随链接
  • 智能过滤 — 跳过 javascript: 和 mailto: href

🤖 kuri-agent

用于 Chrome 自动化的可脚本化 CLI — 从终端或 shell 脚本逐条命令驱动浏览器。通过 ~/.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:~
### 命令

| 命令 | 描述 |
|---------|-------------|
| `tabs [--port N]` | 列出 Chrome 标签页 |
| `use <ws_url>` | 附加到一个标签页(保存会话) |
| `open [url] [--port N]` | 打开新标签页(可选择导航至 url) |
| `status` | 显示当前会话 |
| `go <url>` | 导航至 URL |
| `snap [--interactive] [--json] [--text] [--depth N]` | A11y 快照,保存 `eN` 引用 |
| `click <ref>` | 按引用点击元素(CDP 鼠标事件,兼容 React) |
| `type <ref> <text>` | 向元素输入文本(逐字符按键事件,兼容 React) |
| `fill <ref> <text>` | 填充输入值 |
| `select <ref> <value>` | 选择下拉选项 |
| `hover <ref>` | 悬停在元素上 |
| `focus <ref>` | 聚焦元素 |
| `scroll` | 滚动页面 |
| `viewport [width height]` | 获取或设置视口尺寸 |
| `eval <js>` | 执行 JavaScript |
| `text [selector]` | 获取页面文本 |
| `shot [--out file.png]` | 截图 |
| `back` | 后退 |
| `forward` | 前进 |
| `reload` | 重新加载当前页面 |
| `cookies` | 列出带安全标志的 Cookie |
| `headers` | 检查安全响应头 |
| `audit` | 完整安全审计 |
| `storage [local\|session\|all]` | 导出 localStorage / sessionStorage |
| `jwt` | 从 Cookie 和存储中提取并解码 JWT |
| `fetch <method> <url> [--data <json>]` | 使用页面 Cookie 进行带认证的 fetch |
| `probe <url-template> <start> <end>` | IDOR 探测:遍历 URL 中的数字 ID |
| `grab <ref>` | 点击引用,拦截 `window.open`,在标签页内跟随重定向 |
| `wait-for-tab [--port N]` | 轮询新标签页,自动切换会话 |
| `stealth` | 应用反检测补丁 |
| `set-header <name> <value>` | 为所有请求添加自定义标头 |
| `show-headers` | 显示已存储的额外标头 |
| `clear-headers` | 移除所有额外标头 |
---

## 📱 kuri-mobile(iOS + Android)

用于驱动 iOS 模拟器、真实 iPhone(列出 + 启动/终止)以及 Android 设备/模拟器的原生 Zig CLI——灵感来自 [`mobile-device-mcp`](https://github.com/srmorete/mobile-device-mcp),使用 Zig 重新实现,构建路径中不涉及 Bun/Node/Gradle/Xcode。```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

原生 Zig: adb 主机协议(libc 套接字,通过 host:transport:/shell:/exec: 进行 4 位十六进制帧封装)、Android XML UI 树解析器、usbmuxd ListDevices plist 客户端。 外部调用: xcrun simctl(iOS 模拟器)、xcrun devicectl(iOS 真机启动/终止)。 设计上免驱动: 不会在设备上安装任何应用,因此在真实 iOS 设备上,run_code 沙箱和基于 XCUITest 的 tap/uitree 故意不可用。请参阅 kuri-mobile/README.md 查看与上游对比的完整功能对等矩阵。


🔒 安全测试

kuri-agent 支持浏览器原生的安全操作流程——登录一次,即可在不离开终端的情况下执行侦察与 header/cookie 审计。

操作流程

枚举 → 检查——认证完成后,导出认证 cookie 并检查安全标志:```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:~
**标头审计** — 检查目标发送了哪些安全标头:```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", ...}}

全面审计 — HTTPS、缺失的标头、JS 可见的 Cookie,一次性完成:```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:~
**跨账户轨迹** — 使用 `eval` 以不同令牌重放 API 调用:```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)"

轨迹报告格式

kuri-agent 输出适合流水线集成的 JSON。每个安全命令都会输出单行 JSON — 可通过管道传递给 jq 进行分类:```bash kuri-agent audit | jq '.issues[]' kuri-agent cookies | head -20 kuri-agent headers | jq '.headers | to_entries[] | select(.value == "(missing)") | .key'

root@kitploit:~
---


## 🏗 架构```
┌──────────────────────────────────────────────────────────┐
│                     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)     │
└──────────────────────────────────────────────────────────┘

内存模型

  • 每次请求一个 Arena — 所有按请求分配的内存通过一次 deinit() 调用释放
  • 无 GC — 调试模式下的 GeneralPurposeAllocator 可捕获每一次泄漏
  • 正确的清理链 — Launcher → Bridge → CdpClients → HarRecorders → Snapshots → Tabs
  • errdefer 保护 — 部分失败时干净回滚

Chrome 生命周期

模式行为
受管(未设置 CDP_URL)启动无头 Chrome,寻找空闲 CDP 端口,监督运行,崩溃时自动重启(最多重试 3 次),关闭时终止
外部(设置了 CDP_URL)连接到现有 Chrome,通过 /json/version 进行健康检查,关闭时不终止

📁 结构```

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:~
---

## ⚙️ 配置

| Env Var | 默认值 | 描述 |
|---------|---------|-------------|
| `HOST` | `127.0.0.1` | 服务器绑定地址 |
| `PORT` | `8080` | 服务器端口 |
| `CDP_URL` | *(none)* | 连接到现有的 Chrome(`ws://...` 或 `http://127.0.0.1:9222`) |
| `KURI_SECRET` | *(none)* | API 请求的认证密钥 |
| `STATE_DIR` | `.kuri` | 会话状态目录 |
| `REQUEST_TIMEOUT_MS` | `30000` | HTTP 请求超时 |
| `NAVIGATE_TIMEOUT_MS` | `30000` | 导航超时 |
| `STALE_TAB_INTERVAL_S` | `30` | 过期标签页清理间隔 |
| `NO_COLOR` | *(none)* | 禁用彩色 CLI 输出 |

---

## 💰 Token 成本

对于一个 50 页的监控任务(来自 Pinchtab 基准测试):

| 方法 | Tokens | 成本($) | 最适合 |
|--------|--------|----------|----------|
| `/text` | ~40,000 | $0.20 | 适合阅读为主(比截图便宜 13 倍) |
| `/snapshot?filter=interactive&format=compact` | ~40,000 | $0.20 | 低 Token 元素交互 |
| `/snapshot` (完整) | ~525,000 | $2.63 | 完整页面理解 |
| `/screenshot` | ~100,000 | $1.00 | 视觉验证 |

---

## 🤝 贡献

在提交大型 PR 之前,请先打开一个 issue,以便我们就方案达成一致。

---```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 for guidelines.


致谢

许可证

Apache-2.0

下载工具
TERM=dumb
--no-color
  • 文件输出 — -o / --output,带字节数和计时摘要
  • 自定义 UA — --user-agent 标志
  • 安静模式 — -q 抑制 stderr 状态
  • 命令操作
    <number>跟随链接 [N]
    <url>导航(如果包含 .)
    :go <url>导航到 URL
    :back, :b返回历史记录
    :forward, :f前进
    :reload, :r重新获取当前页面
    :links, :l显示链接索引
    /<term>在页面中搜索(高亮匹配项)
    :search <t>在页面中搜索
    :n, :next重新高亮搜索
    :history显示导航历史
    :help, :h显示所有命令
    :quit, :q退出
    ProjectWhat we borrowed
    agent-browser@eN ref 系统、快照差异比较、HAR 记录模式
    Pinchtab面向 AI 代理的浏览器控制架构
    Pathik高性能爬取模式
    QuickJS-ng via mitchellh/zig-quickjs-ngkuri-fetch 的 JS 引擎
    LightpandaZig 原生无头浏览器先驱,CDP 兼容模式
    Zig 0.16.0整个技术栈