Hwatu

io.github.hongnoul由 GitHub 帳號 hongnoul 發布v0.6.0更新於 Oct 24, 2026

Verification browser for coding agents: headless WebKit, DOM eval, screenshots, pixel-diff.

已驗證STDIO僅桌面瀏覽器自動化開發者工具

概覽

AI 產生的概覽

為編碼代理提供無頭 WebKit 瀏覽器,可一次呼叫完成頁面檢查、截圖、像素比對與介面斷言。

可以做什麼
一個常駐的無頭 WebKit 守護行程,透過 MCP、命令列或 Unix 通訊端上的一行 JSON 協定呼叫。工具涵蓋完整驗證流程(開啟、載入、求值、截圖、關閉)、含區域與熱力圖的像素差異評分、以數值表示的動畫、JSON 形式的頁面快照、真實輸入事件、主控台與失敗請求擷取、事件訂閱,以及帶輪詢的一次呼叫斷言。verify_ui 工具把同一個執行器暴露給 MCP 用戶端,challenge 工具可偵測驗證碼並結構化等待與移交。
適用情境
適合代理修改前端程式碼後,需要可量化的證據證明受影響的使用者流程仍然可用,而不是靠肉眼看截圖。也適合需要反覆、平行執行且不搶走使用者焦點的頁面檢查,以及可能需要人工接管即時頁面的情境。它不是讓使用者用自己 Chrome 設定隨意瀏覽的助理。
執行需求
以本機行程透過 stdio 執行;未宣告驗證、環境變數或標頭。需要一個靜態二進位檔以及發行版的 webkitgtk-6.0 套件,不需要 Node.js,也不下載 Chromium。僅限 Linux、僅限桌面。可透過專案安裝腳本、Arch 套件或從原始碼以 Cargo 建置安裝。
安裝前請注意
它本質上是會載入任意頁面並執行 JavaScript 的瀏覽器引擎,造訪的網址應視為不可信。它可以點擊、輸入、捲動與上傳,會改變頁面甚至伺服器端狀態。安裝腳本是從網路直接管線交給 shell 執行,建議改用打包好的二進位檔或從原始碼建置。目前僅支援 Linux,且算繪的是 WebKit 而非 Chromium,可能漏掉引擎相關的缺陷。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Hwatu,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

hwatu is a headless verification harness for coding agents: a warm WebKit daemon driven over CLI, MCP, or one JSON line per Unix-socket connection. Instead of "looks right to me", the agent gets one-call verified page checks in ~35 ms, pixel-diff scores it can climb, animations as numbers, and headless windows that never steal focus, at any parallelism. Jcode drives it natively as its browser backend. When a check needs a human (a CAPTCHA, a judgment call), hwatu focus <id> materializes the same live session as a real window.

Documents

Install

bash
curl -fsSL https://raw.githubusercontent.com/hongnoul/hwatu/main/scripts/install.sh | bash

One static binary plus your distro's webkitgtk-6.0 (the installer checks). On Arch: yay -S hwatu. From source: cargo build --release.

Then connect an agent:

sh
hwatu setup             # detect Claude Code, Cursor, Jcode, or MCP

Verification, not vibes

  • "Pixel-perfect" is a claim. match_percent: 97.49 is a measurement.
  • One tool call per page check, ~35 ms. The same pass through warm-server Playwright is 5 calls and ~9x slower.
  • Headless by default. No window pops, no focus stolen, you keep typing.
  • One static binary + your distro's webkitgtk. No Node, no 170 MB Chromium download.

hwatu setup detects supported coding agents without changing their config. Choose a client explicitly:

sh
hwatu doctorhwatu setup --client claude --scope project --dry-runhwatu setup --client claude --scope projecthwatu demo

Setup is previewable (--dry-run), idempotent, and reversible (--undo). Manual MCP configuration is one portable entry:

json
{ "mcpServers": { "hwatu": { "command": "hwatu", "args": ["mcp"] } } }

Or skip MCP: every command is a short CLI call or one newline-delimited JSON line over a Unix socket.

Connecting hwatu makes its tools available; a project instruction tells the agent when to use them. Add this to AGENTS.md, CLAUDE.md, or Cursor rules:

markdown
## Frontend verification
Use Hwatu after frontend changes. Exercise the affected user journey andverify 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.

Then make the task's proof concrete:

text
Implement display-name editing on /settings. Use Hwatu to enter “Test User,”save it, verify the visible success state, reload, confirm persistence, andreport any console errors.

The verification loop:

sh
hwatu --headless localhost:3000        # its window; you never see ithwatu --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

This loop took a clone of stripe.com's landing page from 85.1% to 98.8% pixel match. Reproduce it: scripts/demo/. A second real-agent scenario (four responsive viewport diffs, then live human hand-off) with evidence manifests: scripts/demo-aiuc/.

A full verification pass (open, load, eval, screenshot, close) is one command, one tool call, ~35 ms median (benchmarks):

sh
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}

For a repeatable repo-level contract that also owns the preflight, local dev server, responsive screenshots, source-staleness check, and evidence report:

sh
hwatu verify .hwatu/about.verify.json

The same executor is exposed to MCP clients as verify_ui, so agent harnesses do not rebuild the orchestration loop. See the agent guide.

Generated HTML in hand and no server? hwatu render is the same one-call pass with the markup as input: no temp file, no python3 -m http.server:

