Browser Automation with cmux
Use this skill for browser tasks inside cmux webviews. Requires cmux environment ($CMUX_WORKSPACE_ID). Outside cmux, this skill's features are unavailable.
Core Workflow
- Open or target a browser surface.
- Verify navigation with
get urlbefore waiting or snapshotting. - Snapshot (
--interactive) to get fresh element refs. - Act with refs (
click,fill,type,select,press). - Wait for state changes.
- Re-snapshot after DOM/navigation changes.
cmux --json browser open https://example.com
# use returned surface ref, for example: surface:7
cmux browser surface:7 get url
cmux browser surface:7 wait --load-state complete --timeout-ms 15000
cmux browser surface:7 snapshot --interactive
cmux browser surface:7 fill e1 "hello"
cmux --json browser surface:7 click e2 --snapshot-after
cmux browser surface:7 snapshot --interactive
Surface Targeting
# identify current context
cmux identify --json
# open routed to a specific topology target
cmux browser open https://example.com --workspace workspace:2 --window window:1 --json
Notes:
- CLI output defaults to short refs (
surface:N,pane:N,workspace:N,window:N). - UUIDs are still accepted on input; only request UUID output when needed (
--id-format uuids|both). - Keep using one
surface:Nper task unless you intentionally switch.
Wait Support
cmux browser <surface> wait --selector "#ready" --timeout-ms 10000
cmux browser <surface> wait --text "Success" --timeout-ms 10000
cmux browser <surface> wait --url-contains "/dashboard" --timeout-ms 10000
cmux browser <surface> wait --load-state complete --timeout-ms 15000
cmux browser <surface> wait --function "document.readyState === 'complete'" --timeout-ms 10000
Common Flows
Form Submit
cmux --json browser open https://example.com/signup
cmux browser surface:7 get url
cmux browser surface:7 wait --load-state complete --timeout-ms 15000
cmux browser surface:7 snapshot --interactive
cmux browser surface:7 fill e1 "Jane Doe"
cmux browser surface:7 fill e2 "jane@example.com"
cmux --json browser surface:7 click e3 --snapshot-after
cmux browser surface:7 wait --url-contains "/welcome" --timeout-ms 15000
cmux browser surface:7 snapshot --interactive
Clear an Input
cmux browser surface:7 fill e11 "" --snapshot-after --json
cmux browser surface:7 get value e11 --json
Stable Agent Loop (Recommended)
# navigate -> verify -> wait -> snapshot -> action -> snapshot
cmux browser surface:7 get url
cmux browser surface:7 wait --load-state complete --timeout-ms 15000
cmux browser surface:7 snapshot --interactive
cmux --json browser surface:7 click e5 --snapshot-after
cmux browser surface:7 snapshot --interactive
If get url is empty or about:blank, navigate first instead of waiting on load state.
Deep-Dive References
| Reference | When to Use |
|---|---|
| Commands | Full browser command mapping and quick syntax |
| Snapshot and Refs | Ref lifecycle and stale-ref troubleshooting |
| Authentication | Login/OAuth/2FA patterns and state save/load |
| Session Management | Multi-surface isolation and state persistence patterns |
| Video Recording | Recording limitations and screenshot/snapshot alternatives |
| Proxy Support | Proxy behavior in WKWebView and workarounds |
Ready-to-Use Templates
| Template | Description |
|---|---|
| Form Automation | Snapshot/ref form fill loop |
| Authenticated Session | Login once, save/load state |
| Capture Workflow | Navigate + capture snapshots/screenshots |
Limits (WKWebView)
These are not supported in cmux's embedded browser (WKWebView-based):
- Viewport emulation
- Offline emulation
- Trace/screencast recording
- Network route interception/mocking
- Low-level raw input injection
Use supported high-level commands (click, fill, press, scroll, wait, snapshot) instead.
Gotchas
- WKWebView-based, not Chromium — viewport emulation, network interception, and trace/screencast recording are not supported. Don't attempt CDP-style commands.
- Element refs (
e1,e2, ...) are invalidated on any DOM change — always re-snapshot after navigation, modal open/close, or mutating actions. Use--snapshot-afteron click/fill to combine action + snapshot. snapshot --interactivecan returnjs_erroron complex pages — fall back toget text bodyorget html bodyfor content extraction.browser opentargets the workspace of the calling terminal (via$CMUX_WORKSPACE_ID), even if a different workspace is currently focused. Use--workspaceto override.gotoandnavigateare aliases — both work for same-surface navigation.- Always use
--jsonwithbrowser open— without it, the output is plain text and the returned surface ref is harder to parse reliably.cmux --json browser open <url>returns structured JSON with the surface ref.
Troubleshooting
js_error on snapshot --interactive or eval
Some complex pages can reject the JavaScript used for rich snapshots.
Recovery:
cmux browser surface:7 get url
cmux browser surface:7 get text body
cmux browser surface:7 get html body
- Use
get urlfirst to confirm the page actually navigated. - Fall back to
get text bodyorget html bodywhensnapshot --interactivereturnsjs_error. - If the page is still failing, navigate to a simpler intermediate page, then retry.