cmux-browser

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗

End-user browser automation with cmux. Use when you need to open sites, inspect or interact with browser surfaces, wait for page state, and extract data without stealing focus.

skills/cmux-browser/SKILL.md

Download bundle ↓
main · 6f118af13 bundle filesScanned 2026-09-15

references/surface-discovery.md

1,025 tokens · o200k_base · 4,117 bytes

Browser Surface Discovery

Surface-bound existing-surface browser commands need an explicit surface handle. The CLI also has a small, explicit global-verb allowlist (for example identify, devtools, design-mode, zoom, history, and creation/import verbs); those commands may omit a handle according to SKILL.md. Find a surface-bound handle with read-only topology commands; never select or focus a workspace just to make an implicit target work.

Caller workspace

Start with the context of the terminal that launched the agent:

cmux identify --json
if [[ -n "${CMUX_WORKSPACE_ID:-}" ]]; then
  cmux tree --workspace "$CMUX_WORKSPACE_ID" --json
else
  # With no caller anchor, use the server's current context after identify.
  cmux tree --json
fi

CMUX_WORKSPACE_ID is the caller anchor, not necessarily the workspace visible on screen. If it is unavailable, use cmux identify --json and state that the current server context is being used.

For one known workspace, list its panes/surfaces without selecting it:

cmux --json list-pane-surfaces --workspace workspace:N

Browser in any workspace or window

tree --all --json is the non-focus-changing global inventory. The following filter prints only topology refs, not page titles or URLs:

cmux tree --all --json \
  | jq -r '
      .windows[]? as $window
      | $window.workspaces[]? as $workspace
      | $workspace.panes[]? as $pane
      | $pane.surfaces[]?
      | select(.type == "browser")
      | [$window.ref, $workspace.ref, $pane.ref, .ref]
      | @tsv'

Pick the surface by the workspace/pane the user named, or by a URL/title only when the user supplied enough context to disambiguate it. For URL/title-only context, use this exact-match filter; it emits only the unique surface ref and does not print the matched metadata:

MATCH_FIELD="url" # use "title" when matching a page title
MATCH_VALUE="${BROWSER_URL_OR_TITLE:?set BROWSER_URL_OR_TITLE without logging it}"
SURFACE="$(
  cmux tree --all --json |
    jq -r --arg field "$MATCH_FIELD" --arg value "$MATCH_VALUE" '
      [
        .windows[]? as $window
        | $window.workspaces[]? as $workspace
        | $workspace.panes[]? as $pane
        | $pane.surfaces[]?
        | select(.type == "browser")
        | select((if $field == "url" then (.url // "") else (.title // "") end) == $value)
        | .ref
      ] as $matches
      | if ($matches | length) == 1 then $matches[0]
        elif ($matches | length) == 0 then error("no matching browser surface")
        else error("multiple matches; use workspace/pane context")
        end'
)"
if [[ -z "$SURFACE" ]]; then
  printf '%s\n' 'no uniquely matching browser surface; provide workspace/pane context' >&2
  exit 1
fi
cmux browser --surface "$SURFACE" get url

Do not print or store raw authenticated-page metadata unnecessarily.

Inspect the chosen surface

SURFACE="surface:N"
cmux browser --surface "$SURFACE" get url
cmux browser --surface "$SURFACE" get title
cmux browser --surface "$SURFACE" tab list --json
cmux browser --surface "$SURFACE" snapshot --interactive

These inspection commands do not focus the browser or its workspace. Avoid select-workspace, focus-pane, focus-panel, focus-webview, and other focus-intent verbs unless the user explicitly asked to change visible focus.

Stale handles and help drift

Surface refs can change when a tab is closed/replaced or a browser is restored. If a previously valid handle is rejected, run cmux tree --all --json again and reselect from the authoritative topology. Never fall back to a focused surface or a guessed numeric index.

When installed documentation and the binary disagree, stop and refresh the contract before continuing. The installer is pinned to the reviewed skills 1.5.23 release:

cmux browser --help
cmux --version
npx --yes skills@1.5.23 add manaflow-ai/cmux --global --yes --skill cmux-browser --agent claude-code codex --copy

An already-running agent may have cached the old skill; start a fresh session after the install when needed.

Referenced from SKILL.md