AGENT SKILL

patchwright-cli

Anti-detection browser automation via Patchright. Use instead of playwright-cli when the target site has bot detection (Cloudflare, DataDome, etc.).

License 许可
Apache-2.0
最近更新
2026-09-09
Stars
★ 4
Forks
0

01 前言 Front Matter

name
patchwright-cli
description
Anti-detection browser automation via Patchright. Use instead of playwright-cli when the target site has bot detection (Cloudflare, DataDome, etc.).
allowed-tools
Bash(patchwright-cli:*) Bash(npx:*) Bash(npm:*)

02 资源文件 9

03 SKILL.md 正文

Browser Automation with patchwright-cli

Browser lifecycle — read this before anything else

patchwright-cli open does not just run a command. It spawns a detached background daemon that owns a full Chrome process tree (~200-650 MB), and that daemon outlives your shell, your task, and your session. It has no parent-process watchdog: nothing about your lifecycle reclaims it — not finishing the task, not closing the terminal, not the agent session ending. The one automatic backstop is an idle timeout (30 minutes by default, PATCHWRIGHT_IDLE_TIMEOUT), after which the browser closes itself. Treat that as damage control, not cleanup: half an hour × several forgotten sessions is still gigabytes, and a wedged daemon can outlive its own timer. (A daemon that dies is covered separately: each session runs a watchdog process that closes the abandoned browser within seconds. That protects against crashes, not against you forgetting.) Close explicitly.

Leaked daemons are the single most common failure mode of this tool. They accumulate silently at ~200 MB each until the machine starts swapping.

So, two rules:

Start every browser task by taking stock. This costs one command and, unlike a trailing close, it does not depend on your task finishing cleanly:

patchwright-cli list --all  # every daemon on the machine; anything unfamiliar is a leak
patchwright-cli close-all   # clean slate for THIS workspace

--all is not optional here. list and close-all are both scoped to the current workspace, and each git worktree counts as its own workspace — so a bare list run from one worktree reports "(no browsers)" while daemons leaked from another worktree are still holding hundreds of MB. Use list --all to see the truth, and pgrep -fl cli-daemon to cross-check. To sweep every workspace at once there is only kill-all, which SIGKILLs everything; it works, but it skips cleanup, leaving ~80 MB temp profiles behind in $TMPDIR/playwright_chromiumdev_profile-* for you to delete manually. Prefer per-workspace close-all where you can.

Reuse the default session. Do not invent a new -s=<name> per task — every distinct name is a separate daemon and a separate Chrome tree. Omit -s entirely unless you genuinely need two browsers alive at the same time.

Then close when done (patchwright-cli close). But treat that as best-effort: an exploratory task that changes direction, errors out, or gets interrupted will never reach it. The opening close-all is what actually bounds the damage.

When to use patchwright-cli vs playwright-cli

Both tools share the same CLI interface and commands. The difference is the underlying browser engine:

  • playwright-cli uses stock Playwright/Chromium — suitable for most automation and testing tasks.
  • patchwright-cli uses Patchright, a patched version of Playwright that bypasses common bot detection systems (Cloudflare Turnstile, DataDome, PerimeterX, etc.).

Use patchwright-cli when:

  • The target site blocks automated browsers or shows CAPTCHAs
  • You encounter "Access Denied", "Please verify you are human", or similar bot-detection pages
  • You need to interact with sites protected by WAF/anti-bot services

Use playwright-cli when:

  • The target site has no bot detection
  • You are running Playwright tests or test generation
  • You want the standard, unpatched browser behavior

If both skills are installed, prefer playwright-cli by default and switch to patchwright-cli only when bot detection is encountered.

Anti-detection best practices

When targeting sites with bot detection, always use --headed mode (and optionally --browser=chrome). The default headless mode exposes HeadlessChrome in the User-Agent and lacks real screen/window metrics, which most anti-bot systems trivially detect.

# Recommended for bot-protected sites
patchwright-cli open --headed https://protected-site.com
# ... do the work ...
patchwright-cli close

# Best stealth: headed + system Chrome (real UA, real screen metrics)
patchwright-cli open --headed --browser=chrome https://protected-site.com
# ... do the work ...
patchwright-cli close

