Skip to content

txchen/camoucli

Repository files navigation

Camou

Camou is a local-first CLI and background daemon for driving Camoufox through Playwright, without depending on the Camoufox Python SDK.

  • npm package: camou
  • installed command: camou
  • project/repo name: camoucli

Camou is built for agent-style browser workflows:

  • keep a browser session alive across separate CLI invocations
  • preserve login state with persistent profiles
  • operate named tabs in parallel without ref collisions
  • interact through stable @eN refs from text snapshots
  • install, switch, and diagnose Camoufox browser versions from the CLI

Camou takes strong inspiration from vercel-labs/agent-browser and BUNotesAI/agent-browser-session, but is built for the Camoufox + Playwright Firefox path and persistent local daemon workflows.

Why Camou

Feature Why it matters
Persistent profiles Login once and reuse the same authenticated browser state later
Named sessions Keep separate workspaces like work, shopping, or github isolated
Named tabs Run multiple agents against the same browser session without fighting over one active page
Snapshot refs Use @e1, @e2, ... from snapshot instead of brittle selectors when driving pages
Version manager Install and switch Camoufox builds without bundling the browser into the npm package
Doctor diagnostics Check launch compatibility, bundle health, and Linux shared-library issues quickly

Install

Requirements:

  • Node.js >=20
  • a supported Camoufox release for your OS

Global install (recommended):

npm install -g camou
camou install

One-off usage with npx:

npx camou install
npx camou open https://example.com

From this repo:

npm install
npm run build
npm run dev -- --help

Notes:

  • Browser download is explicit. Installing the npm package does not download Camoufox.
  • camou install runs a quick headless launch probe after download.
  • camou use <version> runs the same compatibility check when you switch versions.

Install The Skill

Camou also ships an agent skill that can be installed through the open skills ecosystem at skills.sh.

Install it from this repo:

npx skills add txchen/camoucli --skill camou

Useful variants:

# Preview available skills in the repo
npx skills add txchen/camoucli --list

# Install globally for a specific agent
npx skills add txchen/camoucli --skill camou -g -a opencode

The skill teaches agents the recommended Camou workflow: open -> snapshot -i -> interact with @refs -> re-snapshot, plus session/tab/version troubleshooting guidance.

Quick Start

camou install                  # Install the default browser build
camou open https://example.com # Open the target page
camou snapshot -i              # Capture interactive refs
# @e1 a "Learn more"
camou click @e1                # Click the chosen ref
camou get title                # Read the current page title

What happens behind the scenes:

  1. camou open auto-starts the local daemon if needed.
  2. Camoufox launches with a persistent profile for the default session.
  3. snapshot -i returns interactive elements with refs like @e1.
  4. Later commands reuse the same browser session and profile.

Important ref rule:

  • Re-run snapshot after navigation or major page changes. Refs are per tab and are invalidated on navigation or a new snapshot.

Project Defaults

If you use Camou inside a coding project, you do not need to repeat --session and --tabname on every command.

Camou resolves defaults in this order:

  1. explicit CLI flags
  2. environment variables
  3. nearest project config file in the current directory or any parent directory
  4. built-in defaults: session=default, tabname=main

Supported environment variables:

export CAMOU_SESSION=my-project
export CAMOU_TAB=main
export CAMOU_BROWSER=135.0.1-beta.24
export CAMOU_HEADLESS=true
export CAMOU_PRESET=cache,low-bandwidth

Also supported:

  • CAMOU_TABNAME
  • CAMOU_PRESETS
  • legacy aliases: CAMOUCLI_SESSION, CAMOUCLI_TAB, CAMOUCLI_TABNAME, CAMOUCLI_BROWSER, CAMOUCLI_HEADLESS, CAMOUCLI_PRESET, CAMOUCLI_PRESETS

Supported project config file names:

  • .camou.json
  • camou.json

Example .camou.json:

{
  "session": "my-project",
  "tabname": "main",
  "browser": "135.0.1-beta.24",
  "headless": true,
  "preset": ["cache", "low-bandwidth"]
}

Then you can run commands like:

camou open https://example.com # Open the target page
camou snapshot -i              # Capture interactive refs
camou click @e1                # Click the chosen ref

and they automatically use the configured session, tab, browser version, headless mode, and presets unless you override them with flags.

