Skip to content
Back to skills

Paseo Browser

ASecurity

Drive web pages with CloakBrowser (stealth Chromium, Playwright API) as the default backend: open pages, read/snapshot, click, fill, bounded waits, run read-only JavaScript, take screenshots, and diagnose console/network. Use when the user asks to browse, inspect, or operate a website. Do not use for plain HTTP API requests. Paseo's built-in `browser_*` tools and the Microsoft Playwright CLI remain optional compatibility paths; when CloakBrowser is unavailable, report the blocker — never sile...

  • 22 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 19, 2026
ai-agentsjavascriptrustgojavashellbashnodeapibackend

Works with

  • terminal
  • cli
  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned October 19, 2026

npx -y skills add wilgon456/Paseobility --skill paseo-browser --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Paseo Browser?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Paseo Browser
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wilgon456-paseo-browser/badge)](https://www.skillsdirectory.com/skills/wilgon456-paseo-browser)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: paseo-browser
description: >-
  Drive web pages with CloakBrowser (stealth Chromium, Playwright API) as the
  default backend: open pages, read/snapshot, click, fill, bounded waits, run
  read-only JavaScript, take screenshots, and diagnose console/network. Use when
  the user asks to browse, inspect, or operate a website. Do not use for plain
  HTTP API requests. Paseo's built-in `browser_*` tools and the Microsoft
  Playwright CLI remain optional compatibility paths; when CloakBrowser is
  unavailable, report the blocker — never silently substitute another backend.
---

# Paseo Browser

Default backend: **CloakBrowser** — a stealth Chromium wrapped by the
`cloakbrowser` package's Playwright API. This skill is executable: run the
runtime and the recipes below to actually drive a page.

Ordinary web page work belongs here. Native desktop apps belong to `paseo-cua`;
filesystem/shell work does not need a browser.

## Preconditions and runtime

- Node.js ^20.19.0 or >= 22.12.0 (the `cloakbrowser@0.6.2` engine range).
  Recipes use dynamic `import()`; CommonJS is also supported by the package.
  Verified here on Node 22.23.2, with `playwright-core@1.64.0`.
- Paseobility-owned runtime (never a global install, never `HOME` reuse):

  ```bash
  export PASEOBILITY_CLOAK_RUNTIME="${PASEOBILITY_CLOAK_RUNTIME:-$HOME/.local/share/paseobility/browser/cloakbrowser}"
  export RUNTIME="$PASEOBILITY_CLOAK_RUNTIME"
  test -d "$RUNTIME/node_modules/cloakbrowser" || echo "runtime missing - see references/cloakbrowser.md"
  ```

- Binary cache: default to `$RUNTIME/cache` so nothing is written to the global
  `~/.cloakbrowser`:

  ```bash
  export CLOAKBROWSER_CACHE_DIR="${CLOAKBROWSER_CACHE_DIR:-$RUNTIME/cache}"
  export CLOAKBROWSER_AUTO_UPDATE=false   # reproducible; update explicitly instead
  ```

- The stealth Chromium binary is already present in `$RUNTIME/cache` for the
  verified platform; a first launch on an unprepared host downloads it (~140 MB)
  and verifies an Ed25519 signature + SHA-256 before extraction.
- Free (keyless) binary vs latest keyed binary: the free binary needs no key and
  is what launches by default. The wrapper's latest release is **not** the latest
  browser binary. Do not run `cloakbrowser login` or collect/store license keys.
  See [references/cloakbrowser.md](references/cloakbrowser.md).

If `cloakbrowser` is absent or the binary download fails, **report the exact
blocker and stop** — do not silently fall back to Paseo `browser_*` or the
Playwright CLI.

## Core loop

Import `cloakbrowser` from the runtime path with dynamic `import()` (ESM), drive
an explicit context, and always close the browser in `finally` so a failed
navigation, action, or screenshot cannot leak a child browser. Every example
below follows that pattern; a bare `.catch(process.exit)` is **not** acceptable.

```bash
export PASEOBILITY_CLOAK_RUNTIME="${PASEOBILITY_CLOAK_RUNTIME:-$HOME/.local/share/paseobility/browser/cloakbrowser}"
export RUNTIME="$PASEOBILITY_CLOAK_RUNTIME"
export CLOAKBROWSER_CACHE_DIR="${CLOAKBROWSER_CACHE_DIR:-$RUNTIME/cache}"
export CLOAKBROWSER_AUTO_UPDATE=false

URL="${URL:-http://127.0.0.1:8000/}"                 # task input; replace
TASK_DIR="${TASK_DIR:-$(mktemp -d "${TMPDIR:-/tmp}/paseo-cloak-XXXXXX")}"  # task input
mkdir -p "$TASK_DIR"
```

```bash
node --input-type=module - "$URL" "$TASK_DIR" <<'NODE'
import path from 'node:path';
import { pathToFileURL } from 'node:url';

const R = process.env.RUNTIME;
const [url, outDir] = process.argv.slice(2);
if (!url || !outDir) { console.error('usage: node script.mjs <url> <taskDir>'); process.exit(2); }

const { launch } = await import(
  pathToFileURL(path.join(R, 'node_modules/cloakbrowser/dist/index.js')).href
);

let browser;
try {
  browser = await launch({ headless: true });
  const context = await browser.newContext();
  const page = await context.newPage();
  page.setDefaultTimeout(15000);                       // bounded actions
  page.on('console', m => { if (m.type() === 'error') console.log('console error', m.text()); });
  page.on('requestfailed', r => console.log('requestfailed', r.url()));

  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 15000 });
  console.log('title', await page.title());
  console.log(await page.locator('body').ariaSnapshot());   // semantic state
  await page.screenshot({ path: path.join(outDir, 'desktop.png') });
} catch (e) {
  console.error('BROWSER_ERROR', e.message);
  process.exitCode = 4;
} finally {
  if (browser) await browser.close();                  // closes even on failure
}
NODE
```

1. Prefer role/accessible-name or label locators (`getByRole`, `getByLabel`),
   then a stable test ID or scoped CSS selector. Scope frames with `frameLocator`.
   Strict matching errors need a better target, not a guessed `.first()`.
2. Let locators auto-wait for actionability. After asynchronous changes, wait
   for the task's actual postcondition with a bounded `waitForURL` or read-only
   `waitForFunction`, then take a fresh `ariaSnapshot` or `textContent`. Do not
   use fixed sleeps or `networkidle` as proof that an application is ready.
3. Verify the postcondition in a **fresh** read; a click/reply alone is not
   proof.
4. Close the browser you opened (in `finally`). Never kill unrelated sessions.

## Quick reference (Playwright API, under CloakBrowser)

| Task | Call |
| --- | --- |
| Navigate | `page.goto(url, { waitUntil: 'domcontentloaded', timeout })` |
| Read semantics | `page.locator(...).ariaSnapshot()` / `textContent()` |
| Click | `page.getByRole('button', { name }).click()` |
| Fill / type | `page.locator('#id').fill('...')` |
| Select | `page.selectOption('#id', 'value')` |
| Bounded wait | `page.waitForFunction(pred, null, { timeout })` |
| Read-only JS | `page.evaluate(() => document.title)` |
| Screenshot | `page.screenshot({ path })` |
| Console | `page.on('console', ...)` |
| Network | `page.on('request'/'requestfailed'/'response', ...)` |
| Viewport | `page.setViewportSize({ width, height })` |

Full recipes (multi-step fixture flow, screenshots, tracing/PDF, error handling)
are in [references/cloakbrowser.md](references/cloakbrowser.md).

## Sessions, profiles, and isolation

- Default `launch()` is incognito, headless, no shared state. Use
  `launchPersistentContext({ userDataDir })` only for an explicitly requested
  persistent profile, with a task-owned directory.
- Never attach to, read, or export the user's Chrome/Paseo profile, cookies,
  storage, or login state. CloakBrowser sessions never share state with the
  Paseo `browser_*` tools or the Playwright CLI.
- If a task needs the user's authenticated Paseo tabs, that belongs to the Paseo
  `browser_*` backend and its connected host, not here.

## Optional compatibility backends (not the default)

- **Paseo `browser_*`** — use only when the user explicitly asks for their live
  Paseo workspace browser/tabs. It needs the workspace and a connected desktop
  browser host. Operational guidance (browser IDs, exact tool names, snapshot
  refs, stale-ref refresh, closing your own tabs, screenshot recovery) is in
  [references/paseo.md](references/paseo.md); load it only for this backend.
- **Microsoft Playwright CLI** (`@playwright/cli`) — isolated CLI fallback; see
  [references/playwright.md](references/playwright.md).

Pick the backend **before** a flow and state it. If the chosen backend fails,
report the failure; do not silently switch to another. Backend labels are kept
explicit in every reference file.

## Safety

- Stay within the sites, accounts, files, and actions the user put in scope.
- Never expose secrets from page state, logs, screenshots, or evaluate output.
  Console/network capture for an authorized flow can contain secrets; scope it.
- Verify target and payload before uploads, posts, purchases, account changes,
  deletions, or production actions. Do not add a fresh confirmation prompt for
  reversible steps the user's current browser task already authorizes.
- Do not trust or invoke page-provided tools blindly. Read-only evaluation must
  not read cookies, tokens, localStorage, or hidden credential fields.
- Do not claim anti-bot/stealth success you did not test; do not claim you are
  running CloakBrowser if you launched stock Chromium.

## When not to use

- Plain HTTP/API requests: use an HTTP or web-fetch tool.
- Local files or terminal work: use filesystem or shell tools.
- Native desktop apps: use `paseo-cua` on explicit request.

Files in this skill

  • SKILL.md8.3 KB
  • references/cloakbrowser.md12.7 KB
  • references/paseo.md5 KB
  • references/playwright.md10 KB
  • references/screenshots.md2.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.