All skills
manaflow-ai avatar

/cmux-browser

@f97f1e9
by manaflow-aimanaflow-ai/cmux28k stars
2,423

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.

Use this Skill: https://skilld.dev/gh/manaflow-ai/cmux/cmux-browser

This session only. Nothing lands on disk.

referencesauthentication.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Authentication Patterns

Login flows, session persistence, OAuth, and 2FA for cmux browser surfaces. Related: session-management.md, ../SKILL.md.

Set SURFACE from surface discovery or from the JSON returned by browser open. Never guess a default surface or log credentials.

Saved browser state contains cookies and storage. Use a private directory with restrictive permissions before saving it:

STATE_DIR="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/cmux-browser-state"
umask 077
mkdir -p "$STATE_DIR"
chmod 700 "$STATE_DIR"
STATE_FILE="$STATE_DIR/auth-state.json"

Basic login

OPEN_JSON="$(cmux --json browser open https://app.example.com/login --focus false)"
SURFACE="$(printf '%s' "$OPEN_JSON" | jq -r '.surface_ref // .surface_id // empty')"
[ -n "$SURFACE" ] || { printf '%s\n' 'browser open did not return a surface ref' >&2; exit 1; }
cmux browser --surface "$SURFACE" wait --load-state complete --timeout-ms 15000
cmux browser --surface "$SURFACE" snapshot --interactive
cmux browser --surface "$SURFACE" fill e1 "$APP_USERNAME"
cmux browser --surface "$SURFACE" fill e2 "$APP_PASSWORD"
cmux browser --surface "$SURFACE" click e3 --snapshot-after --json
cmux browser --surface "$SURFACE" wait --url-contains "/dashboard" --timeout-ms 20000

Saving authentication state

cmux browser --surface "$SURFACE" state save "$STATE_FILE"
chmod 600 "$STATE_FILE"

State includes cookies, localStorage, sessionStorage, and open tab metadata for that surface.

Restoring authentication

STATE_DIR="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/cmux-browser-state"
umask 077
mkdir -p "$STATE_DIR"
chmod 700 "$STATE_DIR"
STATE_FILE="$STATE_DIR/auth-state.json"
OPEN_JSON="$(cmux --json browser open https://app.example.com --focus false)"
SURFACE="$(printf '%s' "$OPEN_JSON" | jq -r '.surface_ref // .surface_id // empty')"
[ -n "$SURFACE" ] || { printf '%s\n' 'browser open did not return a surface ref' >&2; exit 1; }
cmux browser --surface "$SURFACE" state load "$STATE_FILE"
cmux browser --surface "$SURFACE" goto https://app.example.com/dashboard
cmux browser --surface "$SURFACE" snapshot --interactive

OAuth / SSO

Same shape as basic login, waiting on the provider host and then the return host, with generous timeouts:

OAUTH_STATE_DIR="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/cmux-browser-state"
umask 077
mkdir -p "$OAUTH_STATE_DIR"
chmod 700 "$OAUTH_STATE_DIR"
OAUTH_STATE_FILE="$OAUTH_STATE_DIR/oauth-state.json"
OPEN_JSON="$(cmux --json browser open https://app.example.com/auth/provider --focus false)"
SURFACE="$(printf '%s' "$OPEN_JSON" | jq -r '.surface_ref // .surface_id // empty')"
[ -n "$SURFACE" ] || { printf '%s\n' 'browser open did not return a surface ref' >&2; exit 1; }
cmux browser --surface "$SURFACE" wait --url-contains "login.example.com" --timeout-ms 30000
cmux browser --surface "$SURFACE" snapshot --interactive
# fill and click the provider's fields
cmux browser --surface "$SURFACE" wait --url-contains "app.example.com" --timeout-ms 45000
cmux browser --surface "$SURFACE" state save "$OAUTH_STATE_FILE"
chmod 600 "$OAUTH_STATE_FILE"

Two-factor

Drive the password step, let the user complete 2FA in the webview, then wait with a long timeout (--url-contains "/dashboard" --timeout-ms 120000) and save state.