sh
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 clients call subscribe_events for the same stream as notifications/hwatu/event. Full protocol and verification loops: agent guide.

Elsewhere, headless is decided at launch and a human can never see the session. In hwatu it is a window property, switchable live, in both directions: hwatu focus <id> promotes any headless session to a real window for the human, state intact.

challenge is detection and hand-off only, by design: no solver APIs, no token injection, no fingerprint games.

The hand-off destination

The hand-off works because hwatu is also a real browser, built for tiling WMs. hwatu <url> opens a window like your terminal opens a shell (your WM is the tab bar, there is none in the window): mainstream keybinds (ctrl+l, ctrl+f, ctrl+k palette, rebindable), native ad blocking (~119k EasyList rules compiled into WebKit's content-extension engine, zero JS in the request path), Chromium-curve scrolling, and unified shortform controls. Every window shares the one warm daemon (~56 MB per extra window), suspends when unfocused, and crash-restores at its last URL. Honest gaps: no Widevine or passkeys in WebKitGTK. WM configs (hyprland, sway, niri), keybinds, and setup: docs/human.md.

[hwatu as the hand-off destination: quarter-width window spawns and Chromium-curve scrolling in a tiling WM]

Features

  • Headless / background / focused as a per-window property, switchable live
  • Human hand-off: hwatu focus <id> drops the live session into your tiling WM
  • Pixel-diff scoring: match percent + diff regions + heatmap (diff)
  • Animations as numbers: duration, easing, velocity (motion)
  • Deterministic animation frames: pin all animations at time t (seek)
  • Page state as JSON, tokens not pixels (snapshot)
  • Real input events with structured errors (click / type / scroll / upload)
  • JS errors, console output, failed requests (console)
  • Push event subscriptions as JSON lines or MCP notifications (watch)
  • One-call page assertions with polling (expect)
  • CAPTCHA / anti-bot detection with structured wait/resume (challenge)
  • MCP server, plain CLI, and a 1-line JSON socket protocol
  • A real browser as the hand-off destination: keybinds, media, ad blocking, crash restore

Why not Playwright or chrome-devtools-mcp?

Three ways to give an agent a browser:

How it runsWhat it costs the agent loop
Cold library (Playwright, launched per task)engine starts when the script doesfast to call, slow to run: every check pays engine startup; no state survives between tasks
Warm browser (your Chrome + devtools-mcp)a full human browser stays residentresources spent on tabs, extensions, sync, UI you never render, and its windows steal your focus while you work
hwatu"the coldest warm daemon": engine hot, everything else absent8 ms spawns, 35 ms verified checks, invisible until you ask to see it (focus), interruptible in both directions

hwatu keeps exactly what makes checks instant (engine, GPU context, compiled adblock, a prewarmed WebView) and nothing that serves a human unless that human asked for a window. That is why it idles warm without a tab bar, and why a kept-warm Playwright server driven the same way costs 341 ms per client to hwatu's 39 (benchmarks).

The second difference is what comes back. Playwright and chrome-devtools-mcp are automation APIs: they let an agent drive a browser, then hand back raw screenshots and DOM to eyeball. hwatu is a verification browser: the measurement primitives (check, diff, motion, expect) are built in, a window costs 13 ms, and headless is a window property, not a launch mode.

How hwatu compares

Legend: ✅ Yes / built-in · 🟡 Partial / limited · ❌ No

CapabilityPlaywrightchrome-devtools-mcphwatu
Verify pass (load + eval + screenshot), warm in-process82 msn/a35 ms
Verify pass as a warm service (fresh client per check)341 msn/a39 ms
Tool calls per verify pass551
Pixel-diff score + regions + heatmap🟡 1❌✅
Animations as numbers, pinned mid-flight❌ 2🟡 3✅
Headless ↔ headed on a live session❌❌✅
Human hand-off mid-session, state intact❌❌✅
No focus stealing at N parallel agents🟡 4🟡 4✅
CAPTCHA detection + structured wait/resume❌❌✅
No Node, no per-version browser download❌❌✅

1 toHaveScreenshot compares against stored goldens: pass/fail for test suites, not a score an agent can climb.

2 Standard practice is to disable animations or fast-forward to the end state to avoid flakes.

3 Raw CDP can query animation state, but there is no numeric summary of easing/velocity/keyframes.

4 Fine headless; every headed window pops and takes focus.

Comparison reflects each project at the time of writing; corrections are welcome. Honest caveats: Playwright still wins cold start (190 vs 435 ms, paid once per boot) and memory; hwatu renders WebKit not Chromium (keep a Playwright matrix in CI for engine-specific bugs), and it is Linux-only today. Full head-to-head data and methodology: docs/benchmarks.md.

What about Claude in Chrome? Different category. Claude in Chrome is one agent product driving your Chrome through an extension, sharing your profile, tabs, and focus, callable by nothing else. hwatu is a client-agnostic daemon any agent calls over CLI/MCP, with its own warm WebKit engine, headless by default, and verification primitives built in. Use Claude in Chrome to let Claude browse alongside you; use hwatu when agents need cheap, repeated, measurable page checks.

Feedback

A successful check, a failed install, a missing keybind, and a site that broke are all useful signals. Share a two-minute use report or report a bug.


MIT licensed. Linux. WebKitGTK 6.

來源:README.md,提交 e8068a8

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.6.0最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分