{
  "markdown": "<div align=\"center\">\n\n# hwatu\n\n[![Latest Release](https://badgen.net/github/release/hongnoul/hwatu?icon=github)](https://github.com/hongnoul/hwatu/releases)\n[![License: AGPL-3.0](https://img.shields.io/badge/license-AGPL--3.0-blue?style=flat-square)](LICENSE)\n[![CI](https://github.com/hongnoul/hwatu/actions/workflows/ci.yml/badge.svg)](https://github.com/hongnoul/hwatu/actions/workflows/ci.yml)\n\n**Your agents are blind without hwatu**\n\n<a href=\"https://github.com/hongnoul/hwatu/releases/download/readme-assets/demo-aiuc.mp4\"><img src=\"https://github.com/hongnoul/hwatu/releases/download/readme-assets/demo-aiuc.webp\" alt=\"An agent verifies aiuc.com with hwatu: one command returns pixel-match scores for four responsive viewports, then the live page pops into view for human hand-off\" width=\"800\"></a>\n\n</div>\n\nhwatu is a visual verification harness for coding agents, built as a\nWebKit daemon. Instead of \"looks right to me\", your agent gets\n**one-call verified page checks in ~35 ms**, **pixel-diff scores it\ncan climb**, **animations as numbers**, and **headless windows that\nnever steal your focus**, at any parallelism.\n\nFor human-in-the-loop tasks (e.g. Captcha), hwatu features a lightweight\nvisual verification frontend renderer written in WebKit and a caller\nfunction. For tiling WMs (Hyprland, sway, **niri**, i3), hwatu is\nintended to replace your primary daily browser. Our current goal is to\nprovide scrolling short-form content experience in mobile-level framerate.\n\n## Documents\n\n- [Vision](VISION.md): durable product principles, native platform strategy, swarm model\n- [Agent guide](docs/agents.md): protocol, primitives, verification loops\n- [Human guide](docs/human.md): daily driving hwatu in a tiling WM, keybinds, media, hand-off\n- [Benchmarks](docs/benchmarks.md): every number, measured, with methodology\n- [Roadmap](docs/roadmap.md): portfolio priorities and product boundaries\n  - [AI verification](docs/roadmaps/verification.md)\n  - [Tiling-WM browser](docs/roadmaps/browser.md)\n  - [Shared platform](docs/roadmaps/platform.md)\n- [Continuous improvement](docs/continuous-improvement.md): activation metric, feedback loop, weekly cadence\n- [Launch kit](docs/launch-kit.md): reusable copy, channels, and measurement plan\n\n## Install\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/hongnoul/hwatu/main/scripts/install.sh | bash\n```\n\nOne static binary plus your distro's `webkitgtk-6.0` (the installer\nchecks). On Arch: `yay -S hwatu`. From source: `cargo build --release`.\n\nThen pick your door, or take both:\n\n```sh\nhwatu setup             # agent: detect Claude Code, Cursor, Jcode, or MCP\nhwatu localhost:3000    # human: open a window like you open a terminal\n```\n\n## Real eyes for your coding agent\n\n- **STOP your agent claiming \"pixel-perfect.\" Make it prove 97.49%.**\n- **STOP paying 5 tool calls per page check. `hwatu check` is one call, ~35 ms (beats warm-server Playwright ~9x).**\n- **STOP browser windows stealing your focus. Headless by default, you keep typing.**\n- **STOP shipping 170 MB of Chromium. One static binary + your distro's webkitgtk.**\n\n`hwatu setup` detects supported coding agents and prints the\navailable connections without changing their config. Choose a client\nexplicitly when you are ready:\n\n```sh\nhwatu doctor\nhwatu setup --client claude --scope project --dry-run\nhwatu setup --client claude --scope project\nhwatu demo\n```\n\nSetup is previewable, idempotent, and reversible with the same client\nand scope plus `--undo`. Manual MCP configuration remains one\nportable entry:\n\n```json\n{ \"mcpServers\": { \"hwatu\": { \"command\": \"hwatu\", \"args\": [\"mcp\"] } } }\n```\n\nOr skip MCP entirely: every command is a short CLI call or one\nnewline-delimited JSON line over a Unix socket.\n\nConnecting hwatu makes its tools available; a project instruction\ntells the agent when to use them. Add this to `AGENTS.md`,\n`CLAUDE.md`, Cursor rules, or the equivalent for your harness:\n\n```markdown\n## Frontend verification\n\nUse Hwatu after frontend changes. Exercise the affected user journey and\nverify its intended visible, navigational, or persisted result with `expect`.\nA successful click or clean console is not proof of success. Check `console`\nfor additional JavaScript and request failures after verifying the outcome.\n```\n\nThen make the task's proof concrete:\n\n```text\nImplement display-name editing on /settings. Use Hwatu to enter “Test User,”\nsave it, verify the visible success state, reload, confirm persistence, and\nreport any console errors.\n```\n\nThe verification loop, real commands, real output:\n\n```sh\nhwatu --headless localhost:3000        # its window; you never see it\nhwatu --headless staging.example.com   # the reference\n\nhwatu diff --id 2 --other 1 --heatmap /tmp/heat.png\n# {\"match_percent\":85.13,\"regions\":[{\"x\":0,\"y\":160,\"w\":2048,...}]}\n\nhwatu motion --id 1                    # the reference's animations, as numbers\n# easing cubic-bezier(0.25,1,0.5,1), 300ms, marquee 29.78px/s ...\n\n# ...agent edits code...\n\nhwatu diff --id 2 --other 1\n# {\"match_percent\":97.49}              # climbing beats guessing\n```\n\nWe ran this loop against a clone of stripe.com's landing page: an\nagent took it from **85.1% to 98.8% pixel match**. Reproduce it:\n[scripts/demo/](scripts/demo/). A second, real-agent scenario against\nAIUC (four responsive viewport diffs followed by live human hand-off)\nis reproducible with evidence manifests from\n[scripts/demo-aiuc/](scripts/demo-aiuc/).\n\nA full verification pass (open, load, eval, screenshot, close) is\n**one command, one tool call, ~35 ms median**\n([benchmarks](docs/benchmarks.md)):\n\n```sh\nhwatu check localhost:5173 --eval 'document.title' --shot=/tmp/after.png\n# {\"title\":\"My App\",\"eval\":\"My App\",\"shot\":\"/tmp/after.png\",\n#  \"console\":[...],\"load_ms\":13,\"total_ms\":35}\n```\n\nFor a repeatable repo-level contract that also owns the preflight, local dev\nserver, responsive screenshots, source-staleness check, and evidence report:\n\n```sh\nhwatu verify .hwatu/about.verify.json\n```\n\nThe same executor is exposed to MCP clients as `verify_ui`, so different agent\nharnesses do not need to rebuild the orchestration loop. See the\n[agent guide](docs/agents.md#verification-jobs-one-contract-for-every-harness).\n\nGenerated HTML in hand and no server? `hwatu render` is the same\none-call pass with the markup as input: no temp file, no\n`python3 -m http.server`:\n\n```sh\necho '<h1>generated</h1>' | hwatu render --stdin --shot=/tmp/gen.png\n# {\"rendered\":true,\"shot\":\"/tmp/gen.png\",\"load_ms\":5,\"total_ms\":28}\n\n# React to load, console, download, and window events without polling.\nhwatu watch --kinds load,console\n# {\"event\":\"load\",\"seq\":1,\"window_id\":7,\"data\":{\"state\":\"started\",...}}\n```\n\nMCP clients can call `subscribe_events` for the same stream as\n`notifications/hwatu/event`. See the full [agent guide](docs/agents.md),\nincluding a larger copy-paste policy and verification loops.\n\nEverywhere else, headless is decided at launch and a human can never\nsee the session at any price. In hwatu it's a window property,\nswitchable live, in both directions. And because hwatu is also the\nbrowser you already live in, the hand-off lands in a window that\nbehaves like every other window on your desk, not a viewer bolted on\nfor emergencies.\n\n`challenge` is detection and hand-off only, by design: no solver\nAPIs, no token injection, no fingerprint games.\n\n## Agents loop, you watch some reels\n\nThe hand-off works because hwatu is also a real browser, one built\nfor tiling WMs. `hwatu <url>` opens a window like your terminal opens\na shell (your WM is the tab bar, there is none in the window), with\nmainstream keybinds (`ctrl+l`, `ctrl+f`, `ctrl+k` palette, all\nrebindable via dotfile), native ad blocking (~119k EasyList rules\ncompiled into WebKit's content-extension engine, zero JS in the\nrequest path), Chromium-curve scrolling, unmuted autoplay, a\nblur-shield that took Shorts from ~34 to ~95 fps, and one shortform\ncontrol scheme (arrows snap exactly one video, Space pauses, hold\nArrowRight for 2x) across Reels, Shorts, and TikTok. High framerates\nhelp oneshotting websites with complicated scroll-anchored animation\nlogic (e.g. scale.com). Because of this reason, hwatu is optimized for\nconsuming short-form content with much less resources than what you\nwould have needed with Chromium or Firefox. The demo video below shows\nwhy hwatu is an excellent alternative browser option for your system,\nespecially for tiling WMs:\n\n<a href=\"https://github.com/hongnoul/hwatu/releases/download/readme-assets/demo-shortform.mp4\"><img src=\"https://github.com/hongnoul/hwatu/releases/download/readme-assets/demo-shortform.webp\" alt=\"hwatu daily driving: quarter-width window spawns, buttery Chromium-curve scrolling, and one-keypress-one-reel shortform controls on Instagram Reels\" width=\"800\"></a>\n\nEvery window shares the one warm daemon (~56 MB per extra window),\nsuspends when unfocused, and crash-restores at its last URL. Honest\ngaps: no Widevine or passkeys in WebKitGTK, so keep a fallback bound\nfor Netflix. Ready-made WM configs\n([hyprland](examples/hyprland.conf), [sway](examples/sway.config),\n[niri](examples/niri.kdl)), the full keybind table, and setup:\n[docs/human.md](docs/human.md).\n\n## Features\n\n- [x] Headless / background / focused as a *per-window* property, switchable live\n- [x] Human hand-off: `hwatu focus <id>` drops the live session into your tiling WM\n- [x] Pixel-diff scoring: match percent + diff regions + heatmap (`diff`)\n- [x] Animations as numbers: duration, easing, velocity (`motion`)\n- [x] Deterministic animation frames: pin all animations at time t (`seek`)\n- [x] Page state as JSON, tokens not pixels (`snapshot`)\n- [x] Real input events with structured errors (`click` / `type` / `scroll` / `upload`)\n- [x] JS errors, console output, failed requests (`console`)\n- [x] Push event subscriptions as JSON lines or MCP notifications (`watch`)\n- [x] One-call page assertions with polling (`expect`)\n- [x] CAPTCHA / anti-bot detection with structured wait/resume (`challenge`)\n- [x] MCP server, plain CLI, and a 1-line JSON socket protocol\n- [x] A real browser for humans: mainstream keybinds, media-correct video, native ad blocking, crash restore\n\n## Why not Playwright or chrome-devtools-mcp?\n\nThere are three ways to give an agent a browser, and two of them are bad at it:\n\n| | How it runs | What it costs the agent loop |\n|---|---|---|\n| **Cold library** (Playwright, launched per task) | engine starts when the script does | fast to *call*, slow to *run*: every check pays engine startup; no state survives between tasks |\n| **Warm browser** (your Chrome + devtools-mcp) | a full human browser stays resident | resources spent on tabs, extensions, sync, UI you never render, and its windows steal *your* focus while you work |\n| **hwatu** | **\"the coldest warm daemon\"**: engine hot, everything else absent | 8 ms spawns, 35 ms verified checks, invisible until *you* ask to see it (`focus`), interruptible in both directions |\n\nhwatu keeps exactly what makes checks instant (engine, GPU context,\ncompiled adblock, a prewarmed WebView) and nothing that serves a\nhuman sitting in front of it *unless that human asked for a window*.\nThat's why it idles warm without a tab bar, and why a kept-warm\nPlaywright server driven the same way still costs 341 ms per client\nto hwatu's 39 ([benchmarks](docs/benchmarks.md)).\n\nThe second difference is what comes back. Playwright and\nchrome-devtools-mcp are, at their core, automation APIs: they let an\nagent *drive* a browser, then hand back raw screenshots and DOM for\nthe agent to eyeball. hwatu is a *verification* browser: the\nmeasurement primitives are built in, and the browser itself is a warm\ndaemon where a window costs 13 ms and headless is a window property,\nnot a launch mode.\n\nThe same pass through Playwright's warm in-process CDP connection,\nits best case, is 82 ms and five API calls. Shaped like hwatu\nactually runs (a fresh client each check against a kept-warm engine),\nPlaywright's pass is **341 ms vs hwatu's 39**: hwatu is a warm daemon\nby design, Playwright is a library you have to keep warm yourself.\n\n## How hwatu compares\n\n**Legend:** ✅ Yes / built-in  ·  🟡 Partial / limited  ·  ❌ No\n\n| Capability | Playwright | chrome-devtools-mcp | hwatu |\n| --- | :---: | :---: | :---: |\n| Verify pass (load + eval + screenshot), warm in-process | 82 ms | n/a | **35 ms** |\n| Verify pass as a warm *service* (fresh client per check) | 341 ms | n/a | **39 ms** |\n| Tool calls per verify pass | 5 | 5 | **1** |\n| Pixel-diff score + regions + heatmap | 🟡 1 | ❌ | ✅ |\n| Animations as numbers, pinned mid-flight | ❌ 2 | 🟡 3 | ✅ |\n| Headless ↔ headed on a *live* session | ❌ | ❌ | ✅ |\n| Human hand-off mid-session, state intact | ❌ | ❌ | ✅ |\n| No focus stealing at N parallel agents | 🟡 4 | 🟡 4 | ✅ |\n| CAPTCHA detection + structured wait/resume | ❌ | ❌ | ✅ |\n| No Node, no per-version browser download | ❌ | ❌ | ✅ |\n\n1 `toHaveScreenshot` compares against stored goldens: pass/fail for\ntest suites, not a score an agent can climb.\n\n2 Standard practice is to disable animations or fast-forward to the\nend state to avoid flakes.\n\n3 Raw CDP can query animation state, but there is no numeric\nsummary of easing/velocity/keyframes.\n\n4 Fine headless; every headed window pops and takes focus.\n\n> Comparison reflects each project at the time of writing;\n> corrections are welcome. Honest caveats: Playwright still wins\n> cold start (190 vs 435 ms, paid once per boot) and memory; hwatu\n> renders WebKit not Chromium (keep a Playwright matrix in CI for\n> engine-specific bugs), and it is Linux-only today. Full\n> head-to-head data and methodology:\n> [docs/benchmarks.md](docs/benchmarks.md).\n\n**What about Claude in Chrome?** Different category. Claude in\nChrome is Claude driving *your* Chrome through a browser extension:\none agent product, one browser, sharing your profile, tabs, and\nfocus. hwatu is a client-agnostic daemon any agent (Claude Code,\nCursor, or a shell script) calls over CLI/MCP, with its own warm\nWebKit engine, headless by default, and verification primitives\n(`check`, pixel diff, motion capture) built in. Speed is not really\ncomparable: claude-in-chrome's loop is extension messaging inside a\nfull human browser and is not callable by other tools, while hwatu\nis a purpose-built verification service (~35 ms per check). Use\nClaude in Chrome to let Claude browse alongside you; use hwatu when\nagents need cheap, repeated, measurable page checks.\n\n## Feedback\n\nTried hwatu? A successful check, a failed install, a missing keybind,\nand a site that broke are all useful signals. Share a two-minute\n[use report](https://github.com/hongnoul/hwatu/issues/new?template=use-report.yml)\nor [report a bug](https://github.com/hongnoul/hwatu/issues/new?template=bug-report.yml).\n\n---\n\nAGPL-3.0 licensed. Linux. WebKitGTK 6.\n",
  "bytes": 14807,
  "sha": "a2254af00b6d66b97b0fcb097def2b279f87b57f8513ea75c92dcb26be558bab",
  "repo_slug": "hongnoul/hwatu",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_hongnoul_hwatu_ef068eca/readme"
}