Headless mode is fine for sites without bot detection or for quick scripting tasks. Note that --headed and --browser=chrome produce the heaviest daemons — a leaked headed Chrome costs several hundred MB, so the cleanup rules above matter most here.

Quick start

# open new browser (use --headed for bot-protected sites)
patchwright-cli open --headed
# navigate to a page
patchwright-cli goto https://playwright.dev
# interact with the page using refs from the snapshot
patchwright-cli click e15
patchwright-cli type "page.click"
patchwright-cli press Enter
# take a screenshot (rarely used, as snapshot is more common)
patchwright-cli screenshot
# close the browser
patchwright-cli close

Commands

Core

patchwright-cli open
# open and navigate right away
patchwright-cli open https://example.com/
patchwright-cli goto https://playwright.dev
patchwright-cli type "search query"
patchwright-cli click e3
patchwright-cli dblclick e7
# --submit presses Enter after filling the element
patchwright-cli fill e5 "user@example.com"  --submit
patchwright-cli drag e2 e8
patchwright-cli hover e4
patchwright-cli select e9 "option-value"
patchwright-cli upload ./document.pdf
patchwright-cli check e12
patchwright-cli uncheck e12
patchwright-cli snapshot
patchwright-cli eval "document.title"
patchwright-cli eval "el => el.textContent" e5
# get element id, class, or any attribute not visible in the snapshot
patchwright-cli eval "el => el.id" e5
patchwright-cli eval "el => el.getAttribute('data-testid')" e5
patchwright-cli dialog-accept
patchwright-cli dialog-accept "confirmation text"
patchwright-cli dialog-dismiss
patchwright-cli resize 1920 1080
patchwright-cli close

Navigation

patchwright-cli go-back
patchwright-cli go-forward
patchwright-cli reload

Keyboard

patchwright-cli press Enter
patchwright-cli press ArrowDown
patchwright-cli keydown Shift
patchwright-cli keyup Shift

Mouse

patchwright-cli mousemove 150 300
patchwright-cli mousedown
patchwright-cli mousedown right
patchwright-cli mouseup
patchwright-cli mouseup right
patchwright-cli mousewheel 0 100

Save as

patchwright-cli screenshot
patchwright-cli screenshot e5
patchwright-cli screenshot --filename=page.png
patchwright-cli pdf --filename=page.pdf

Tabs

patchwright-cli tab-list
patchwright-cli tab-new
patchwright-cli tab-new https://example.com/page
patchwright-cli tab-close
patchwright-cli tab-close 2
patchwright-cli tab-select 0

Storage

patchwright-cli state-save
patchwright-cli state-save auth.json
patchwright-cli state-load auth.json

# Cookies
patchwright-cli cookie-list
patchwright-cli cookie-list --domain=example.com
patchwright-cli cookie-get session_id
patchwright-cli cookie-set session_id abc123
patchwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
patchwright-cli cookie-delete session_id
patchwright-cli cookie-clear

# LocalStorage
patchwright-cli localstorage-list
patchwright-cli localstorage-get theme
patchwright-cli localstorage-set theme dark
patchwright-cli localstorage-delete theme
patchwright-cli localstorage-clear

# SessionStorage
patchwright-cli sessionstorage-list
patchwright-cli sessionstorage-get step
patchwright-cli sessionstorage-set step 3
patchwright-cli sessionstorage-delete step
patchwright-cli sessionstorage-clear

Network

patchwright-cli route "**/*.jpg" --status=404
patchwright-cli route "https://api.example.com/**" --body='{"mock": true}'
patchwright-cli route-list
patchwright-cli unroute "**/*.jpg"
patchwright-cli unroute

DevTools

patchwright-cli console
patchwright-cli console warning
patchwright-cli network
patchwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])"
patchwright-cli run-code --filename=script.js
patchwright-cli tracing-start
patchwright-cli tracing-stop
patchwright-cli video-start video.webm
patchwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000
patchwright-cli video-stop

Open parameters

# Use headed mode (recommended for bot-protected sites)
patchwright-cli open --headed
patchwright-cli open --headed --browser=chrome

