From avadbot
Fast headless browser for QA testing and site dogfooding. Navigate any URL, interact with elements, verify page state, diff before/after actions, take annotated screenshots, check responsive layouts, test forms and uploads, handle dialogs, assert element states, and import cookies from your real browser for authenticated page testing. ~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a user flow, or file a bug with evidence. Do NOT use for automated CI pipelines, non-browser tasks, or general code execution — this is an interactive browser tool for QA and dogfooding.
How this skill is triggered — by the user, by Claude, or both
Slash command
/avadbot:avad-browseThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->
ARCHITECTURE.mdBROWSER.mdSKILL.md.tmplbin/find-browsebin/remote-slugsrc/browser-manager.tssrc/buffers.tssrc/cli.tssrc/commands.tssrc/config.tssrc/cookie-import-browser.tssrc/cookie-picker-routes.tssrc/cookie-picker-ui.tssrc/find-browse.tssrc/meta-commands.tssrc/read-commands.tssrc/server.tssrc/snapshot.tssrc/url-validation.tssrc/write-commands.tsPersistent headless Chromium. First call auto-starts (~3s), then ~100ms per command. State persists between calls (cookies, tabs, login sessions).
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
B=""
# Primary tiers — new name (7 tiers)
[ -n "$_ROOT" ] && [ -x "$_ROOT/skills/avad-browse/dist/avad-browse" ] && B="$_ROOT/skills/avad-browse/dist/avad-browse"
[ -z "$B" ] && [ -n "$_ROOT" ] && for _D in "$_ROOT"/*/skills/avad-browse/dist/avad-browse; do [ -x "$_D" ] && B="$_D" && break; done 2>/dev/null
[ -z "$B" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/avad-browse/dist/avad-browse" ] && B="$_ROOT/.claude/skills/avad-browse/dist/avad-browse"
[ -z "$B" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/avadbot/avad-browse/dist/avad-browse" ] && B="$_ROOT/.claude/skills/avadbot/avad-browse/dist/avad-browse"
[ -z "$B" ] && [ -x ~/.claude/skills/avad-browse/dist/avad-browse ] && B=~/.claude/skills/avad-browse/dist/avad-browse
[ -z "$B" ] && [ -x ~/.claude/skills/avadbot/avad-browse/dist/avad-browse ] && B=~/.claude/skills/avadbot/avad-browse/dist/avad-browse
[ -z "$B" ] && for _P in ~/.claude/plugins/*/skills/avad-browse/dist/avad-browse; do [ -x "$_P" ] && B="$_P" && break; done 2>/dev/null
# Legacy fallbacks — old name (backward compat, 6 tiers)
[ -z "$B" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/skills/browse/dist/browse" ] && B="$_ROOT/skills/browse/dist/browse"
[ -z "$B" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/browse/dist/browse" ] && B="$_ROOT/.claude/skills/browse/dist/browse"
[ -z "$B" ] && [ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/avadbot/browse/dist/browse" ] && B="$_ROOT/.claude/skills/avadbot/browse/dist/browse"
[ -z "$B" ] && [ -x ~/.claude/skills/browse/dist/browse ] && B=~/.claude/skills/browse/dist/browse
[ -z "$B" ] && [ -x ~/.claude/skills/avadbot/browse/dist/browse ] && B=~/.claude/skills/avadbot/browse/dist/browse
[ -z "$B" ] && for _P in ~/.claude/plugins/*/skills/browse/dist/browse; do [ -x "$_P" ] && B="$_P" && break; done 2>/dev/null
if [ -x "$B" ]; then
echo "READY: $B"
else
echo "NEEDS_SETUP"
fi
If NEEDS_SETUP:
package.json with "name": "avadbot"): AVADBOT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)/avadbot; [ -f "$AVADBOT_ROOT/package.json" ] || AVADBOT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null); [ -f "$AVADBOT_ROOT/package.json" ] || echo "Cannot find avadbot root"cd "$AVADBOT_ROOT" && bun install && bun run buildbun is not installed: curl -fsSL https://bun.sh/install | bashTo test authenticated pages, import cookies from your real browser:
$B cookie-import-browser comet --domain github.com
$B cookie-import-browser
Opens a picker UI — select domains to import, then verify:
$B cookies
Notes:
$B goto https://yourapp.com
$B text # content loads?
$B console # JS errors?
$B network # failed requests?
$B is visible ".main-content" # key elements present?
$B goto https://app.com/login
$B snapshot -i # see all interactive elements
$B fill @e3 "[email protected]"
$B fill @e4 "password"
$B click @e5 # submit
$B snapshot -D # diff: what changed after submit?
$B is visible ".dashboard" # success state present?
$B snapshot # baseline
$B click @e3 # do something
$B snapshot -D # unified diff shows exactly what changed
$B snapshot -i -a -o /tmp/annotated.png # labeled screenshot
$B screenshot /tmp/bug.png # plain screenshot
$B console # error log
$B snapshot -C # finds divs with cursor:pointer, onclick, tabindex
$B click @c1 # interact with them
$B is visible ".modal"
$B is enabled "#submit-btn"
$B is disabled "#submit-btn"
$B is checked "#agree-checkbox"
$B is editable "#name-field"
$B is focused "#search-input"
$B js "document.body.textContent.includes('Success')"
$B responsive /tmp/layout # mobile + tablet + desktop screenshots
$B viewport 375x812 # or set specific viewport
$B screenshot /tmp/mobile.png
$B upload "#file-input" /path/to/file.pdf
$B is visible ".upload-success"
$B dialog-accept "yes" # set up handler
$B click "#delete-button" # trigger dialog
$B dialog # see what appeared
$B snapshot -D # verify deletion happened
$B diff https://staging.app.com https://prod.app.com
The snapshot is your primary tool for understanding and interacting with pages.
-i --interactive Interactive elements only (buttons, links, inputs) with @e refs
-c --compact Compact (no empty structural nodes)
-d <N> --depth Limit tree depth (0 = root only, default: unlimited)
-s <sel> --selector Scope to CSS selector
-D --diff Unified diff against previous snapshot (first call stores baseline)
-a --annotate Annotated screenshot with red overlay boxes and ref labels
-o <path> --output Output path for annotated screenshot (default: /tmp/browse-annotated.png)
-C --cursor-interactive Cursor-interactive elements (@c refs — divs with pointer, onclick)
All flags can be combined freely. -o only applies when -a is also used.
Example: $B snapshot -i -a -C -o /tmp/annotated.png
Ref numbering: @e refs are assigned sequentially (@e1, @e2, ...) in tree order.
@c refs from -C are numbered separately (@c1, @c2, ...).
After snapshot, use @refs as selectors in any command:
$B click @e3 $B fill @e4 "value" $B hover @e1
$B html @e2 $B css @e5 "color" $B attrs @e6
$B click @c1 # cursor-interactive ref (from -C)
Output format: indented accessibility tree with @ref IDs, one element per line.
@e1 [heading] "Welcome" [level=1]
@e2 [textbox] "Email"
@e3 [button] "Submit"
Refs are invalidated on navigation — run snapshot again after goto.
Refs (@e1, @e2, ...) are cleared on full page navigation (framenavigated), but SPA client-side route changes (pushState/replaceState) do NOT trigger this event. After a SPA navigation (e.g., clicking a React Router link), existing refs may point to wrong or stale elements.
Workaround: Always run snapshot again after any SPA navigation to get fresh refs. If you clicked a link and the page content changed without a full reload, assume all refs are stale.
| Command | Description |
|---|---|
back | History back |
forward | History forward |
goto <url> | Navigate to URL |
reload | Reload page |
url | Print current URL |
| Command | Description |
|---|---|
accessibility | Full ARIA tree |
forms | Form fields as JSON |
html [selector] | innerHTML of selector (throws if not found), or full page HTML if no selector given |
links | All links as "text → href" |
text | Cleaned page text |
| Command | Description |
|---|---|
click <sel> | Click element |
cookie <name>=<value> | Set cookie on current page domain |
cookie-import <json> | Import cookies from JSON file |
cookie-import-browser [browser] [--domain d] | Import cookies from Comet, Chrome, Arc, Brave, or Edge (opens picker, or use --domain for direct import) |
dialog-accept [text] | Auto-accept next alert/confirm/prompt. Optional text is sent as the prompt response |
dialog-dismiss | Auto-dismiss next dialog |
fill <sel> <val> | Fill input |
header <name>:<value> | Set custom request header (colon-separated, sensitive values auto-redacted) |
hover <sel> | Hover element |
press <key> | Press key — Enter, Tab, Escape, ArrowUp/Down/Left/Right, Backspace, Delete, Home, End, PageUp, PageDown, or modifiers like Shift+Enter |
scroll [sel] | Scroll element into view, or scroll to page bottom if no selector |
select <sel> <val> | Select dropdown option by value, label, or visible text |
type <text> | Type into focused element |
upload <sel> <file> [file2...] | Upload file(s) |
useragent <string> | Set user agent |
viewport <WxH> | Set viewport size |
| `wait <sel | --networkidle |
| Command | Description |
|---|---|
| `attrs <sel | @ref>` |
| `console [--clear | --errors]` |
cookies | All cookies as JSON |
css <sel> <prop> | Computed CSS value |
dialog [--clear] | Dialog messages |
eval <file> | Run JavaScript from file and return result as string (path must be under /tmp or cwd) |
is <prop> <sel> | State check (visible/hidden/enabled/disabled/checked/editable/focused) |
js <expr> | Run JavaScript expression and return result as string |
network [--clear] | Network requests |
perf | Page load timings |
storage [set k v] | Read all localStorage + sessionStorage as JSON, or set to write localStorage |
| Command | Description |
|---|---|
diff <url1> <url2> | Text diff between pages |
pdf [path] | Save as PDF |
responsive [prefix] | Screenshots at mobile (375x812), tablet (768x1024), desktop (1280x720). Saves as {prefix}-mobile.png etc. |
| `screenshot [--viewport] [--clip x,y,w,h] [selector | @ref] [path]` |
| Command | Description |
|---|---|
snapshot [flags] | Accessibility tree with @e refs for element selection. Flags: -i interactive only, -c compact, -d N depth limit, -s sel scope, -D diff vs previous, -a annotated screenshot, -o path output, -C cursor-interactive @c refs |
| Command | Description |
|---|---|
chain | Run commands from JSON stdin. Format: [["cmd","arg1",...],...] |
| Command | Description |
|---|---|
closetab [id] | Close tab |
newtab [url] | Open new tab |
tab <id> | Switch to tab |
tabs | List open tabs |
| Command | Description |
|---|---|
handoff [message] | Open visible Chrome at current page for user takeover |
restart | Restart server |
resume | Re-snapshot after user takeover, return control to AI |
status | Health check |
stop | Shutdown server |
npx claudepluginhub agwacom/avadbot --plugin avadbotAutomates headless browser via agent-browser CLI: open/navigate sites, snapshot interactive elements for refs, click/fill forms, verify UI, scrape data, e2e test web apps.
CLI for browser automation: navigate sites, snapshot elements for refs, fill forms, click buttons, screenshot, scrape data, test web apps. Chains commands, imports auth state.
CLI for AI agents to automate browser tasks: open sites, snapshot DOM refs, fill forms, click elements, screenshot, extract data, test web apps.