Start the broker once, then open one tab per agent and drive it: navigate, click, type,
hover, drag, upload, wait for content, read the accessibility tree, run raw JavaScript,
capture. 24 commands, tested against a real Chromium tab, not just compiled.
-
01
Start the broker (idempotent: does nothing if it's already running)
hublot start
-
02
Check its state and the open tabs (alias: hublot list)
hublot status
-
03
Open a tab for this label (reuses it if it already exists)
hublot open --label claude-main --url "https://example.com"
-
04
Navigate inside that tab
hublot navigate --label claude-main --url "https://example.com/page2"
-
05
Go back to the previous page
hublot back --label claude-main
-
06
Click an element (Playwright CSS selector)
hublot click --label claude-main --selector "button.submit"
-
07
Hover an element (e.g. to reveal a menu)
hublot hover --label claude-main --selector "nav .menu-trigger"
-
08
Type into a field (replaces the value outright, no fake keystrokes)
hublot type --label claude-main --selector "input[name=q]" --text "search"
-
09
Press a key, on an element or globally
hublot press --label claude-main --selector "input[name=q]" --key Enter
-
10
Pick an option in a dropdown
hublot select --label claude-main --selector "#country" --value FR
-
11
Drag one element onto another
hublot drag --label claude-main --source "#card-1" --target "#column-2"
-
12
Send a file into an <input type=file>
hublot upload --label claude-main --selector "input[type=file]" --files "C:\path\file.pdf"
-
13
Decide how this tab answers JS dialogs (default: dismiss)
hublot dialog --label claude-main --action accept
-
14
Wait for an element or a piece of text to show up
hublot wait --label claude-main --text "Loading complete"
-
15
Find elements containing a text, without guessing a CSS selector
hublot find --label claude-main --text "Add to cart"
-
16
Run a JS expression inside the page's own sandbox and print the result (JSON)
hublot evaluate --label claude-main --expression "document.title"
-
17
Resize this tab's viewport
hublot resize --label claude-main --width 1280 --height 800
-
18
Extract text (innerText) from an element, or the whole page if --selector is omitted
hublot extract --label claude-main --selector ".result"
-
19
Accessibility tree (roles/names) — more reliable than a screenshot for an agent to locate something
hublot snapshot --label claude-main
-
20
Take a screenshot: a timestamped PNG is written to disk, its path printed to stdout
hublot screenshot --label claude-main
-
21
Read the JS console log captured since the tab was opened (capped at 500 entries)
hublot console --label claude-main
-
22
Read the network requests captured since the tab was opened (method, status, URL)
hublot network --label claude-main
-
23
Close this tab (the browser itself stays open)
hublot close --label claude-main
-
24
Stop the broker entirely and close the browser
hublot stop
⚠
hublot run-code-unsafe --label claude-main --code "async (page) => page.title()"
Runs Playwright/Node code inside the broker process itself — full filesystem and
process access, not just the page's JS sandbox like evaluate.
OPT-IN · PERSONAL, TRUSTED MACHINES ONLY
MULTI-AGENT CONVENTION
Each agent should keep a stable --label that names itself, not just the
task at hand, and reuse it for its whole session instead of opening a new tab for
every command. That is what keeps several agents from ever stepping on each other,
even on the same machine.