Use From Node Scripts

Camou can also be used as a Node library, not just a CLI.

The programmatic API is Playwright-based: it launches Camoufox for you and gives you a real Playwright BrowserContext, similar in spirit to the Camoufox Python wrapper.

import { Camoufox } from 'camou';

const camou = await Camoufox.launch({
  session: 'script',
  headless: false,
  fingerprint: {
    locales: ['en-US', 'fr-FR'],
    screenProfile: 'desktop-fhd',
    blockImages: true,
  },
});

const page = await camou.open('https://example.com');
console.log(await page.title());

await camou.close();

If you prefer a scoped helper:

import { Camoufox } from 'camou';

await Camoufox.with({ session: 'script' }, async (camou) => {
  const page = await camou.open('https://example.com');
  console.log(await page.title());
});

Useful exported helpers include:

  • Camoufox.launch()
  • Camoufox.launchContext()
  • Camoufox.with()
  • AsyncCamoufox
  • launchCamoufox()
  • launchCamoufoxContext()
  • resolveCamoufoxLaunchSpec()
  • withCamoufox()
  • installCamoufox()
  • listInstalledBrowsers()
  • setCurrentBrowser()
  • doctorCamoufox()

Notes:

  • install a browser first with camou install or installCamoufox()
  • use a dedicated session name in scripts if you do not want to share the default CLI profile
  • the returned context is a normal Playwright context, so you can use standard Playwright APIs from there

Recommended Agent Workflow

For agents and automation loops, this is the happy path:

camou open https://target.site # Open the target page
camou snapshot -i --json       # Capture JSON refs
camou click @e3                # Act on a chosen ref
camou fill @e5 "hello"       # Fill the next field
camou snapshot -i --json       # Refresh refs after changes

Why this works well:

  • snapshot gives a stable text representation of the page
  • refs are deterministic within the current tab snapshot
  • --json gives machine-readable success and error payloads
  • the daemon keeps browser state alive between commands

Core Concepts

Session

A session is a named browser workspace selected with --session <name>.

  • sessions have separate persistent profile directories
  • different sessions isolate cookies, storage, downloads, and artifacts
  • reuse the same session name to keep login state across runs

Example:

camou open https://github.com --session work          # Open the work session
camou open https://mail.google.com --session personal # Open a separate personal session

Tab

A tab is a named page binding inside a session selected with --tabname <name>.

  • tabs in the same session share browser profile state
  • tabs keep separate page bindings and separate ref maps
  • named tabs make concurrent agent workflows much safer

Example:

camou open https://reddit.com --session work --tabname reddit       # First named tab
camou open https://news.ycombinator.com --session work --tabname hn # Second named tab

Ref

A ref is a snapshot-generated handle like @e1 or @e2.

  • refs come from camou snapshot or camou snapshot -i
  • refs are only valid for the tab that created them
  • refs are cleared when the page navigates or you take a new snapshot

Browser version

Camou keeps an active Camoufox version, but you can also pick a version per command.

  • camou use <version> changes the active default version
  • camou <command> ... --browser <version> runs a command against a specific installed version without changing the default

Common Workflows

Persistent login session

camou open https://github.com/login --session work --tabname github   # Start a named session
# log in once in the browser
camou open https://github.com/settings/profile --session work --tabname github # Reuse saved login

Use the same --session name later and the login state is still there.

Multi-tab parallel-safe browsing

camou open https://reddit.com --session research --tabname reddit       # Shared session, first tab
camou open https://news.ycombinator.com --session research --tabname hn # Shared session, second tab

camou snapshot -i --session research --tabname reddit                   # Inspect the reddit tab
camou snapshot -i --session research --tabname hn                       # Inspect the hn tab

Both tabs share the same browser profile, but each tab has its own page and ref map.

Install and switch versions

camou remote-versions         # Show compatible remote versions
camou install 135.0.1-beta.24 # Install one version
camou install 135.0.1-beta.23 # Install another version
camou versions                # Show installed and active versions
camou use 135.0.1-beta.24     # Switch the default version
camou doctor --json           # Check compatibility in JSON

Use a specific browser version for one session

camou open https://example.com --session canary --browser 135.0.1-beta.24 # Pin one run

JSON output for automation

