references/surface-discovery.md
1,025 tokens · o200k_base · 4,117 bytes
Source excerpt starting at line 1.# Browser Surface Discovery Surface-bound existing-surface browser commands need an explicit surfacehandle. The CLI also has a small, explicit global-verb allowlist (for example`identify`, `devtools`, `design-mode`, `zoom`, `history`, and creation/importverbs); those commands may omit a handle according to `SKILL.md`. Find asurface-bound handle with read-only topology commands; never select or focus aworkspace just to make an implicit target work. ## Caller workspace Start with the context of the terminal that launched the agent: ```bashcmux identify --jsonif [[ -n "${CMUX_WORKSPACE_ID:-}" ]]; then cmux tree --workspace "$CMUX_WORKSPACE_ID" --jsonelse # With no caller anchor, use the server's current context after identify. cmux tree --jsonfi``` `CMUX_WORKSPACE_ID` is the caller anchor, not necessarily the workspace visibleon screen. If it is unavailable, use `cmux identify --json` and state that thecurrent server context is being used. For one known workspace, list its panes/surfaces without selecting it: ```bashcmux --json list-pane-surfaces --workspace workspace:N``` ## Browser in any workspace or window `tree --all --json` is the non-focus-changing global inventory. The followingfilter prints only topology refs, not page titles or URLs: ```bashcmux 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 onlywhen the user supplied enough context to disambiguate it. For URL/title-onlycontext, use this exact-match filter; it emits only the unique surface ref anddoes not print the matched metadata: ```bashMATCH_FIELD="url" # use "title" when matching a page titleMATCH_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 1ficmux browser --surface "$SURFACE" get url``` Do not print or store raw authenticated-page metadata unnecessarily. ## Inspect the chosen surface ```bashSURFACE="surface:N"cmux browser --surface "$SURFACE" get urlcmux browser --surface "$SURFACE" get titlecmux browser --surface "$SURFACE" tab list --jsoncmux 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 otherfocus-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 andreselect from the authoritative topology. Never fall back to a focused surfaceor a guessed numeric index. When installed documentation and the binary disagree, stop and refresh thecontract before continuing. The installer is pinned to the reviewed `skills`1.5.23 release: ```bashcmux browser --helpcmux --versionnpx --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 sessionafter the install when needed.