[Skip to content](https://github.com/hanzili/hanzi-browse#start-of-content)

You signed in with another tab or window. [Reload](https://github.com/hanzili/hanzi-browse) to refresh your session.You signed out in another tab or window. [Reload](https://github.com/hanzili/hanzi-browse) to refresh your session.You switched accounts on another tab or window. [Reload](https://github.com/hanzili/hanzi-browse) to refresh your session.Dismiss alert

{{ message }}

[hanzili](https://github.com/hanzili)/ **[hanzi-browse](https://github.com/hanzili/hanzi-browse)** Public

- [Notifications](https://github.com/login?return_to=%2Fhanzili%2Fhanzi-browse) You must be signed in to change notification settings
- [Fork\\
52](https://github.com/login?return_to=%2Fhanzili%2Fhanzi-browse)
- [Star\\
167](https://github.com/login?return_to=%2Fhanzili%2Fhanzi-browse)


main

[**3** Branches](https://github.com/hanzili/hanzi-browse/branches) [**0** Tags](https://github.com/hanzili/hanzi-browse/tags)

[Go to Branches page](https://github.com/hanzili/hanzi-browse/branches)[Go to Tags page](https://github.com/hanzili/hanzi-browse/tags)

Go to file

Code

Open more actions menu

## Folders and files

| Name | Name | Last commit message | Last commit date |
| --- | --- | --- | --- |
| ## Latest commit<br>[![IVVI0927](https://avatars.githubusercontent.com/u/183055163?v=4&size=40)](https://github.com/IVVI0927)[IVVI0927](https://github.com/hanzili/hanzi-browse/commits?author=IVVI0927)<br>[test: add Chrome extension vitest baseline (](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918) [#115](https://github.com/hanzili/hanzi-browse/pull/115) [)](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918)<br>success<br>3 months agoApr 25, 2026<br>[ce6e10d](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918) · 3 months agoApr 25, 2026<br>## History<br>[314 Commits](https://github.com/hanzili/hanzi-browse/commits/main/) <br>Open commit details<br>[View commit history for this file.](https://github.com/hanzili/hanzi-browse/commits/main/) 314 Commits |
| [dist](https://github.com/hanzili/hanzi-browse/tree/main/dist "dist") | [dist](https://github.com/hanzili/hanzi-browse/tree/main/dist "dist") | [fix: unhandled sendMessage rejections + Codex missing tool results](https://github.com/hanzili/hanzi-browse/commit/7f955c22839d456532b7b9d73832ca72269747c0 "fix: unhandled sendMessage rejections + Codex missing tool results  HANZI-MCP-1: Wrap sendToContent in try/catch and add .catch() to unguarded chrome.runtime.sendMessage calls. In MV3, these return Promises that reject when no receiver exists (sidepanel closed, content script not injected).  HANZI-MCP-5: When the agent loop is cancelled mid-tool-execution, push stub tool_result entries for all unresolved tool_use blocks before returning. Without this, the conversation history has function_calls without function_call_outputs, which Codex/OpenAI rejects on the next turn.  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 30, 2026 |
| [docs](https://github.com/hanzili/hanzi-browse/tree/main/docs "docs") | [docs](https://github.com/hanzili/hanzi-browse/tree/main/docs "docs") | [docs: reposition landing + READMEs as "context layer for browsing age…](https://github.com/hanzili/hanzi-browse/commit/1c0c274d2b16b10cc317a0c04e1593a603fcf805 "docs: reposition landing + READMEs as \"context layer for browsing agents\"  Hero now leads with the context-layer framing and \"hints for the LLM, not brittle scripts\" differentiator (vs adapter-script tools like OpenCLI). Landing page gains a site-pill row of the 24 supported domains and dual-surface CTAs (Install for your agent / Build with the SDK). Chinese README gets the two-tracks descriptions and a new Site Playbooks section that were missing.  Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>") | 3 months agoApr 17, 2026 |
| [examples](https://github.com/hanzili/hanzi-browse/tree/main/examples "examples") | [examples](https://github.com/hanzili/hanzi-browse/tree/main/examples "examples") | [fix(qa-tester): quote report inputs, redesign frontend layout (](https://github.com/hanzili/hanzi-browse/commit/49ce555150aa78aed9a9067039550578123631aa "fix(qa-tester): quote report inputs, redesign frontend layout (#113)  Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>") [#113](https://github.com/hanzili/hanzi-browse/pull/113) [)](https://github.com/hanzili/hanzi-browse/commit/49ce555150aa78aed9a9067039550578123631aa "fix(qa-tester): quote report inputs, redesign frontend layout (#113)  Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>") | 3 months agoApr 25, 2026 |
| [icons](https://github.com/hanzili/hanzi-browse/tree/main/icons "icons") | [icons](https://github.com/hanzili/hanzi-browse/tree/main/icons "icons") | [Rebrand to LLM in Chrome with teal theme and updated models](https://github.com/hanzili/hanzi-browse/commit/19984945e6777401c1e0b5a07cae995a87046dc5 "Rebrand to LLM in Chrome with teal theme and updated models  - Rename from Browser Agent to LLM in Chrome - Add new logo icons (16, 32, 48, 128px) - Update color scheme from orange to teal (#5D9A9A) - Update model lists: GPT-5, Gemini 3 Pro, o3/o4-mini - Fix steps toggle expand/collapse bug - Change tab group color to cyan  Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>") | 6 months agoJan 24, 2026 |
| [landing](https://github.com/hanzili/hanzi-browse/tree/main/landing "landing") | [landing](https://github.com/hanzili/hanzi-browse/tree/main/landing "landing") | [feat(landing): add skills grid + feature X Marketing free tool (](https://github.com/hanzili/hanzi-browse/commit/83b1cd6e8b0537afea774615f16d43e786a7916e "feat(landing): add skills grid + feature X Marketing free tool (#87) (#114)  Addresses the two remaining gaps from #87 after the recent \"context layer\" homepage refactor:  1. Skills showcase grid inside the \"For your agent\" section    - 3x2 grid of the 6 main skills with icon badges, names and      one-line descriptions    - Each card links to its landing page (data-extractor links to      GitHub since it has none yet)    - \"See all skills -> GitHub\" link at the top right    - Responsive: 3 cols desktop / 2 cols <=980px / 1 col <=560px  2. X Marketing featured card in \"Free tools\"    - Green \"LIVE - TRY FREE\" badge    - Browser-chrome mockup (traffic-light dots + URL) showing a      mock conversation + drafted reply, so the card communicates      what the tool actually does at a glance    - Gradient background with a soft top-right glow    - Mockup content locked to light colors so it still reads as a      \"light-themed tool preview\" under dark mode") [#87](https://github.com/hanzili/hanzi-browse/issues/87) [) (](https://github.com/hanzili/hanzi-browse/commit/83b1cd6e8b0537afea774615f16d43e786a7916e "feat(landing): add skills grid + feature X Marketing free tool (#87) (#114)  Addresses the two remaining gaps from #87 after the recent \"context layer\" homepage refactor:  1. Skills showcase grid inside the \"For your agent\" section    - 3x2 grid of the 6 main skills with icon badges, names and      one-line descriptions    - Each card links to its landing page (data-extractor links to      GitHub since it has none yet)    - \"See all skills -> GitHub\" link at the top right    - Responsive: 3 cols desktop / 2 cols <=980px / 1 col <=560px  2. X Marketing featured card in \"Free tools\"    - Green \"LIVE - TRY FREE\" badge    - Browser-chrome mockup (traffic-light dots + URL) showing a      mock conversation + drafted reply, so the card communicates      what the tool actually does at a glance    - Gradient background with a soft top-right glow    - Mockup content locked to light colors so it still reads as a      \"light-themed tool preview\" under dark mode") [#…](https://github.com/hanzili/hanzi-browse/pull/114) | 3 months agoApr 25, 2026 |
| [native-host](https://github.com/hanzili/hanzi-browse/tree/main/native-host "native-host") | [native-host](https://github.com/hanzili/hanzi-browse/tree/main/native-host "native-host") | [fix: sync runtime config on Codex/Claude credential import (](https://github.com/hanzili/hanzi-browse/commit/d396b201569bdfab0596e88c0b0b2d5c6bf7af67 "fix: sync runtime config on Codex/Claude credential import (#107)  Sync imported OAuth credentials to runtime config and make native host install work with unpacked extension IDs.") [#107](https://github.com/hanzili/hanzi-browse/pull/107) [)](https://github.com/hanzili/hanzi-browse/commit/d396b201569bdfab0596e88c0b0b2d5c6bf7af67 "fix: sync runtime config on Codex/Claude credential import (#107)  Sync imported OAuth credentials to runtime config and make native host install work with unpacked extension IDs.") | 3 months agoApr 11, 2026 |
| [pr-evidence/issue-22](https://github.com/hanzili/hanzi-browse/tree/main/pr-evidence/issue-22 "This path skips through empty directories") | [pr-evidence/issue-22](https://github.com/hanzili/hanzi-browse/tree/main/pr-evidence/issue-22 "This path skips through empty directories") | [feat: add ecommerce domain skills for amazon/target/ebay/walmart (](https://github.com/hanzili/hanzi-browse/commit/d56646458595a4c63a0c3cecccdf4521bb8042a6 "feat: add ecommerce domain skills for amazon/target/ebay/walmart (#106)  * Add e-commerce site patterns and domain hints  * Refine e-commerce validation notes and evidence checklist") [#106](https://github.com/hanzili/hanzi-browse/pull/106) [)](https://github.com/hanzili/hanzi-browse/commit/d56646458595a4c63a0c3cecccdf4521bb8042a6 "feat: add ecommerce domain skills for amazon/target/ebay/walmart (#106)  * Add e-commerce site patterns and domain hints  * Refine e-commerce validation notes and evidence checklist") | 3 months agoApr 11, 2026 |
| [sdk](https://github.com/hanzili/hanzi-browse/tree/main/sdk "sdk") | [sdk](https://github.com/hanzili/hanzi-browse/tree/main/sdk "sdk") | [docs(sdk): comprehensive README covering all methods + polling + errors](https://github.com/hanzili/hanzi-browse/commit/cbc40c9fd6f5bed811e1109c8dde1b2b1e03a5a2 "docs(sdk): comprehensive README covering all methods + polling + errors  Previous README documented 9 methods; the SDK exports 18+. Rewrote to: - Document every public method (createPairingToken with label/   externalUserId, deleteSession, listTasks, getTaskSteps, getScreenshot,   createApiKey, listApiKeys, deleteApiKey, getCredits, plus the rest). - Explain runTask() auto-polling behavior and transient-error retry. - Show three task patterns: blocking, fire-and-forget with webhook,   manual polling. - Add HanziError handling example with common HTTP codes. - Document TaskCreateParams.webhookUrl (was undocumented). - Explicit prerequisite callout that the user needs the Chrome   extension installed — pairing fails silently otherwise. - Pairing flow explains both redirect URL and embed widget options. - Task-debugging section with getTaskSteps + getScreenshot.  Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>") | 3 months agoApr 16, 2026 |
| [server](https://github.com/hanzili/hanzi-browse/tree/main/server "server") | [server](https://github.com/hanzili/hanzi-browse/tree/main/server "server") | [security: replace innerHTML in pairing templates with safe DOM updates (](https://github.com/hanzili/hanzi-browse/commit/ae240b31cde7ae8b0c49348af2b0e5ad7b103247 "security: replace innerHTML in pairing templates with safe DOM updates (#116)") | 3 months agoApr 25, 2026 |
| [src](https://github.com/hanzili/hanzi-browse/tree/main/src "src") | [src](https://github.com/hanzili/hanzi-browse/tree/main/src "src") | [test: add Chrome extension vitest baseline (](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") [#115](https://github.com/hanzili/hanzi-browse/pull/115) [)](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") | 3 months agoApr 25, 2026 |
| [test](https://github.com/hanzili/hanzi-browse/tree/main/test "test") | [test](https://github.com/hanzili/hanzi-browse/tree/main/test "test") | [test: add Chrome extension vitest baseline (](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") [#115](https://github.com/hanzili/hanzi-browse/pull/115) [)](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") | 3 months agoApr 25, 2026 |
| [.env.example](https://github.com/hanzili/hanzi-browse/blob/main/.env.example ".env.example") | [.env.example](https://github.com/hanzili/hanzi-browse/blob/main/.env.example ".env.example") | [chore: unify PostHog configuration via env var (](https://github.com/hanzili/hanzi-browse/commit/b37125dd4bea1b02f00a8937f8703813d7bd0220 "chore: unify PostHog configuration via env var (#111)") [#111](https://github.com/hanzili/hanzi-browse/pull/111) [)](https://github.com/hanzili/hanzi-browse/commit/b37125dd4bea1b02f00a8937f8703813d7bd0220 "chore: unify PostHog configuration via env var (#111)") | 3 months agoApr 14, 2026 |
| [.eslintrc.json](https://github.com/hanzili/hanzi-browse/blob/main/.eslintrc.json ".eslintrc.json") | [.eslintrc.json](https://github.com/hanzili/hanzi-browse/blob/main/.eslintrc.json ".eslintrc.json") | [chore: code quality — fix all lint errors, remove dead code, break ci…](https://github.com/hanzili/hanzi-browse/commit/c5f09305b0a057805c2aef29f4c9af25a37bbe5e "chore: code quality — fix all lint errors, remove dead code, break circular deps  - Fix 9 ESLint errors (undefined var, empty catch blocks) - Remove 24 unused variables and imports - Extract relay-client.js from mcp-bridge.js to break 3 circular dependency cycles - Remove unused devDeps (@tavily/core, @anthropic-ai/sdk) - Configure knip.json to scan .jsx files (eliminates false positives) - Raise ESLint thresholds (complexity 20→40, depth 4→6) to match codebase reality - Refactor 4 provider files: extract 20+ helper methods to reduce complexity - Refactor format.js: extract list state helpers - Add targeted eslint-disable for inherently complex dispatch functions - Result: npm run quality passes with 0 errors, 0 warnings, 0 dead code  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 30, 2026 |
| [.gitignore](https://github.com/hanzili/hanzi-browse/blob/main/.gitignore ".gitignore") | [.gitignore](https://github.com/hanzili/hanzi-browse/blob/main/.gitignore ".gitignore") | [fix: pairing flow, per-task tabs, domain knowledge, turn logs, LLM pr…](https://github.com/hanzili/hanzi-browse/commit/be52d607f1dc8217fda4e22a2f2fc0c5260ef31b "fix: pairing flow, per-task tabs, domain knowledge, turn logs, LLM proxy for find tool  Pairing: page calls register API directly (no duplicate content script relay) Per-task tabs: parallel tasks get separate tabs keyed by taskId Domain knowledge: x.com patterns injected via system prompt, removed site-pattern duplication Turn logs: structured tool name/input/result/duration per step, stored on task LLM proxy: find tool routes LLM calls through relay to server's Vertex AI Scroll normalization: auto-correct malformed scroll actions from Gemini Publishable key permissions: block task/step/screenshot/api-key reads X Marketing: parallel posts, cleaned task prompts, fixed rate limit counter Tests: fix Windows path test for cross-platform  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 3 months agoApr 2, 2026 |
| [.prettierrc.json](https://github.com/hanzili/hanzi-browse/blob/main/.prettierrc.json ".prettierrc.json") | [.prettierrc.json](https://github.com/hanzili/hanzi-browse/blob/main/.prettierrc.json ".prettierrc.json") | [Major refactor: Provider architecture, OAuth, and LLM-agnostic codebase](https://github.com/hanzili/hanzi-browse/commit/efde46244f18b98e0d0bd4d255c86a566be82d42 "Major refactor: Provider architecture, OAuth, and LLM-agnostic codebase  Architecture: - Refactor to provider pattern for multi-LLM support - Extract managers (tab, debugger, logging, indicator) - Extract tool handlers to separate modules - Add CDP helper and supporting utilities  Features: - Add OAuth authentication with native messaging - Implement conversation compaction for long sessions - Add hybrid memory management  Code Quality: - Make codebase LLM-agnostic (generic variable names, clean comments) - Add ESLint and Prettier configuration - Update .gitignore for cleaner repo  Co-Authored-By: Claude <noreply@anthropic.com>") | 6 months agoJan 30, 2026 |
| [AUDIT-FIXES.md](https://github.com/hanzili/hanzi-browse/blob/main/AUDIT-FIXES.md "AUDIT-FIXES.md") | [AUDIT-FIXES.md](https://github.com/hanzili/hanzi-browse/blob/main/AUDIT-FIXES.md "AUDIT-FIXES.md") | [fix: security audit, SDK hardening, docs accuracy](https://github.com/hanzili/hanzi-browse/commit/c323f0b86c9307384272251156816d50e3faba89 "fix: security audit, SDK hardening, docs accuracy  Security: - Remove debug block from /v1/me that leaked cookie headers - Sanitize 500 error responses (no raw err.message to clients) - Add tools.hanzilla.co to CORS allowed origins  SDK: - Catch JSON parse errors in request() (502 HTML pages no longer crash) - Make createApiKey(name) required, add type parameter for publishable keys - Add retry logic to runTask() polling (3 consecutive failures = give up) - Consolidate embed.js: single source in landing/, delete divergent sdk/ copy - Add secret key warning + onError callback to embed widget  Docs: - Fix screenshot format PNG→JPEG in docs.html - Add TypeScript SDK section to docs.html with install + usage + method list - Document DELETE /v1/browser-sessions/:id endpoint - Fix landing page code example: show full pairing→session flow - Rewrite npm README: add API/SDK quick start, fix stale references  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 3 months agoApr 3, 2026 |
| [CLAUDE.md](https://github.com/hanzili/hanzi-browse/blob/main/CLAUDE.md "CLAUDE.md") | [CLAUDE.md](https://github.com/hanzili/hanzi-browse/blob/main/CLAUDE.md "CLAUDE.md") | [docs(claude-md): drop automations tables from architecture table list](https://github.com/hanzili/hanzi-browse/commit/7c4bda79dddda992db5ace63d8de5a629fe0c182 "docs(claude-md): drop automations tables from architecture table list  automations / automation_drafts / engagement_log tables are gone from fresh installs. Remove from the CLAUDE.md table listing so future AI agents editing the codebase don't resurrect them.  Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>") | 3 months agoApr 16, 2026 |
| [CONTRIBUTING.md](https://github.com/hanzili/hanzi-browse/blob/main/CONTRIBUTING.md "CONTRIBUTING.md") | [CONTRIBUTING.md](https://github.com/hanzili/hanzi-browse/blob/main/CONTRIBUTING.md "CONTRIBUTING.md") | [docs(contributing): add domain-knowledge section, warn against site-p…](https://github.com/hanzili/hanzi-browse/commit/d25a63e091deabc5306f6866acba616d4c8bf45d "docs(contributing): add domain-knowledge section, warn against site-patterns/  Two contributor PRs (#68, #106) targeted the deleted server/site-patterns/ directory because nothing told them it had moved to domain-skills.json. Add a clear section to CONTRIBUTING.md explaining the current format, the JSON schema, and a \"do NOT add files to server/site-patterns/\" callout.  Also updated the 8 open \"Site patterns:\" issues (#15-#22) with a pointer to this guide and closed the 4 that are now fully resolved (#18, #22, #24, #90).  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 3 months agoApr 12, 2026 |
| [LICENSE](https://github.com/hanzili/hanzi-browse/blob/main/LICENSE "LICENSE") | [LICENSE](https://github.com/hanzili/hanzi-browse/blob/main/LICENSE "LICENSE") | [Change license from MIT to Polyform Noncommercial 1.0.0](https://github.com/hanzili/hanzi-browse/commit/dc416dda857c77f6cc80895d75f337329fdfd321 "Change license from MIT to Polyform Noncommercial 1.0.0  Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>") | 4 months agoMar 3, 2026 |
| [Makefile](https://github.com/hanzili/hanzi-browse/blob/main/Makefile "Makefile") | [Makefile](https://github.com/hanzili/hanzi-browse/blob/main/Makefile "Makefile") | [Improve developer onboarding: make fresh, prereq checks, Docker-based…](https://github.com/hanzili/hanzi-browse/commit/1851c1b016636befb2f3539cea2dedb880948f6d "Improve developer onboarding: make fresh, prereq checks, Docker-based migrations  - Add `make fresh` as single first-time setup command (prereqs + env + deps + build + DB + start) - Add `check-prereqs` target validating Node 18+, Docker running, Docker Compose - Replace psql-based migration with Docker exec (no local psql required) - Add proper Postgres readiness wait loop instead of blind sleep - Add clear error messages for Docker not running, migration failures - Auto-create .env from .env.example when missing - Expand .env.example with Vertex AI setup instructions and safe placeholder values - Update README development section with first-time vs subsequent workflows  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 28, 2026 |
| [PRIVACY.md](https://github.com/hanzili/hanzi-browse/blob/main/PRIVACY.md "PRIVACY.md") | [PRIVACY.md](https://github.com/hanzili/hanzi-browse/blob/main/PRIVACY.md "PRIVACY.md") | [Rename to hanzi-browse, add managed sidepanel, accessibility overhaul](https://github.com/hanzili/hanzi-browse/commit/51216daa023a991ed9587b73210782d79b2a2f0e "Rename to hanzi-browse, add managed sidepanel, accessibility overhaul  Product rename: hanzi-in-chrome → hanzi-browse across all packages, configs, and docs.  Managed sidepanel support: - Self-service pairing flow (/pair-self): Google sign-in → auto-pair → done - Relay-based task execution: sidepanel → create_task via relay → server agent loop → results - Clean paired UI: \"Hanzi Managed\" header, no model selector, one-click disconnect - Auto-detect pairing state via chrome.storage.onChanged  Dashboard auth fixes: - Direct DB session lookup (bypasses Better Auth cookie reading bug behind Caddy) - Fix missing 'plan' column in workspaces query - Fix UUID type mismatches for session-based auth (pairing tokens, task runs) - Cache-control headers on dashboard HTML  Accessibility (audit score 10→18/20): - ARIA: dropdown listbox/options, aria-expanded, keyboard nav, focus trap (useFocusTrap hook) - Modals: role=dialog, aria-modal, escape handler, overlay click-to-close - Focus: :focus-visible outlines on all 3 surfaces, prefers-reduced-motion - Landmarks: skip-to-content link, <nav> with aria-label - Labels: aria-label on icon buttons, textarea, close buttons, external links - Streaming: aria-live=polite on streaming messages  Landing page: - Dark mode (prefers-color-scheme: dark) with warm palette - YouTube facade (saves ~1MB initial load) - Social proof signal row - Brand SVG dark mode adaptation - Touch targets (44px min), signal chip sizing  Sidepanel UX: - Settings distilled: 4 tabs → 2 tabs (Connections + Site Tips) - Managed + BYOM both visible as first-class options - Steps auto-expand during active tasks - Warmer empty state (\"What should we browse?\") and no-credentials state (\"Almost ready\") - Keyboard shortcuts (Cmd+N, Cmd+,) - Inline form validation (replaces alert()) - Confirm before clear chat  Design tokens: - --color-success, --color-error, --color-success-bg, --color-error-bg with light/dark variants - Replaced ~20 hard-coded #4CAF50/#ff6b6b instances  Removed legacy popup (src/popup/) — unused, not in manifest.json.  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 25, 2026 |
| [README.md](https://github.com/hanzili/hanzi-browse/blob/main/README.md "README.md") | [README.md](https://github.com/hanzili/hanzi-browse/blob/main/README.md "README.md") | [docs: reposition landing + READMEs as "context layer for browsing age…](https://github.com/hanzili/hanzi-browse/commit/1c0c274d2b16b10cc317a0c04e1593a603fcf805 "docs: reposition landing + READMEs as \"context layer for browsing agents\"  Hero now leads with the context-layer framing and \"hints for the LLM, not brittle scripts\" differentiator (vs adapter-script tools like OpenCLI). Landing page gains a site-pill row of the 24 supported domains and dual-surface CTAs (Install for your agent / Build with the SDK). Chinese README gets the two-tracks descriptions and a new Site Playbooks section that were missing.  Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>") | 3 months agoApr 17, 2026 |
| [demo.gif](https://github.com/hanzili/hanzi-browse/blob/main/demo.gif "demo.gif") | [demo.gif](https://github.com/hanzili/hanzi-browse/blob/main/demo.gif "demo.gif") | [Rewrite README for launch: user-facing copy, npx setup, pricing](https://github.com/hanzili/hanzi-browse/commit/67f5cc4e978c78b2111b171bdb2098ebde524a6c "Rewrite README for launch: user-facing copy, npx setup, pricing  Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>") | 5 months agoMar 2, 2026 |
| [docker-compose.yml](https://github.com/hanzili/hanzi-browse/blob/main/docker-compose.yml "docker-compose.yml") | [docker-compose.yml](https://github.com/hanzili/hanzi-browse/blob/main/docker-compose.yml "docker-compose.yml") | [Developer console, dashboard UX, backend hardening, one-click pairing](https://github.com/hanzili/hanzi-browse/commit/e6c717650d00e8a6b9c0117a654687fab5ba75b1 "Developer console, dashboard UX, backend hardening, one-click pairing  Developer console (server/dashboard/): - Preact + Vite app served at /dashboard from managed API - Progressive disclosure: API key → pair browser → run task - One-click browser pairing via content script bridge (window.postMessage) - Interactive task runner: type a task, click Run, see results live - Session management: view connected/disconnected, remove old sessions - Personalized header with workspace name via GET /v1/me - Post-auth redirect: GET / sends authenticated users to /dashboard  Backend: - GET /v1/me endpoint for user profile + workspace info - DELETE /v1/browser-sessions/:id for session cleanup - Structured JSON logging (log.ts) with request IDs on all responses - Persisted stuck-task recovery on startup (listStuckTasks + recoverStuckTasks) - Billing wiring: webhook persistence, customer mapping, usage metering, soft plan gate - Health endpoint: version, uptime, store_type, DB connectivity - Better Auth: toNodeHandler for correct OAuth flow, basePath config - Schema: Better Auth tables, billing columns, TEXT api_key_id, ON DELETE SET NULL  Extension: - Content script bridge: HANZI_PING/HANZI_PAIR/HANZI_PAIR_RESULT messaging - Lazy tab creation for managed sessions (don't capture dashboard tab) - Managed tab: status dot indicator, better error messages - Cleared stale tab mapping on re-pair  Public surfaces: - Docs page: full rewrite with sidebar nav, API reference, error codes, troubleshooting - Pricing merged into landing page (pricing.html now redirects) - All references updated to \"developer console\" instead of raw API  Dev experience: - make dev: one command to start everything (Docker Postgres + server + dashboard) - docker-compose.yml, .env.example, Makefile - CONTRIBUTING.md: full rewrite with setup, architecture, testing, deployment - Proxy support for China dev (proxy-setup.mjs)  Tests: - E2E test (e2e.test.ts): connected session task creation + cancellation - Billing workspace fields test - Stuck-task recovery test - Request ID header test  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 24, 2026 |
| [install.sh](https://github.com/hanzili/hanzi-browse/blob/main/install.sh "install.sh") | [install.sh](https://github.com/hanzili/hanzi-browse/blob/main/install.sh "install.sh") | [Rename to hanzi-browse, add managed sidepanel, accessibility overhaul](https://github.com/hanzili/hanzi-browse/commit/51216daa023a991ed9587b73210782d79b2a2f0e "Rename to hanzi-browse, add managed sidepanel, accessibility overhaul  Product rename: hanzi-in-chrome → hanzi-browse across all packages, configs, and docs.  Managed sidepanel support: - Self-service pairing flow (/pair-self): Google sign-in → auto-pair → done - Relay-based task execution: sidepanel → create_task via relay → server agent loop → results - Clean paired UI: \"Hanzi Managed\" header, no model selector, one-click disconnect - Auto-detect pairing state via chrome.storage.onChanged  Dashboard auth fixes: - Direct DB session lookup (bypasses Better Auth cookie reading bug behind Caddy) - Fix missing 'plan' column in workspaces query - Fix UUID type mismatches for session-based auth (pairing tokens, task runs) - Cache-control headers on dashboard HTML  Accessibility (audit score 10→18/20): - ARIA: dropdown listbox/options, aria-expanded, keyboard nav, focus trap (useFocusTrap hook) - Modals: role=dialog, aria-modal, escape handler, overlay click-to-close - Focus: :focus-visible outlines on all 3 surfaces, prefers-reduced-motion - Landmarks: skip-to-content link, <nav> with aria-label - Labels: aria-label on icon buttons, textarea, close buttons, external links - Streaming: aria-live=polite on streaming messages  Landing page: - Dark mode (prefers-color-scheme: dark) with warm palette - YouTube facade (saves ~1MB initial load) - Social proof signal row - Brand SVG dark mode adaptation - Touch targets (44px min), signal chip sizing  Sidepanel UX: - Settings distilled: 4 tabs → 2 tabs (Connections + Site Tips) - Managed + BYOM both visible as first-class options - Steps auto-expand during active tasks - Warmer empty state (\"What should we browse?\") and no-credentials state (\"Almost ready\") - Keyboard shortcuts (Cmd+N, Cmd+,) - Inline form validation (replaces alert()) - Confirm before clear chat  Design tokens: - --color-success, --color-error, --color-success-bg, --color-error-bg with light/dark variants - Replaced ~20 hard-coded #4CAF50/#ff6b6b instances  Removed legacy popup (src/popup/) — unused, not in manifest.json.  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 25, 2026 |
| [jsconfig.json](https://github.com/hanzili/hanzi-browse/blob/main/jsconfig.json "jsconfig.json") | [jsconfig.json](https://github.com/hanzili/hanzi-browse/blob/main/jsconfig.json "jsconfig.json") | [Major refactor: Provider architecture, OAuth, and LLM-agnostic codebase](https://github.com/hanzili/hanzi-browse/commit/efde46244f18b98e0d0bd4d255c86a566be82d42 "Major refactor: Provider architecture, OAuth, and LLM-agnostic codebase  Architecture: - Refactor to provider pattern for multi-LLM support - Extract managers (tab, debugger, logging, indicator) - Extract tool handlers to separate modules - Add CDP helper and supporting utilities  Features: - Add OAuth authentication with native messaging - Implement conversation compaction for long sessions - Add hybrid memory management  Code Quality: - Make codebase LLM-agnostic (generic variable names, clean comments) - Add ESLint and Prettier configuration - Update .gitignore for cleaner repo  Co-Authored-By: Claude <noreply@anthropic.com>") | 6 months agoJan 30, 2026 |
| [knip.json](https://github.com/hanzili/hanzi-browse/blob/main/knip.json "knip.json") | [knip.json](https://github.com/hanzili/hanzi-browse/blob/main/knip.json "knip.json") | [chore: code quality — fix all lint errors, remove dead code, break ci…](https://github.com/hanzili/hanzi-browse/commit/c5f09305b0a057805c2aef29f4c9af25a37bbe5e "chore: code quality — fix all lint errors, remove dead code, break circular deps  - Fix 9 ESLint errors (undefined var, empty catch blocks) - Remove 24 unused variables and imports - Extract relay-client.js from mcp-bridge.js to break 3 circular dependency cycles - Remove unused devDeps (@tavily/core, @anthropic-ai/sdk) - Configure knip.json to scan .jsx files (eliminates false positives) - Raise ESLint thresholds (complexity 20→40, depth 4→6) to match codebase reality - Refactor 4 provider files: extract 20+ helper methods to reduce complexity - Refactor format.js: extract list state helpers - Add targeted eslint-disable for inherently complex dispatch functions - Result: npm run quality passes with 0 errors, 0 warnings, 0 dead code  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 30, 2026 |
| [manifest.json](https://github.com/hanzili/hanzi-browse/blob/main/manifest.json "manifest.json") | [manifest.json](https://github.com/hanzili/hanzi-browse/blob/main/manifest.json "manifest.json") | [chore: bump extension manifest to 2.3.3](https://github.com/hanzili/hanzi-browse/commit/38f6c4d41e806090929841f410219d6f94c14ec1 "chore: bump extension manifest to 2.3.3  Sync with server/package.json 2.3.3 so Chrome Web Store upload matches the npm-published MCP server.  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 3 months agoApr 14, 2026 |
| [package.json](https://github.com/hanzili/hanzi-browse/blob/main/package.json "package.json") | [package.json](https://github.com/hanzili/hanzi-browse/blob/main/package.json "package.json") | [test: add Chrome extension vitest baseline (](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") [#115](https://github.com/hanzili/hanzi-browse/pull/115) [)](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") | 3 months agoApr 25, 2026 |
| [social-posts.md](https://github.com/hanzili/hanzi-browse/blob/main/social-posts.md "social-posts.md") | [social-posts.md](https://github.com/hanzili/hanzi-browse/blob/main/social-posts.md "social-posts.md") | [feat: X Marketing free tool, Gemini 3 Flash, site patterns, architect…](https://github.com/hanzili/hanzi-browse/commit/27ffe4cf336ac07f96e0268a47c7c3dac3a354cf "feat: X Marketing free tool, Gemini 3 Flash, site patterns, architecture docs  X Marketing Tool (tools.hanzilla.co/x-marketing): - Full redesign: landing hero, per-keyword search progress, draft lifecycle - Stateless server with rate limiting, PostHog analytics - Deployment: systemd + Caddy on VPS, ccproxy for Claude API - XSS protection, post confirmation, approve all, retry failed  Engine improvements: - Gemini 3 Flash support with thought signature passthrough - Site patterns: x.com.md with verified search/reply/text-input procedures - get_page_text fix for X async loading (read_page returns empty a11y tree) - embed.js: auto-detect extension install, 3-min pairing timeout  Docs: - CLAUDE.md: comprehensive architecture guide for AI agents - README.md: Skills & Free Tools distribution channels - Skills: hanzi-browse core + x-marketer workflow  Version: server 2.2.3 → 2.3.0  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 30, 2026 |
| [task.md](https://github.com/hanzili/hanzi-browse/blob/main/task.md "task.md") | [task.md](https://github.com/hanzili/hanzi-browse/blob/main/task.md "task.md") | [Rename to hanzi-browse, add managed sidepanel, accessibility overhaul](https://github.com/hanzili/hanzi-browse/commit/51216daa023a991ed9587b73210782d79b2a2f0e "Rename to hanzi-browse, add managed sidepanel, accessibility overhaul  Product rename: hanzi-in-chrome → hanzi-browse across all packages, configs, and docs.  Managed sidepanel support: - Self-service pairing flow (/pair-self): Google sign-in → auto-pair → done - Relay-based task execution: sidepanel → create_task via relay → server agent loop → results - Clean paired UI: \"Hanzi Managed\" header, no model selector, one-click disconnect - Auto-detect pairing state via chrome.storage.onChanged  Dashboard auth fixes: - Direct DB session lookup (bypasses Better Auth cookie reading bug behind Caddy) - Fix missing 'plan' column in workspaces query - Fix UUID type mismatches for session-based auth (pairing tokens, task runs) - Cache-control headers on dashboard HTML  Accessibility (audit score 10→18/20): - ARIA: dropdown listbox/options, aria-expanded, keyboard nav, focus trap (useFocusTrap hook) - Modals: role=dialog, aria-modal, escape handler, overlay click-to-close - Focus: :focus-visible outlines on all 3 surfaces, prefers-reduced-motion - Landmarks: skip-to-content link, <nav> with aria-label - Labels: aria-label on icon buttons, textarea, close buttons, external links - Streaming: aria-live=polite on streaming messages  Landing page: - Dark mode (prefers-color-scheme: dark) with warm palette - YouTube facade (saves ~1MB initial load) - Social proof signal row - Brand SVG dark mode adaptation - Touch targets (44px min), signal chip sizing  Sidepanel UX: - Settings distilled: 4 tabs → 2 tabs (Connections + Site Tips) - Managed + BYOM both visible as first-class options - Steps auto-expand during active tasks - Warmer empty state (\"What should we browse?\") and no-credentials state (\"Almost ready\") - Keyboard shortcuts (Cmd+N, Cmd+,) - Inline form validation (replaces alert()) - Confirm before clear chat  Design tokens: - --color-success, --color-error, --color-success-bg, --color-error-bg with light/dark variants - Replaced ~20 hard-coded #4CAF50/#ff6b6b instances  Removed legacy popup (src/popup/) — unused, not in manifest.json.  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 25, 2026 |
| [vite.config.js](https://github.com/hanzili/hanzi-browse/blob/main/vite.config.js "vite.config.js") | [vite.config.js](https://github.com/hanzili/hanzi-browse/blob/main/vite.config.js "vite.config.js") | [Rename to hanzi-browse, add managed sidepanel, accessibility overhaul](https://github.com/hanzili/hanzi-browse/commit/51216daa023a991ed9587b73210782d79b2a2f0e "Rename to hanzi-browse, add managed sidepanel, accessibility overhaul  Product rename: hanzi-in-chrome → hanzi-browse across all packages, configs, and docs.  Managed sidepanel support: - Self-service pairing flow (/pair-self): Google sign-in → auto-pair → done - Relay-based task execution: sidepanel → create_task via relay → server agent loop → results - Clean paired UI: \"Hanzi Managed\" header, no model selector, one-click disconnect - Auto-detect pairing state via chrome.storage.onChanged  Dashboard auth fixes: - Direct DB session lookup (bypasses Better Auth cookie reading bug behind Caddy) - Fix missing 'plan' column in workspaces query - Fix UUID type mismatches for session-based auth (pairing tokens, task runs) - Cache-control headers on dashboard HTML  Accessibility (audit score 10→18/20): - ARIA: dropdown listbox/options, aria-expanded, keyboard nav, focus trap (useFocusTrap hook) - Modals: role=dialog, aria-modal, escape handler, overlay click-to-close - Focus: :focus-visible outlines on all 3 surfaces, prefers-reduced-motion - Landmarks: skip-to-content link, <nav> with aria-label - Labels: aria-label on icon buttons, textarea, close buttons, external links - Streaming: aria-live=polite on streaming messages  Landing page: - Dark mode (prefers-color-scheme: dark) with warm palette - YouTube facade (saves ~1MB initial load) - Social proof signal row - Brand SVG dark mode adaptation - Touch targets (44px min), signal chip sizing  Sidepanel UX: - Settings distilled: 4 tabs → 2 tabs (Connections + Site Tips) - Managed + BYOM both visible as first-class options - Steps auto-expand during active tasks - Warmer empty state (\"What should we browse?\") and no-credentials state (\"Almost ready\") - Keyboard shortcuts (Cmd+N, Cmd+,) - Inline form validation (replaces alert()) - Confirm before clear chat  Design tokens: - --color-success, --color-error, --color-success-bg, --color-error-bg with light/dark variants - Replaced ~20 hard-coded #4CAF50/#ff6b6b instances  Removed legacy popup (src/popup/) — unused, not in manifest.json.  Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>") | 4 months agoMar 25, 2026 |
| [vitest.config.js](https://github.com/hanzili/hanzi-browse/blob/main/vitest.config.js "vitest.config.js") | [vitest.config.js](https://github.com/hanzili/hanzi-browse/blob/main/vitest.config.js "vitest.config.js") | [test: add Chrome extension vitest baseline (](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") [#115](https://github.com/hanzili/hanzi-browse/pull/115) [)](https://github.com/hanzili/hanzi-browse/commit/ce6e10dc0e09afdf88b481afc5e8339bee745918 "test: add Chrome extension vitest baseline (#115)") | 3 months agoApr 25, 2026 |
| View all files |

## Repository files navigation

[English](https://github.com/hanzili/hanzi-browse/blob/main/README.md) \| [中文](https://github.com/hanzili/hanzi-browse/blob/main/docs/zh/README.md)

[![Hanzi Browse](https://github.com/hanzili/hanzi-browse/raw/main/docs/logo.svg)](https://github.com/hanzili/hanzi-browse/blob/main/docs/logo.svg)

# Hanzi Browse

[Permalink: Hanzi Browse](https://github.com/hanzili/hanzi-browse#hanzi-browse)

**The context layer for browsing agents.**

Your browsing agent keeps failing on real sites — X uses Draft.js, LinkedIn hides the

connect button, Gmail needs keyboard shortcuts. Hanzi Browse ships 24 site playbooks —

**hints for the LLM, not brittle scripts** — so it actually finishes the task.

[![npm](https://camo.githubusercontent.com/1432e04f49bb9fe0430dc45097d37d77c8cbaf0c373c1bca1c081b69febd1b87/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f68616e7a692d62726f7773653f636f6c6f723d253233636233383337266c6162656c3d6e706d)](https://www.npmjs.com/package/hanzi-browse)[![Chrome Web Store](https://camo.githubusercontent.com/40bd283d0c13cf0a8c0f46cc35687a30526f9641cdbfde45fe9c86326d5d3bb9/68747470733a2f2f696d672e736869656c64732e696f2f6368726f6d652d7765622d73746f72652f762f696b6c706b656d6c6d6268656d6b696f6a6e647062686f616b67696b706d63643f6c6162656c3d6368726f6d6525323077656225323073746f726526636f6c6f723d253233343238354634)](https://chrome.google.com/webstore/detail/iklpkemlmbhemkiojndpbhoakgikpmcd)[![Discord](https://camo.githubusercontent.com/248061ff84b21b0f1f74dc4c740e9792447d50cffc545a245001680100321ae4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646973636f72642d6a6f696e2d3538363546323f6c6f676f3d646973636f7264266c6f676f436f6c6f723d7768697465)](https://discord.gg/hahgu5hcA5)[![License](https://camo.githubusercontent.com/6b0e1c1515684df618b6221feb094760975f131125e0b5d22034d966290ee5f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d506f6c79466f726d2532304e432d677265656e)](https://github.com/hanzili/hanzi-browse/blob/main/LICENSE)

**Works with**

[![Claude Code](https://camo.githubusercontent.com/f2ed2f58b8a400e4ea81977223cdf3f5e2126703db3f8bb7c744b2f4ae95bc6d/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f636c617564652d6c6f676f2d30703962363832342e706e67)](https://claude.ai/code)[![Cursor](https://camo.githubusercontent.com/fe855cfb70e6c2aaa5061cd1027b777da51533484c2d5b7cac1c18b2798c27a7/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f637572736f722d6c6f676f2d356a78686a6e31372e706e67)](https://cursor.com/)[![Codex](https://camo.githubusercontent.com/72dda8fec979547420c637ca06bdfc418c61d793dfb9ffa4de2f3c4512698053/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f6f70656e61692d6c6f676f2d3633323378347a642e706e67)](https://openai.com/codex)[![Gemini CLI](https://camo.githubusercontent.com/60b786ce7c9d14024483fc5834cd437eefb7055ccf57fbd15dab719f4422089a/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f67656d696e692d6c6f676f2d3166366b766277632e706e67)](https://ai.google.dev/gemini-api/docs/cls)![VS Code](https://camo.githubusercontent.com/fa880755faae4677b7b08f5408203e6edcc42a538b8a103789cc005486291b46/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f6769746875622d6c6f676f2d74723964383334392e706e67)![Kiro](https://camo.githubusercontent.com/7f4e0e5edb46f7d2768234f8ff6e29345b80ae561f93123e790a3946af223e7a/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f6b69726f2d6c6f676f2d776b3373396263792e706e67)![Antigravity](https://camo.githubusercontent.com/046172aa6c0cac817a482ecd785bcae149512d85b7f369a376a6c52465fc1505/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f616e7469677261766974792d6c6f676f2d737a6a31676a67762e706e67)![OpenCode](https://camo.githubusercontent.com/3531bc42d70ce50b99e0704c774321d1458997e80eee4faaf56f67ed1de84246/68747470733a2f2f62726f7773652e68616e7a696c6c612e636f2f6c6f676f732f6f70656e636f64652d6c6f676f2d73767079307763622e706e67)

[![Watch demo](https://camo.githubusercontent.com/939868e5f37a3a3def2dc3da0b29ac30e43f76a59d8656636d32fcf67c63b907/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f3374487a673270732d39772f6d617872657364656661756c742e6a7067)](https://www.youtube.com/watch?v=3tHzg2ps-9w)

## Two ways to use Hanzi Browse

[Permalink: Two ways to use Hanzi Browse](https://github.com/hanzili/hanzi-browse#two-ways-to-use-hanzi-browse)

Same 24 site playbooks underneath. Two install paths depending on who's driving.

### For your agent — a browser sub-agent for your coding agent

[Permalink: For your agent — a browser sub-agent for your coding agent](https://github.com/hanzili/hanzi-browse#for-your-agent--a-browser-sub-agent-for-your-coding-agent)

One command. `npx hanzi-browse setup` detects every AI agent on your machine (Claude Code, Cursor, Codex, and 9 more) and wires Hanzi Browse in as an MCP tool. Your main agent delegates browser work; a sub-agent runs the loop — _read page → plan next action → click/type/scroll → observe → repeat until done_ — and returns a clean answer. Site playbooks auto-load by URL so the model already knows the quirks.

[![Use it now](https://github.com/hanzili/hanzi-browse/raw/main/docs/diagrams/use-it.svg)](https://github.com/hanzili/hanzi-browse/blob/main/docs/diagrams/use-it.svg)

### For your product — browser automation for your users, described in English

[Permalink: For your product — browser automation for your users, described in English](https://github.com/hanzili/hanzi-browse#for-your-product--browser-automation-for-your-users-described-in-english)

Your backend calls `runTask({ task: "…" })`. Your users' own Chrome executes it, signed in as themselves. Same 24 playbooks as the CLI, exposed as a REST API and `@hanzi-browse/sdk`. Free tools on [tools.hanzilla.co](https://tools.hanzilla.co/) are built on this SDK.

[![Build with it](https://github.com/hanzili/hanzi-browse/raw/main/docs/diagrams/build-with-it.svg)](https://github.com/hanzili/hanzi-browse/blob/main/docs/diagrams/build-with-it.svg)

## Get Started

[Permalink: Get Started](https://github.com/hanzili/hanzi-browse#get-started)

```
npx hanzi-browse setup
```

One command does everything:

```
npx hanzi-browse setup
│
├── 1. Detect browsers ──── Chrome, Brave, Edge, Arc, Chromium
│
├── 2. Install extension ── Opens Chrome Web Store, waits for install
│
├── 3. Detect AI agents ─── Claude Code, Cursor, Codex, Windsurf,
│                           VS Code, Gemini CLI, Amp, Cline, Roo Code
│
├── 4. Configure MCP ────── Merges hanzi-browse into each agent's config
│
├── 5. Install skills ───── Copies browser skills into each agent
│
└── 6. Choose AI mode ───── Managed ($0.05/task) or BYOM (free forever)
```

- **Managed** — we handle the AI. 20 free tasks/month, then $0.05/task. No API key needed.
- **BYOM** — use your Claude Pro/Max subscription, GPT Plus, or any API key. Free forever, runs locally.

## Examples

[Permalink: Examples](https://github.com/hanzili/hanzi-browse#examples)

```
"Go to Gmail and unsubscribe from all marketing emails from the last week"
"Apply for the senior engineer position on careers.acme.com"
"Log into my bank and download last month's statement"
"Find AI engineer jobs on LinkedIn in San Francisco"
```

## Skills & Free Tools

[Permalink: Skills & Free Tools](https://github.com/hanzili/hanzi-browse#skills--free-tools)

Hanzi Browse has two distribution channels. Both use the same browser automation engine and site domain knowledge:

**Skills** — for users who run Hanzi Browse locally through their AI agent. The setup wizard installs skills directly into your agent (Claude Code, Cursor, etc.). Each skill teaches the agent _when_ and _how_ to use the browser for a specific workflow.

**Free Tools** — hosted web apps that anyone can try without installing anything. Each tool is a standalone app built on the Hanzi Browse API that demonstrates a use case. Every skill can become a free tool.

### Skills

[Permalink: Skills](https://github.com/hanzili/hanzi-browse#skills)

Installed automatically during `npx hanzi-browse setup`. Your agent reads these as markdown files.

| Skill | Description |
| --- | --- |
| `hanzi-browse` | Core skill — when and how to use browser automation |
| `e2e-tester` | Test your app in a real browser, report bugs with screenshots |
| `social-poster` | Draft per-platform posts, publish from your signed-in accounts |
| `linkedin-prospector` | Find prospects, send personalized connection requests |
| `a11y-auditor` | Run accessibility audits in a real browser |
| `data-extractor` | Extract structured data from websites into CSV/JSON |
| `x-marketer` | Twitter/X marketing workflows |

Open source — [add your own](https://github.com/hanzili/hanzi-browse/tree/main/server/skills).

### Free Tools

[Permalink: Free Tools](https://github.com/hanzili/hanzi-browse#free-tools)

Try them at [tools.hanzilla.co](https://tools.hanzilla.co/). No account needed — just install the extension and go.

| Tool | What it does | Try it |
| --- | --- | --- |
| X Marketing | AI finds relevant conversations on X, drafts personalized replies, posts from your Chrome | [tools.hanzilla.co/x-marketing](https://tools.hanzilla.co/x-marketing) |

### Site Playbooks — the context layer

[Permalink: Site Playbooks — the context layer](https://github.com/hanzili/hanzi-browse#site-playbooks--the-context-layer)

Both CLI and SDK rely on a shared set of **site playbooks** — verified interaction recipes for complex websites. They teach the LLM how async loading works on X, which selector hides LinkedIn's connect button, that Gmail responds to keyboard shortcuts, and how to sidestep anti-bot detection on ~20 other sites.

**Hints for the LLM, not brittle scripts.** The model stays in control; we just hand it the cheat sheet. When the DOM shifts, the agent adapts — no adapter to rebuild.

**Currently supports 24 sites:** X, LinkedIn, Gmail, GitHub, Notion, Figma, Slack, Reddit, Amazon, eBay, Walmart, Target, Zillow, Apartments.com, Craigslist, Indeed, Google Docs, Sheets, Calendar, Drive, ChatGPT, Claude.ai, Stack Overflow.

All playbooks live in [`server/src/agent/domain-skills.json`](https://github.com/hanzili/hanzi-browse/blob/main/server/src/agent/domain-skills.json) as a single shared JSON array. To add a site, open a PR appending a `{ domain, skill }` entry.

## Build with Hanzi Browse

[Permalink: Build with Hanzi Browse](https://github.com/hanzili/hanzi-browse#build-with-hanzi-browse)

Embed browser automation in your product. Your app calls the Hanzi Browse API, a real browser executes the task, you get the result back.

1. **Get an API key** — [sign in](https://api.hanzilla.co/dashboard) to your developer console, then create a key
2. **Pair a browser** — create a pairing token, send your user a pairing link (`/pair/{token}`) — they click it and auto-pair
3. **Run a task** — `POST /v1/tasks` with a task and browser session ID
4. **Get the result** — poll `GET /v1/tasks/:id` until complete, or use `runTask()` which blocks

```
import { HanziClient } from '@hanzi-browse/sdk';

const client = new HanziClient({ apiKey: process.env.HANZI_API_KEY });

const { pairingToken } = await client.createPairingToken();
const sessions = await client.listSessions();

const result = await client.runTask({
  browserSessionId: sessions[0].id,
  task: 'Read the patient chart on the current page',
});
console.log(result.answer);
```

[API reference](https://browse.hanzilla.co/docs.html#build-with-hanzi) · [Dashboard](https://api.hanzilla.co/dashboard) · [Sample integration](https://github.com/hanzili/hanzi-browse/blob/main/examples/partner-quickstart)

## Tools

[Permalink: Tools](https://github.com/hanzili/hanzi-browse#tools)

| Tool | Description |
| --- | --- |
| `browser_start` | Run a task. Blocks until complete. |
| `browser_message` | Send follow-up to an existing session. |
| `browser_status` | Check progress. |
| `browser_stop` | Stop a task. |
| `browser_screenshot` | Capture current page as image. |

## Pricing

[Permalink: Pricing](https://github.com/hanzili/hanzi-browse#pricing)

|  | Managed | BYOM |
| --- | --- | --- |
| **Price** | $0.05/task (20 free/month) | Free forever |
| **AI model** | We handle it (Gemini) | Your own key |
| **Data** | Processed on Hanzi Browse servers | Never leaves your machine |
| **Billing** | Only completed tasks. Errors are free. | N/A |

Building a product? [Contact us](mailto:hanzili0217@gmail.com?subject=Partner%20pricing) for volume pricing.

## Development

[Permalink: Development](https://github.com/hanzili/hanzi-browse#development)

**Prerequisites:** [Node.js 18+](https://nodejs.org/), [Docker Desktop](https://docs.docker.com/get-docker/) (must be running before `make fresh`).

### First time (local setup)

[Permalink: First time (local setup)](https://github.com/hanzili/hanzi-browse#first-time-local-setup)

```
git clone https://github.com/hanzili/hanzi-browse
cd hanzi-browse
make fresh
```

Performs full setup: installs deps, builds server/dashboard/extension, starts Postgres, runs migrations, and launches the dev server (~90s).

### Run the project

[Permalink: Run the project](https://github.com/hanzili/hanzi-browse#run-the-project)

```
make dev
```

Starts the backend services (Postgres + migrations + API server) and serves the dashboard UI.

- API: [http://localhost:3456](http://localhost:3456/)
- Dashboard (requires Google OAuth): [http://localhost:3456/dashboard](http://localhost:3456/dashboard)

### Configuration

[Permalink: Configuration](https://github.com/hanzili/hanzi-browse#configuration)

The defaults in `.env.example` are enough to run the server.

Optional services:

- **Google OAuth** (dashboard sign-in) -- add `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` to `.env`
- **Stripe** (credit purchases) -- add test keys to `.env`
- **Vertex AI** (managed task execution) -- see `.env.example` for setup steps
- **PostHog** (analytics) -- add `POSTHOG_API_KEY` to enable local CLI telemetry, dashboard analytics, managed backend analytics, and the example apps; optionally set `POSTHOG_HOST`

### Load the extension

[Permalink: Load the extension](https://github.com/hanzili/hanzi-browse#load-the-extension)

Open `chrome://extensions`, enable Developer Mode, click "Load unpacked", and select the project root (the folder that contains `manifest.json`).

### Verify everything works

[Permalink: Verify everything works](https://github.com/hanzili/hanzi-browse#verify-everything-works)

After `make dev` is running and the extension is loaded, test both user paths:

**Test 1: MCP / CLI mode (user path)**

```
# In a separate terminal:
node server/dist/cli.js start "Go to example.com and tell me the page title"
```

You should see a Chrome window open, the agent navigate to example.com, and return the page title. If this works, the relay + extension + agent loop are all connected.

**Test 2: Managed API mode (developer path)**

```
# 1. Check the API is running
curl http://localhost:3456/v1/health

# 2. Open the dashboard and sign in (requires Google OAuth configured)
open http://localhost:3456/dashboard

# 3. Create an API key from the dashboard, then:
curl -X POST http://localhost:3456/v1/browser-sessions/pair \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

# 4. Open the pairing URL in Chrome (from the response)
open "http://localhost:3456/pair/PAIRING_TOKEN"

# 5. After pairing, run a task
curl -X POST http://localhost:3456/v1/tasks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"task": "Go to example.com and read the title", "browser_session_id": "SESSION_ID"}'

# 6. Check the result
curl http://localhost:3456/v1/tasks/TASK_ID \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Test 3: Embed widget**

Create a test HTML file and open it in Chrome:

```
<div id="hanzi"></div>
<script src="http://localhost:3456/embed.js"></script>
<script>
  HanziConnect.mount('#hanzi', {
    apiKey: 'YOUR_PUBLISHABLE_KEY',
    apiUrl: 'http://localhost:3456',
    onConnected: (id) => console.log('Connected:', id),
    onError: (err) => console.log('Error:', err),
  });
</script>
```

You should see the pairing widget with step-by-step instructions.

### Notes

[Permalink: Notes](https://github.com/hanzili/hanzi-browse#notes)

- **Local vs CLI usage** \-\- `npx hanzi-browse setup` is for packaged usage and may not work in a local clone
- **Port conflicts** \-\- if you see `EADDRINUSE` on `3456`, stop existing processes or run `make stop`
- **No Google OAuth?** \-\- The dashboard sign-in won't work, but you can seed a test workspace directly in the database and use the API key for testing

### Commands

[Permalink: Commands](https://github.com/hanzili/hanzi-browse#commands)

| Command | What it does |
| --- | --- |
| `make fresh` | Full first-time setup (deps + build + DB + start) |
| `make dev` | Start everything (DB + migrate + server) |
| `make build` | Rebuild server + dashboard + extension |
| `make stop` | Stop Postgres |
| `make clean` | Stop + delete database volume |
| `make check-prereqs` | Verify Node 18+ and Docker are available |
| `make help` | Show all commands |

## Contributing

[Permalink: Contributing](https://github.com/hanzili/hanzi-browse#contributing)

We welcome contributions! See [CONTRIBUTING.md](https://github.com/hanzili/hanzi-browse/blob/main/CONTRIBUTING.md) for setup instructions.

Good first contributions: new skills, landing pages, site-pattern files, platform testing, translations. Check the [open issues](https://github.com/hanzili/hanzi-browse/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).

## Community

[Permalink: Community](https://github.com/hanzili/hanzi-browse#community)

[Discord](https://discord.gg/hahgu5hcA5) · [Documentation](https://browse.hanzilla.co/docs.html) · [Twitter](https://x.com/user)

## Privacy

[Permalink: Privacy](https://github.com/hanzili/hanzi-browse#privacy)

Hanzi Browse operates in different modes with different data handling. [Read the privacy policy](https://github.com/hanzili/hanzi-browse/blob/main/PRIVACY.md).

- **BYOM**: No data sent to Hanzi Browse servers. Screenshots go to your chosen AI provider only.
- **Managed / API**: Task data processed on Hanzi Browse servers via Google Vertex AI.

## License

[Permalink: License](https://github.com/hanzili/hanzi-browse#license)

[Polyform Noncommercial 1.0.0](https://github.com/hanzili/hanzi-browse/blob/main/LICENSE)

## About

let any ai agent use the local browser


[browse.hanzilla.co/](https://browse.hanzilla.co/ "https://browse.hanzilla.co/")

### Topics

[chrome-extension](https://github.com/topics/chrome-extension "Topic: chrome-extension") [chrome](https://github.com/topics/chrome "Topic: chrome") [mcp](https://github.com/topics/mcp "Topic: mcp") [developer-tools](https://github.com/topics/developer-tools "Topic: developer-tools") [cursor](https://github.com/topics/cursor "Topic: cursor") [browser-automation](https://github.com/topics/browser-automation "Topic: browser-automation") [codex](https://github.com/topics/codex "Topic: codex") [ai-agents](https://github.com/topics/ai-agents "Topic: ai-agents") [web-automation](https://github.com/topics/web-automation "Topic: web-automation") [windsurf](https://github.com/topics/windsurf "Topic: windsurf") [linkedin-automation](https://github.com/topics/linkedin-automation "Topic: linkedin-automation") [ai-agent](https://github.com/topics/ai-agent "Topic: ai-agent") [computer-use](https://github.com/topics/computer-use "Topic: computer-use") [model-context-protocol](https://github.com/topics/model-context-protocol "Topic: model-context-protocol") [claude-code](https://github.com/topics/claude-code "Topic: claude-code")

### Resources

[Readme](https://github.com/hanzili/hanzi-browse#readme-ov-file)

### License

[View license](https://github.com/hanzili/hanzi-browse#License-1-ov-file)

### Contributing

[Contributing](https://github.com/hanzili/hanzi-browse#contributing-ov-file)

### Uh oh!

There was an error while loading. [Please reload this page](https://github.com/hanzili/hanzi-browse).

[Activity](https://github.com/hanzili/hanzi-browse/activity)

### Stars

**167**
stars


### Watchers

**0**
watching


### Forks

[**52**\\
forks](https://github.com/hanzili/hanzi-browse/forks)

[Report repository](https://github.com/contact/report-content?content_url=https%3A%2F%2Fgithub.com%2Fhanzili%2Fhanzi-browse&report=hanzili+%28user%29)

## [Releases](https://github.com/hanzili/hanzi-browse/releases)

No releases published

## [Packages\  0](https://github.com/users/hanzili/packages?repo_name=hanzi-browse)

No packages published

## [Contributors\  16](https://github.com/hanzili/hanzi-browse/graphs/contributors)

- [![@hanzili](https://avatars.githubusercontent.com/u/96609857?s=64&v=4)](https://github.com/hanzili)
- [![@claude](https://avatars.githubusercontent.com/u/81847?s=64&v=4)](https://github.com/claude)
- [![@FelixNg1022](https://avatars.githubusercontent.com/u/83550578?s=64&v=4)](https://github.com/FelixNg1022)
- [![@Llawlietcyd](https://avatars.githubusercontent.com/u/144309819?s=64&v=4)](https://github.com/Llawlietcyd)
- [![@IVVI0927](https://avatars.githubusercontent.com/u/183055163?s=64&v=4)](https://github.com/IVVI0927)
- [![@tyrahappy](https://avatars.githubusercontent.com/u/17371143?s=64&v=4)](https://github.com/tyrahappy)
- [![@Jeevanm2004](https://avatars.githubusercontent.com/u/199288486?s=64&v=4)](https://github.com/Jeevanm2004)
- [![@flazouh](https://avatars.githubusercontent.com/u/25705704?s=64&v=4)](https://github.com/flazouh)
- [![@JYins](https://avatars.githubusercontent.com/u/90402453?s=64&v=4)](https://github.com/JYins)
- [![@FredZ6](https://avatars.githubusercontent.com/u/93838088?s=64&v=4)](https://github.com/FredZ6)
- [![@Leo-Liu66](https://avatars.githubusercontent.com/u/158031229?s=64&v=4)](https://github.com/Leo-Liu66)
- [![@xspyce](https://avatars.githubusercontent.com/u/233141092?s=64&v=4)](https://github.com/xspyce)
- [![@waleedsworld](https://avatars.githubusercontent.com/u/82969990?s=64&v=4)](https://github.com/waleedsworld)
- [![@JiwaniZakir](https://avatars.githubusercontent.com/u/108548454?s=64&v=4)](https://github.com/JiwaniZakir)

[\+ 2 contributors](https://github.com/hanzili/hanzi-browse/graphs/contributors)

## Languages

- [JavaScript53.5%](https://github.com/hanzili/hanzi-browse/search?l=javascript)
- [TypeScript27.3%](https://github.com/hanzili/hanzi-browse/search?l=typescript)
- [HTML14.6%](https://github.com/hanzili/hanzi-browse/search?l=html)
- [CSS2.9%](https://github.com/hanzili/hanzi-browse/search?l=css)
- [Shell1.4%](https://github.com/hanzili/hanzi-browse/search?l=shell)
- [Makefile0.3%](https://github.com/hanzili/hanzi-browse/search?l=makefile)

You can’t perform that action at this time.