camou snapshot -i --json                        # JSON interactive snapshot
camou get title --json                          # JSON scalar output
camou eval 'document.title' --json              # JSON eval result
camou cookies export --json                     # JSON cookie export
camou doctor --json                             # JSON diagnostics
camou remote-versions --json | jq -r '.remoteVersions[].version' # Extract versions

Errors are also structured when --json is enabled.

Daemon lifecycle

camou daemon stop             # Stop the local daemon process
camou daemon restart          # Restart the daemon after upgrades or cleanup
camou daemon cleanup          # Stop sessions, stop daemon, kill stray Camoufox processes

Use camou daemon restart after upgrading the CLI if an older background daemon is still running. Use camou daemon cleanup when the daemon is gone but orphan Camoufox processes remain.

Command Reference

Browser management

camou install [version]    # Install the default or one specific build
camou remove [version]     # Remove an installed browser build
camou use <version>        # Switch the default browser version
camou versions             # List installed versions and the default
camou remote-versions      # List compatible remote versions
camou presets              # Show built-in launch presets
camou version              # Print the active camoucli version
camou path                 # Show the active browser executable path
camou doctor               # Diagnose install and launch issues

Page automation

camou open <url>                  # Open a URL in the current tab
camou back                        # Go back in the current tab history
camou forward                     # Go forward in the current tab history
camou reload                      # Reload the current page
camou eval <expression>           # Run JavaScript in the current tab
camou snapshot                    # Capture page state and refs
camou snapshot -i                 # Interactive elements only; recommended
camou click <selectorOrRef>       # Click a selector or @eN ref
camou hover <selectorOrRef>       # Hover a selector or @eN ref
camou fill <selectorOrRef> <text> # Set an input value directly
camou type <selectorOrRef> <text> # Type text with key events
camou check <selectorOrRef>       # Check a checkbox or radio input
camou uncheck <selectorOrRef>     # Uncheck a checkbox
camou select <selectorOrRef> <value> # Choose a select option
camou press <key>                 # Press a keyboard key in the page
camou scroll <direction> [amount] # Scroll up, down, left, or right
camou scrollintoview <selectorOrRef> # Scroll until visible
camou wait [selectorOrRef] [--text <text>] [--load <state>] # Wait for element, text, or load
camou screenshot [path]           # Save a screenshot of the current page
camou get url                     # Read the current page URL
camou get title                   # Read the current page title
camou get text <selectorOrRef>    # Read visible text from an element
camou get value <selectorOrRef>   # Read an element's form value

Sessions and tabs

Use session for live daemon state and profile for stored disk-backed browser data.

camou session list            # List running daemon sessions
camou profile list            # List stored profiles on disk
camou profile inspect <name>  # Show one profile's paths
camou profile remove <name>   # Delete a profile; stops it first if needed
camou cookies export [path]   # Export context cookies as JSON
camou cookies import <path>   # Import cookies into session context
camou close --all             # Stop all running sessions
camou daemon stop             # Stop the local daemon process
camou daemon restart          # Restart the local daemon process
camou daemon cleanup          # Stop sessions, stop daemon, kill stray Camoufox processes
camou session stop [name]     # Stop one session or the current session
camou tab list                # List tabs in the current session
camou tab new [url]           # Create a new tab, optionally opening a URL
camou tab close [nameOrIndex] # Close one tab by name or index

Common Flags

Most browser commands support:

  • --session <name>
  • --tabname <name>
  • --headless
  • --browser <version>
  • --config <path>
  • --config-json <json>
  • --prefs <path>
  • --prefs-json <json>
  • --fingerprint <path>
  • --fingerprint-json <json>
  • --preset <name>
  • --proxy <url>
  • --locale <locale>
  • --locales <locale[,locale...]>
  • --region <code>
  • --timezone <timezone>
  • --screen-profile <name>
  • --window-profile <name>
  • --block-images
  • --block-webrtc
  • --block-webgl
  • --disable-coop
  • --width <px>
  • --height <px>
  • --json
  • --verbose

wait also supports:

  • --text <text>
  • --load <domcontentloaded|load|networkidle>

Presets

Built-in presets give you a small layer of tested ergonomics on top of raw config and prefs JSON.

Preset What it does
default Baseline launch with no extra overrides
cache Enables the Firefox cache/session prefs used by the Python library
low-bandwidth Blocks images and speculative requests for lighter automation sessions
disable-coop Relaxes Cross-Origin-Opener-Policy isolation for troublesome embedded flows

