关于 hwatu
hwatu 是面向编码 Agent 的无头 UI 验证工具,基于常驻的 WebKit 守护进程,可通过命令行、MCP 或 Unix 套接字调用。它为 Agent 提供单次调用的页面检查、像素差异评分和动画数值化结果,并可将无头会话切换为真实窗口交由人工接管。
主要功能
- 01无头、后台与有窗口模式可实时切换
- 02像素差异评分、差异区域与热力图
- 03动画时长、缓动与速度的数值输出
- 04页面状态以 JSON 形式返回
- 05JavaScript 错误、控制台输出与请求失败记录
- 06CAPTCHA 检测与结构化等待、恢复
适用场景
- 01对前端修改进行单次页面验证并截图
- 02将本地页面与参考站点做像素级对比
- 03检查页面动画的缓动与时长是否符合预期
- 04遇到 CAPTCHA 时将会话交由人工接管
MCP 相关
hwatu 以 MCP 服务的形式运行,向 MCP 客户端暴露 verify_ui、expect 等验证工具,并通过 subscribe_events 推送事件通知。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
hwatu 是面向编码 Agent 的无头验证框架:通过 CLI、MCP 或每条 Unix 套接字连接发送一行 JSON,即可驱动一个常驻的 WebKit 守护进程。无需再说“我觉得看起来没问题”,Agent 可以获得一次调用即可完成的页面验证,耗时约 35 ms、可逐步优化的像素差异分数、以数字呈现的动画效果,以及永不抢占焦点的无头窗口,并支持任意并行度。Jcode 原生将其用作 browser 后端。当验证需要人工介入(例如 CAPTCHA 或需要判断的情况)时,执行 hwatu focus <id> 即可将同一实时会话显示为真实窗口。
文档
- Agent 指南:协议、基本功能、验证循环
- 基准测试:所有数据、测量结果和方法
- 愿景:持久的产品原则、原生平台策略
- 人工指南:将 hwatu 用作平铺式 WM 浏览器、快捷键、交接
- 路线图:产品组合优先级和产品边界
- macOS 研究:实测 WKWebView 探测、竞品调研,以及 macOS 仅用于验证的原因
- 持续改进:激活指标、反馈循环、每周节奏
- 发布工具包:可复用文案、渠道和衡量计划
安装
curl -fsSL https://raw.githubusercontent.com/hongnoul/hwatu/main/scripts/install.sh | bash
一个静态二进制文件,加上发行版提供的 webkitgtk-6.0(安装程序会检查)。在 Arch 上:yay -S hwatu。从源码构建:cargo build --release。
然后连接 Agent:
hwatu setup # detect Claude Code, Cursor, Jcode, or MCP
验证,而非凭感觉
- “像素级完美”是一种说法。
match_percent: 97.49是一项测量结果。 - 每页检查只需调用一次工具,耗时约 35 ms。用预热的 Playwright 服务端进行同样的检查需要调用 5 次,速度慢约 9 倍。
- 默认无头运行。不弹出窗口、不抢焦点,你可以继续输入。
- 一个静态二进制文件 + 你的发行版提供的 webkitgtk。无需 Node,也无需下载 170 MB 的 Chromium。
hwatu setup 会检测受支持的编码 Agent,且不会更改它们的配置。明确选择客户端:
hwatu doctor
hwatu setup --client claude --scope project --dry-run
hwatu setup --client claude --scope project
hwatu demo
设置可预览(--dry-run)、可重复执行且不会产生副作用,并且可撤销(--undo)。手动配置 MCP 只需一条可移植的配置项:
{ "mcpServers": { "hwatu": { "command": "hwatu", "args": ["mcp"] } } }
也可以跳过 MCP:每条命令都是一次简短的命令行调用,或通过 Unix 套接字发送一行以换行符分隔的 JSON。
连接 hwatu 后,即可使用其工具;项目指令会告诉 Agent 何时使用它们。将以下内容添加到 AGENTS.md、CLAUDE.md 或 Cursor 规则中:
## Frontend verification
Use Hwatu after frontend changes. Exercise the affected user journey and
verify its intended visible, navigational, or persisted result with `expect`.
A successful click or clean console is not proof of success. Check `console`
for additional JavaScript and request failures after verifying the outcome.
然后把任务的验证方式具体化:
Implement display-name editing on /settings. Use Hwatu to enter “Test User,”
save it, verify the visible success state, reload, confirm persistence, and
report any console errors.
验证循环:
hwatu --headless localhost:3000 # its window; you never see it
hwatu --headless staging.example.com # the reference
hwatu diff --id 2 --other 1 --heatmap /tmp/heat.png
# {"match_percent":85.13,"regions":[{"x":0,"y":160,"w":2048,...}]}
hwatu motion --id 1 # the reference's animations, as numbers
# easing cubic-bezier(0.25,1,0.5,1), 300ms, marquee 29.78px/s ...
# ...agent edits code...
hwatu diff --id 2 --other 1
# {"match_percent":97.49} # climbing beats guessing
这个循环将 stripe.com 落地页的克隆从 85.1% 提升到 98.8% 的像素匹配度。复现步骤见:scripts/demo/。另一个真实 Agent 场景(四种响应式视口差异,然后交接给真人),附带证据清单: scripts/demo-aiuc/。
一次完整的验证流程(打开、加载、求值、截图、关闭)只需一条命令、一次工具调用,中位耗时约 35 ms (基准测试):
hwatu check localhost:5173 --eval 'document.title' --shot=/tmp/after.png
# {"title":"My App","eval":"My App","shot":"/tmp/after.png",
# "console":[...],"load_ms":13,"total_ms":35}
如需一份可重复执行的仓库级契约,同时负责预检、本地开发服务、响应式截图、源文件过时检查和证据报告:
hwatu verify .hwatu/about.verify.json
同一个执行器也作为 verify_ui 提供给 MCP 客户端,因此 Agent 执行框架无需重新构建编排循环。请参阅Agent 指南。
已有生成的 HTML,但没有服务?hwatu render 可将标记作为输入,执行同样的一次调用流程:无需临时文件,也无需运行 python3 -m http.server:
echo '<h1>generated</h1>' | hwatu render --stdin --shot=/tmp/gen.png
# {"rendered":true,"shot":"/tmp/gen.png","load_ms":5,"total_ms":28}
# React to load, console, download, and window events without polling.
hwatu watch --kinds load,console
# {"event":"load","seq":1,"window_id":7,"data":{"state":"started",...}}
MCP 客户端调用 subscribe_events,即可接收与 notifications/hwatu/event 相同的事件流。完整协议和验证循环见Agent 指南。
在其他浏览器中,无头模式在启动时便已确定,人无法查看会话。而在 hwatu 中,无头模式是可实时双向切换的窗口属性:hwatu focus <id> 可将任意无头会话切换为真人可见的窗口,同时保留原有状态。
challenge 按设计仅用于检测和交接:不提供求解器 API、不注入令牌,也不做指纹伪装。
交接目标
hwatu 之所以能实现交接,是因为它本身也是一款为平铺式窗口管理器打造的真正浏览器。hwatu <url> 会像终端打开 shell 一样打开一个窗口(你的窗口管理器就是标签栏,窗口内不设标签栏):常见快捷键(ctrl+l、ctrl+f、ctrl+k 打开调色板,均可重新绑定)、原生广告拦截(约 11.9 万条 EasyList 规则编译进 WebKit 的内容扩展引擎,请求路径中没有任何 JS)、Chromium 曲线滚动,以及统一的短视频控件。所有窗口共用一个预热的守护进程(每增加一个窗口约占用 56 MB),失去焦点时会暂停,崩溃后会恢复到上次访问的网址。坦诚说明限制:WebKitGTK 不支持 Widevine 或通行密钥。窗口管理器配置(hyprland、sway、niri)、快捷键和设置见:
docs/human.md。
功能
- 无头/后台/聚焦作为每个窗口的属性,可实时切换
- 人工接管:
hwatu focus <id>将实时会话交给你的平铺式 WM - 像素差异评分:匹配百分比 + 差异区域 + 热力图(
diff) - 将动画转化为数值:时长、缓动、速度(
motion) - 确定性动画帧:将所有动画固定在时间 t(
seek) - 将页面状态保存为 JSON,而非像素(
snapshot) - 真实输入事件与结构化错误(
click/type/scroll/upload) - JS 错误、控制台输出、失败的请求(
console) - 将推送事件订阅为 JSON 行或 MCP 通知(
watch) - 通过轮询进行单次调用的页面断言(
expect) - CAPTCHA / 反机器人检测,支持结构化等待/恢复(
challenge) - MCP 服务、纯命令行,以及单行 JSON 套接字协议
- 以真实浏览器作为接管目标:快捷键绑定、媒体、广告拦截、崩溃恢复
为什么不选 Playwright 或 chrome-devtools-mcp?
向 Agent 提供浏览器有三种方式:
| 运行方式 | 对 Agent 循环的代价 | |
|---|---|---|
| 冷启动库(Playwright,每项任务启动一次) | 脚本启动时引擎才启动 | 调用很快,运行很慢:每次检查都要等待引擎启动;任务之间不会保留状态 |
| 常驻浏览器(你的 Chrome + devtools-mcp) | 完整的人工浏览器持续运行 | 资源耗在标签页、扩展、同步,以及你永远不会渲染的 UI 上;工作时,其窗口还会抢占你的焦点 |
| hwatu | “最冷的常驻守护进程”:引擎常热,其余一概不存在 | 8 ms 即可启动,35 ms 完成验证检查;只有你要求查看时才会显示(focus),且双方都可随时中断 |
hwatu 只保留能让检查即时完成的部分(引擎、GPU 上下文、 已编译的广告拦截器、预热的 WebView),除非有人要求打开 窗口,否则不会保留任何服务于人工用户的内容。这就是为什么它 能在没有标签栏的情况下保持预热,也解释了为什么用相同方式 驱动的常驻 Playwright 服务每个客户端需要 341 ms,而 hwatu 只需 39 ms (基准测试)。
第二个区别在于返回的内容。Playwright 和
chrome-devtools-mcp 是自动化 API:它们让 Agent 操控浏览器,
然后返回原始屏幕截图和 DOM,供人查看。hwatu 是一款验证浏览器:
内置测量原语(check、
diff、motion、expect),打开窗口只需 13 ms,
无头是窗口属性,而非启动模式。
hwatu 对比
图例: ✅ 支持/内置 · 🟡 部分支持/有限 · ❌ 不支持
| 功能 | Playwright | chrome-devtools-mcp | hwatu |
|---|---|---|---|
| 验证通过(加载 + 求值 + 截图),进程内预热 | 82 ms | 不适用 | 35 ms |
| 验证通过,作为预热的服务运行(每次检查都使用新客户端) | 341 ms | 不适用 | 39 ms |
| 每次验证调用的工具数 | 5 | 5 | 1 |
| 像素差异评分 + 区域 + 热力图 | 🟡 1 | ❌ | ✅ |
| 将动画表示为数值,并固定在播放中途 | ❌ 2 | 🟡 3 | ✅ |
| 在运行中的会话中切换无头 ↔ 有头模式 | ❌ | ❌ | ✅ |
| 会话中途交接给人工,状态保持不变 | ❌ | ❌ | ✅ |
| N 个 Agent 并行时不抢占焦点 | 🟡 4 | 🟡 4 | ✅ |
| CAPTCHA 检测 + 结构化等待/恢复 | ❌ | ❌ | ✅ |
| 无需 Node,无需按版本下载浏览器 | ❌ | ❌ | ✅ |
1 toHaveScreenshot 会与已存储的基准图比较:为测试套件给出通过/失败结果,而不是 Agent 可以逐步提升的评分。
2 通常会禁用动画或快进到最终状态,以避免不稳定的测试结果。
3 原始 CDP 可以查询动画状态,但不会提供缓动、速度或关键帧的数值摘要。
4 无头模式没问题;每个有头窗口都会弹出并抢占焦点。
此比较反映了撰写时各项目的情况; 欢迎指正。坦诚地说:Playwright 的冷启动仍然更快 (190 vs 435 ms,每次启动仅需支付一次),内存占用也更低;hwatu 使用 WebKit 而非 Chromium 渲染(请在 CI 中保留 Playwright 测试矩阵, 以覆盖引擎特有的错误),而且目前仅支持 Linux。完整的 直接对比数据和方法: docs/benchmarks.md。
Claude in Chrome 怎么样? 这是不同类别的产品。Claude in Chrome 是一款 Agent 产品,通过扩展驱动你的 Chrome,共享你的个人资料、标签页和焦点,且无法被其他工具调用。hwatu 则是客户端无关的守护进程,任何 Agent 都可以通过 CLI/MCP 调用;它内置预热的 WebKit 引擎,默认以无头模式运行,并提供验证功能。使用 Claude in Chrome,让 Claude 与你一起浏览;当 Agent 需要低成本、重复且可量化的页面检查时,使用 hwatu。
反馈
一次成功的检查、一次失败的安装、一个缺失的快捷键绑定,以及一个出现问题的网站,都是有用的信号。请分享一份两分钟的 使用报告,或报告错误。
采用 MIT 许可证。Linux。WebKitGTK 6。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。