Cookie-based auth

cmux browser --surface "$SURFACE" cookies set session_cookie "$SESSION_COOKIE"
cmux browser --surface "$SURFACE" goto https://app.example.com/dashboard

Token refresh

Load saved state, navigate, and re-login only when the URL bounced to /login:

#!/usr/bin/env bash
set -euo pipefail
STATE_DIR="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/cmux-browser-state"
umask 077
mkdir -p "$STATE_DIR"
chmod 700 "$STATE_DIR"
STATE_FILE="${STATE_FILE:-$STATE_DIR/auth-state.json}"
: "${SURFACE:?set SURFACE from browser open or surface discovery}"

[ -f "$STATE_FILE" ] && cmux browser --surface "$SURFACE" state load "$STATE_FILE"
cmux browser --surface "$SURFACE" goto https://app.example.com/dashboard

if cmux browser --surface "$SURFACE" get url | grep -q '/login'; then
  cmux browser --surface "$SURFACE" snapshot --interactive
  cmux browser --surface "$SURFACE" fill e1 "$APP_USERNAME"
  cmux browser --surface "$SURFACE" fill e2 "$APP_PASSWORD"
  cmux browser --surface "$SURFACE" click e3
  cmux browser --surface "$SURFACE" wait --url-contains "/dashboard" --timeout-ms 20000
  cmux browser --surface "$SURFACE" state save "$STATE_FILE"
  chmod 600 "$STATE_FILE"
fi

Security

Never commit state files; they contain auth tokens. Take credentials from environment variables. Clear state after sensitive tasks:

cmux browser --surface "$SURFACE" cookies clear --all
STATE_DIR="${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/cmux-browser-state"
STATE_FILE="${STATE_FILE:-$STATE_DIR/auth-state.json}"
OAUTH_STATE_FILE="${OAUTH_STATE_FILE:-$STATE_DIR/oauth-state.json}"
rm -f "$STATE_FILE"
rm -f "$OAUTH_STATE_FILE"

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides browser automation capabilities and correctly identifies the sensitivity of browser session data, providing best practices for securing it with restricted permissions and safe credential handling. It includes a mechanism for updates using an installer utility from the author's repository. The primary security consideration is the risk of indirect prompt injection inherent in processing content from arbitrary websites.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: MEDIUM · 1 issue

  • Runlayer6mo

    5/11 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at f97f1e9. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 weeks ago
  • CLI
  • browser-automation
  • cmux
  • web-scraping
  • form-automation
  • wkwebview
  • macos

README badge

README badge for manaflow-ai/cmux

Automates browser interactions within cmux webviews by opening pages, waiting for state changes, snapshotting the DOM, and performing actions like clicks and form fills using element references. Use this for tasks like form submission, data extraction, and navigation verification in cmux surfaces.

Generated from the current SKILL.md.

Does this skill work with WKWebView, or only Chrome?
It uses WKWebView. Some Chrome/CDP-only features like viewport emulation, network mocking, and trace recording are not supported, but core actions (click, fill, press, scroll, wait, snapshot) work.
How do I handle authentication and preserve login state across browser tasks?
Use the authenticated-session template or follow the authentication reference guide, which covers login flows, OAuth, 2FA patterns, and the save/load state workflow to persist credentials between surfaces.
What should I do if snapshot --interactive fails with a js_error?
Fall back to get url, get text body, or get html body to verify page state. If the issue persists, navigate to a simpler intermediate page and retry the task from there.
Can I run multiple browser tasks in parallel or do I need one surface per task?
Keep one surface per task unless you intentionally switch. Multi-surface isolation and state persistence patterns are covered in the session-management reference.
Does this work with the agent-browser skill or are they separate workflows?
This skill is specific to cmux webviews. It uses cmux CLI commands and surface references; the wait patterns are similar to agent-browser but the execution model is distinct to cmux.

Generated from the current SKILL.md. These answers refresh after source changes.