List them:

camou presets

List built-in fingerprint profiles:

camou fingerprint-profiles

Apply one or more:

camou open https://example.com --preset cache --preset low-bandwidth

Fingerprint Helpers

Camou now includes a higher-level helper layer for common Camoufox identity settings without forcing you to handcraft raw config keys.

CLI shortcuts:

camou open https://example.com \
  --locales en-US,fr-FR \
  --region US \
  --screen-profile desktop-fhd \
  --window-profile desktop \
  --block-images

You can also pass a helper JSON object:

camou open https://example.com --fingerprint-json '{"screenProfile":"retina-mac","locales":["en-US","en"],"blockWebRtc":true}'

Node API example:

import { Camoufox } from 'camou';

const camou = await Camoufox.launch({
  fingerprint: {
    region: 'CA',
    locales: ['en-CA', 'fr-CA'],
    screenProfile: 'desktop-fhd',
    windowProfile: 'desktop',
    blockImages: true,
  },
});

Supported helper fields include:

  • locales to keep navigator.language, navigator.languages, and Accept-Language aligned
  • region to apply a curated locale, timezone, and geolocation bundle for a target country or territory
  • screenProfile / windowProfile for curated screen and window templates
  • screen / window in the Node API for direct helper objects
  • blockImages, blockWebRtc, blockWebGl, and disableCoop as Python-style toggle helpers
  • fonts and fontSpacingSeed in the Node API for higher-level font config

Current region helpers seed representative locale, timezone, and geolocation values for supported regions. Direct IP-based GeoIP lookup is not bundled yet.

Built-in screen profiles:

  • laptop-hd
  • desktop-fhd
  • desktop-qhd
  • retina-mac

Built-in window profiles:

  • laptop
  • desktop
  • desktop-large
  • retina

Doctor And Troubleshooting

camou doctor --json reports:

  • installed Camoufox versions
  • which version is active
  • whether each version can launch with the current playwright-core
  • bundle file checks
  • Linux shared-library diagnostics
  • remediation hints

Useful commands:

camou versions
camou use 135.0.1-beta.24
camou doctor --json

Common fixes:

  • Browser.setContrast is not supported
    • the selected Camoufox build is older than the bundled Playwright runtime
    • switch to a newer browser version with camou use <version>
  • profile/session locked
    • another browser process is using that session profile
    • stop the other browser or use a different --session
  • executable missing or damaged
    • reinstall with camou install --force
  • Linux launch failures
    • run camou doctor --json and install the missing shared libraries it reports

Current Compatibility

Current local verification with playwright-core 1.51.1:

Camoufox Status Notes
135.0.1-beta.24 launches smoke-tested successfully
135.0.1-beta.23 incompatible Browser.setContrast is not supported

The repo now also includes:

  • Linux/macOS CI in .github/workflows/ci.yml
  • a workflow-driven compatibility probe in .github/workflows/compatibility-matrix.yml
  • local scripts to generate compatibility reports and markdown summaries

See docs/compatibility-matrix.md for the workflow and local tooling.

Storage Layout

Camou keeps its own runtime state and profiles, but stores browser binaries in the shared Camoufox cache layout when possible.

  • session data lives under profiles/<session>/{user-data,downloads,artifacts}
  • daemon state and logs live under platform runtime/state directories
  • Camoufox binaries live in the shared cache used by the Python library:
    • Linux: ~/.cache/camoufox/browsers/official/<version>/
    • macOS: ~/Library/Caches/camoufox/browsers/official/<version>/
    • Windows: %LOCALAPPDATA%\camoufox\Cache\browsers\official\<version>\

This lets Camou reuse compatible Camoufox installs from the Python ecosystem and vice versa.

Development

npm install
npm run build
npm test

Optional targeted integration suite:

npm run test:integration

Local development commands:

npm run dev -- --help
npm run dev:daemon

Compatibility tooling:

# produce a raw compatibility report JSON
node scripts/run-compatibility-report.mjs --output compatibility-report.json

# turn one or more reports into a markdown table
node scripts/generate-compatibility-matrix.mjs compatibility-report.json

Acknowledgements

Camou learned a lot from these projects:

About

nodejs powered camoufox client

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors