hwatu

by hongnoul

Not rated
GitHub

About

Visual verification browser for coding agents: daemon-based headless WebKit with snapshot, click/type, console capture, screenshots, and pixel-diff scoring. One static binary, Linux/Wayland. MCP server via `hwatu mcp` (stdio).

Details

Author
hongnoul
Categories
Developer Tools

Setup

Install hwatu in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/hongnoul/hwatu

Follow the installation instructions in the repository README, then restart your MCP client.

hwatu is a visual verification harness for coding agents, built as a WebKit daemon. Instead of "looks right to me", your agent getsone-call verified page checks in ~35 ms,pixel-diff scores it can climb,animations as numbers, andheadless windows that never steal your focus, at any parallelism.

For human-in-the-loop tasks (e.g. Captcha), hwatu features a lightweight visual verification frontend renderer written in WebKit and a caller function. For tiling WMs (Hyprland, sway,niri, i3), hwatu is intended to replace your primary daily browser. Our current goal is to provide scrolling short-form content experience in mobile-level framerate.

- Vision: durable product principles, native platform strategy, swarm model
-
Agent guide: protocol, primitives, verification loops
-
Human guide: daily driving hwatu in a tiling WM, keybinds, media, hand-off
-
Benchmarks: every number, measured, with methodology
-
Roadmap: portfolio priorities and product boundaries

- AI verification
-
Tiling-WM browser
-
Shared platform

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

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

hwatu setup # agent: detect Claude Code, Cursor, Jcode, or MCP hwatu localhost:3000 # human: open a window like you open a terminal

- STOP your agent claiming "pixel-perfect." Make it prove 97.49%.
- STOP paying 5 tool calls per page check.hwatu checkis one call, ~35 ms (beats warm-server Playwright ~9x).
- STOP browser windows stealing your focus. Headless by default, you keep typing.
- STOP shipping 170 MB of Chromium. One static binary + your distro's webkitgtk.

hwatu setupdetects supported coding agents and prints the available connections without changing their config. Choose a client explicitly when you are ready:

hwatu doctor hwatu setup --client claude --scope project --dry-run hwatu setup --client claude --scope project hwatu demo

Setup is previewable, idempotent, and reversible with the same client and scope plus--undo. Manual MCP configuration remains one portable entry:

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

Or skip MCP entirely: 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 toAGENTS.md,CLAUDE.md, Cursor rules, or the equivalent for your harness:

## 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.

Then make the task's proof concrete:

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.

The verification loop, real commands, real output:

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

We ran this loop against a clone of stripe.com's landing page: an agent took it from85.1% to 98.8% pixel match. Reproduce it:scripts/demo/. A second, real-agent scenario against AIUC (four responsive viewport diffs followed by live human hand-off) is reproducible with evidence manifests fromscripts/demo-aiuc/.

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

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:

The same executor is exposed to MCP clients asverify_ui, so different agent harnesses do not need to rebuild the orchestration loop. See theagent guide.

Generated HTML in hand and no server?hwatu renderis the same one-call pass with the markup as input: no temp file, nopython3 -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",...}}

Everywhere else, headless is decided at launch and a human can never see the session at any price. In hwatu it's a window property, switchable live, in both directions. And because hwatu is also the browser you already live in, the hand-off lands in a window that behaves like every other window on your desk, not a viewer bolted on for emergencies.

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

The hand-off works because hwatu is also a real browser, one 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), with mainstream keybinds (ctrl+l,ctrl+f,ctrl+kpalette, all rebindable via dotfile), native ad blocking (~119k EasyList rules compiled into WebKit's content-extension engine, zero JS in the request path), Chromium-curve scrolling, unmuted autoplay, a blur-shield that took Shorts from ~34 to ~95 fps, and one shortform control scheme (arrows snap exactly one video, Space pauses, hold ArrowRight for 2x) across Reels, Shorts, and TikTok. High framerates help oneshotting websites with complicated scroll-anchored animation logic (e.g. scale.com). Because of this reason, hwatu is optimized for consuming short-form content with much less resources than what you would have needed with Chromium or Firefox. The demo video below shows why hwatu is an excellent alternative browser option for your system, especially for tiling WMs:

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, so keep a fallback bound for Netflix. Ready-made WM configs (hyprland,sway,niri), the full keybind table, and setup:[docs/human.md.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.