# Use specific browser when creating session
patchwright-cli open --browser=chrome
patchwright-cli open --browser=firefox
patchwright-cli open --browser=webkit
patchwright-cli open --browser=msedge
# Connect to browser via extension
patchwright-cli open --extension

# Use persistent profile (by default profile is in-memory)
patchwright-cli open --persistent
# Use persistent profile with custom directory
patchwright-cli open --profile=/path/to/profile

# Start with config file
patchwright-cli open --config=my-config.json

# Close the browser
patchwright-cli close
# Delete user data for the default session
patchwright-cli delete-data

Snapshots

After each command, patchwright-cli provides a snapshot of the current browser state.

> patchwright-cli goto https://example.com
### Page
- Page URL: https://example.com/
- Page Title: Example Domain
### Snapshot
[Snapshot](.patchwright-cli/page-2026-02-14T19-22-42-679Z.yml)

You can also take a snapshot on demand using patchwright-cli snapshot command. All the options below can be combined as needed.

# default - save to a file with timestamp-based name
patchwright-cli snapshot

# save to file, use when snapshot is a part of the workflow result
patchwright-cli snapshot --filename=after-click.yaml

# snapshot an element instead of the whole page
patchwright-cli snapshot "#main"

# limit snapshot depth for efficiency, take a partial snapshot afterwards
patchwright-cli snapshot --depth=4
patchwright-cli snapshot e34

Targeting elements

By default, use refs from the snapshot to interact with page elements.

# get snapshot with refs
patchwright-cli snapshot

# interact using a ref
patchwright-cli click e15

You can also use css selectors or Playwright locators.

# css selector
patchwright-cli click "#main > button.submit"

# role locator
patchwright-cli click "getByRole('button', { name: 'Submit' })"

# test id
patchwright-cli click "getByTestId('submit-button')"

Browser Sessions

-s=<name> exists for concurrency — running two browsers at the same time with separate cookies and storage. It is not a label for what a task is about. Each name is a separate daemon that must be closed separately, so if you do not need two browsers alive simultaneously, omit -s and use the default session.

# create new browser session named "mysession" with persistent profile
patchwright-cli -s=mysession open example.com --persistent
# same with manually specified profile directory (use when requested explicitly)
patchwright-cli -s=mysession open example.com --profile=/path/to/profile
patchwright-cli -s=mysession click e6
patchwright-cli -s=mysession close  # stop a named browser — required, nothing does it for you
patchwright-cli -s=mysession delete-data  # delete user data for persistent session

Cleanup commands. Mind the scope column — list and close-all only see the current workspace, and every git worktree is a separate workspace:

patchwright-cli list        # THIS workspace only — usually misleading
patchwright-cli list --all  # every workspace on the machine — use this one
patchwright-cli close-all   # THIS workspace; graceful, cleans up temp profiles
patchwright-cli kill-all    # ALL workspaces; SIGKILL, leaves temp profiles behind

Installation

If global patchwright-cli command is not available, try a local version via npx patchwright-cli:

npx --no-install patchwright-cli --version

When local version is available, use npx patchwright-cli in all commands. Otherwise, install patchwright-cli as a global command:

npm install -g patchwright-cli@latest

Example: Form submission

patchwright-cli open https://example.com/form
patchwright-cli snapshot

patchwright-cli fill e1 "user@example.com"
patchwright-cli fill e2 "password123"
patchwright-cli click e3
patchwright-cli snapshot
patchwright-cli close

Example: Multi-tab workflow

patchwright-cli open https://example.com
patchwright-cli tab-new https://example.com/other
patchwright-cli tab-list
patchwright-cli tab-select 0
patchwright-cli snapshot
patchwright-cli close

Example: Debugging with DevTools

patchwright-cli open https://example.com
patchwright-cli click e4
patchwright-cli fill e7 "test"
patchwright-cli console
patchwright-cli network
patchwright-cli close
patchwright-cli open https://example.com
patchwright-cli tracing-start
patchwright-cli click e4
patchwright-cli fill e7 "test"
patchwright-cli tracing-stop
patchwright-cli close

Specific tasks

04 同仓库更多 Skills