Allow
These run without a prompt.
navigatesnapshotgetwaitdialog
page.snapshot
network.list_requests
console.list_messages
diagnostics.doctor
Observable Electron browser · macOS arm64 cask · v0.1.2
AI Web Debugger embeds one sandboxed browser page and hands a model a list of named tools. The model can read the page, and it can click or type after you confirm. It does not get the DOM, the network stack, or storage.
brew tap dickwu/tap brew install --cask ai-web-debugger
page.snapshot snapshot · read · allowed
These run without a prompt.
navigatesnapshotgetwaitdialog
page.snapshot
network.list_requests
console.list_messages
diagnostics.doctor
The Agent tab asks. If the countdown ends, the call is denied.
clickfillinteracteval-readonly
page.click
page.type
page.press
page.scroll
page.evaluate_readonly
No configured tool uses these categories.
evalnetworkstatedownloadupload
Window
The address bar has Back, Forward, Reload, Stop, and a URL field. The target page is a separate WebContentsView: nodeIntegration off, contextIsolation on, sandbox on, no preload. The debug tabs are Network, Console, Snapshot, Agent, and Settings. An approval request switches to Agent.
The Agent tab has a task field (the placeholder example is “Why is login failing?”), Run Agent, Cancel, Manual Tools, an Activity feed, and Agent Result. Page-derived tool output is marked “untrusted page content”. Evidence in a result can jump to Network, Console, or Snapshot.
Settings cards are Capture, Security, Browser, and LLM. Capture covers max body bytes, POST data, response bodies, and a Redact secrets control described as masking authorization headers, tokens, and cookies. Content boundaries stay on. Allowed domains are one domain per line; empty means allow all. Viewport, user agent, and timeout come from the environment or a config file. The LLM card keeps the provider, the model, and the name of the variable that holds the key.
Containment
CDP events from the target page stay in the main process. NetworkRecorder and ConsoleRecorder redact secrets and write CaptureStore. Tool handlers read that store. ContentBoundaryWrapper wraps page text with a nonce for the run. AgentRunner calls only toolRegistry.run(), then the provider: mock by default, or anthropic.
The renderer talks through window.debuggerApp, exposed by the preload contextBridge. Raw ipcRenderer is not exposed. require inside the target page is undefined.
Tool registry
Risk on a tool is read or page_action. The lane comes from the category, not from that risk label. dialog.accept and dialog.dismiss are page_action and still allowed, because dialog is on the allow list.
| Tool | Category | Risk | Policy |
|---|---|---|---|
| Allow | |||
| browser.open_url | navigate | page_action | Allow |
| browser.open_blank | navigate | page_action | Allow |
| browser.reload | navigate | page_action | Allow |
| browser.back | navigate | page_action | Allow |
| browser.forward | navigate | page_action | Allow |
| browser.stop | navigate | page_action | Allow |
| browser.batch | navigate | page_action | Allow |
| browser.wait_for_load_state | wait | read | Allow |
| page.snapshot | snapshot | read | Allow |
| page.screenshot | snapshot | read | Allow |
| page.get_interactive_elements | snapshot | read | Allow |
| page.get_by_ref | snapshot | read | Allow |
| page.find | snapshot | read | Allow |
| page.query_selector | snapshot | read | Allow |
| page.wait_for | wait | read | Allow |
| network.list_requests | get | read | Allow |
| network.get_request | get | read | Allow |
| network.get_response_body | get | read | Allow |
| console.list_messages | get | read | Allow |
| storage.get_cookies | get | read | Allow |
| storage.get_local_storage | get | read | Allow |
| storage.get_session_storage | get | read | Allow |
| dialog.status | dialog | read | Allow |
| dialog.accept | dialog | page_action | Allow |
| dialog.dismiss | dialog | page_action | Allow |
| diagnostics.summarize_current_page | get | read | Allow |
| diagnostics.doctor | get | read | Allow |
| Confirm | |||
| page.scroll | interact | page_action | Confirm |
| page.click | click | page_action | Confirm |
| page.type | fill | page_action | Confirm |
| page.press | interact | page_action | Confirm |
| page.evaluate_readonly | eval-readonly | read | Confirm |
Deny covers eval, network, state, download, and upload. None of those categories has a configured tool. Precedence is deny, then confirm, then allow.
Install
The Homebrew cask is ai-web-debugger in dickwu/tap. It requires macOS Big Sur or newer on Apple silicon, and it installs AI Web Debugger.app from the arm64 disk image. The cask homepage is the GitHub repo.
These two lines are the install in the product README and the tap README.
brew tap dickwu/tap brew install --cask ai-web-debugger
Same cask, one command. Homebrew taps dickwu/tap if you do not already have it.
brew install --cask dickwu/tap/ai-web-debugger
The macOS build is unsigned and not notarized. If macOS shows a damaged app or quarantine warning, run:
sudo xattr -d com.apple.quarantine /Applications/AI\ Web\ Debugger.app/
The disk image and zip are Apple silicon. The release also has a Windows setup exe and a Linux AppImage.
The app uses Bun. bun run fixture is optional. It serves the debug site at http://127.0.0.1:4321/, with a deliberate 500, a two-second /api/slow response, and /api/secret for the redactor. Open that URL from the address bar.
git clone https://github.com/dickwu/ai-web-debugger.git cd ai-web-debugger bun install bun run dev bun run fixture
dickwu/tap and install the ai-web-debugger cask, or download the arm64 disk image.On disk
config.json in the user data directory./ai-web-debugger.json in the projectAI_WEB_DEBUGGER_On macOS the user data directory is ~/Library/Application Support/ai-web-debugger.
LLM_PROVIDER — mock (default) or anthropicLLM_API_KEY — key for that providerLLM_MODEL — for example claude-3-5-sonnet-20241022AI_WEB_DEBUGGER_LLM_PROVIDER, AI_WEB_DEBUGGER_LLM_API_KEY, and AI_WEB_DEBUGGER_LLM_MODEL override the three aboveA new session id is created. Under the user data directory:
sessions/<id>/screenshots/*.pngsessions/<id>/events.jsonlsessions/<id>/session.jsonlogs/main.jsonlThe status bar shows the version and Check for updates. The v0.1.2 release includes latest-mac.yml, latest.yml, and latest-linux.yml for electron-updater.
v0.1 limits
WebContentsView per session. No multi-tab.CaptureStore is in memory. No SQLite.page.wait_for implements a subset of Playwright-style assertions.Questions
The model never touches the DOM, network, or storage. It calls tools on a ToolRegistry. Those tools read a CaptureStore of network and console records after secrets are redacted, and every tool that returns page text is wrapped in a content boundary with a nonce for that run before the model sees it.
ActionPolicy allows navigate, snapshot, get, wait, and dialog. It asks you to confirm click, fill, interact, and eval-readonly. It denies eval, network, state, download, and upload. A call that needs confirmation opens Action Requires Approval on the Agent tab, shows the tool name, risk, and input summary, and denies the action if the countdown runs out.
On an Apple silicon Mac running Big Sur or newer, run brew tap dickwu/tap and then brew install --cask ai-web-debugger. That cask is dickwu/tap/ai-web-debugger. It installs AI Web Debugger.app from the arm64 disk image.
The macOS build is unsigned and not notarized. If macOS shows a damaged app or quarantine warning, run sudo xattr -d com.apple.quarantine /Applications/AI\ Web\ Debugger.app/
mock is the default, and anthropic is the other wired provider. Set LLM_PROVIDER, LLM_API_KEY, and LLM_MODEL, or override them with AI_WEB_DEBUGGER_LLM_PROVIDER, AI_WEB_DEBUGGER_LLM_API_KEY, and AI_WEB_DEBUGGER_LLM_MODEL. An OpenAI adapter is not wired in v0.1. The README gives claude-3-5-sonnet-20241022 as a model name example.
One target page per session. v0.1 does not include multi-tab support, full iframe and OOPIF tracking, SQLite persistence, code-signing and notarization, network interception or mutation, the rest of the Playwright-style assertions in page.wait_for, or an OpenAI provider. CaptureStore stays in memory.
Each launch creates a new session id. On macOS the user data directory is ~/Library/Application Support/ai-web-debugger. Screenshots, events.jsonl, and session.json live under sessions, and the main process log is logs/main.jsonl. Settings load from built-in defaults, then that directory's config.json, then ./ai-web-debugger.json, then AI_WEB_DEBUGGER_ environment variables. Later entries win.