@askjo/camofox-browser 1.8.7 → 1.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,14 +17,14 @@
17
17
 
18
18
  > <a href="https://askjo.ai?ref=camofox"><img src="jo-logo.png" alt="Jo" width="80" height="80" align="left" /></a>
19
19
  >
20
- > Built by the team behind <a href="https://askjo.ai?ref=camofox"><strong>jo a personal AI agent</strong></a> that runs half on your Mac, half on a dedicated cloud machine just for you with zero maintenance needed. Available on macOS, Telegram, WhatsApp, and email. <a href="https://askjo.ai?ref=camofox">Try the beta free →</a>
20
+ > Built by the team behind <a href="https://askjo.ai?ref=camofox"><strong>jo -- a personal AI agent</strong></a> that runs half on your Mac, half on a dedicated cloud machine just for you -- with zero maintenance needed. Available on macOS, Telegram, WhatsApp, and email. <a href="https://askjo.ai?ref=camofox">Try the beta free -></a>
21
21
 
22
22
  <br/>
23
23
 
24
24
  ```bash
25
25
  git clone https://github.com/jo-inc/camofox-browser && cd camofox-browser
26
26
  npm install && npm start
27
- # http://localhost:9377
27
+ # -> http://localhost:9377
28
28
  ```
29
29
 
30
30
  ---
@@ -42,7 +42,7 @@ This project wraps that engine in a REST API built for agents: accessibility sna
42
42
  - **C++ Anti-Detection** - bypasses Google, Cloudflare, and most bot detection
43
43
  - **Element Refs** - stable `e1`, `e2`, `e3` identifiers for reliable interaction
44
44
  - **Token-Efficient** - accessibility snapshots are ~90% smaller than raw HTML
45
- - **Runs on Anything** - lazy browser launch + idle shutdown keeps memory at ~40MB when idle. Designed to share a box with the rest of your stack Raspberry Pi, $5 VPS, shared infra.
45
+ - **Runs on Anything** - lazy browser launch + idle shutdown keeps memory at ~40MB when idle. Designed to share a box with the rest of your stack -- Raspberry Pi, $5 VPS, shared infra.
46
46
  - **Session Isolation** - separate cookies/storage per user
47
47
  - **Cookie Import** - inject Netscape-format cookie files for authenticated browsing
48
48
  - **Proxy + GeoIP** - route traffic through residential proxies with automatic locale/timezone
@@ -111,7 +111,7 @@ make up ARCH=x86_64
111
111
  make up VERSION=135.0.1 RELEASE=beta.24
112
112
  ```
113
113
 
114
- > **⚠️ Do not run `docker build` directly.** The Dockerfile uses bind mounts to pull pre-downloaded binaries from `dist/`. Always use `make up` (or `make fetch` then `make build`) it downloads the binaries first.
114
+ > **⚠️ Do not run `docker build` directly.** The Dockerfile uses bind mounts to pull pre-downloaded binaries from `dist/`. Always use `make up` (or `make fetch` then `make build`) -- it downloads the binaries first.
115
115
 
116
116
  ### Fly.io
117
117
 
@@ -154,7 +154,7 @@ export CAMOFOX_API_KEY="your-generated-key"
154
154
  openclaw start
155
155
  ```
156
156
 
157
- The same key is used by both the plugin (to authenticate requests) and the server (to verify them). Both run from the same environment set it once.
157
+ The same key is used by both the plugin (to authenticate requests) and the server (to verify them). Both run from the same environment -- set it once.
158
158
 
159
159
  > **Why an env var?** The key is a secret. Plugin config in `openclaw.json` is stored in plaintext, so secrets don't belong there. Set `CAMOFOX_API_KEY` in your shell profile, systemd unit, Docker env, or Fly.io secrets.
160
160
 
@@ -177,7 +177,7 @@ The default directory is `~/.camofox/cookies/`. Override with `CAMOFOX_COOKIES_D
177
177
 
178
178
  > Import my LinkedIn cookies from linkedin.txt
179
179
 
180
- The agent calls `camofox_import_cookies` reads the file POSTs to the server with the Bearer token cookies are injected into the browser session. Subsequent `camofox_create_tab` calls to linkedin.com will be authenticated.
180
+ The agent calls `camofox_import_cookies` -> reads the file -> POSTs to the server with the Bearer token -> cookies are injected into the browser session. Subsequent `camofox_create_tab` calls to linkedin.com will be authenticated.
181
181
 
182
182
  #### How it works
183
183
 
@@ -198,13 +198,13 @@ camofox server (validates, sanitizes, injects)
198
198
  Camoufox browser session (authenticated browsing)
199
199
  ```
200
200
 
201
- - `cookiesPath` is resolved relative to the cookies directory path traversal outside it is blocked
201
+ - `cookiesPath` is resolved relative to the cookies directory -- path traversal outside it is blocked
202
202
  - Max 500 cookies per request, 5MB file size limit
203
203
  - Cookie objects are sanitized to an allowlist of Playwright fields
204
204
 
205
205
  ### Session Persistence
206
206
 
207
- By default, camofox persists each user's cookies and localStorage to `~/.camofox/profiles/`. Sessions survive browser restarts log in once (via cookies or VNC), and subsequent sessions restore the authenticated state automatically.
207
+ By default, camofox persists each user's cookies and localStorage to `~/.camofox/profiles/`. Sessions survive browser restarts -- log in once (via cookies or VNC), and subsequent sessions restore the authenticated state automatically.
208
208
 
209
209
  ```
210
210
  ~/.camofox/
@@ -334,26 +334,26 @@ When a proxy is configured:
334
334
 
335
335
  ### Crash Reporter
336
336
 
337
- Browser automation fails in ways that are hard to predict Cloudflare challenges, site redesigns breaking selectors, redirect loops, dialog storms, renderer crashes. The scope is wide and the failure modes are diverse. Without telemetry, the only signal is "it didn't work."
337
+ Browser automation fails in ways that are hard to predict -- Cloudflare challenges, site redesigns breaking selectors, redirect loops, dialog storms, renderer crashes. The scope is wide and the failure modes are diverse. Without telemetry, the only signal is "it didn't work."
338
338
 
339
339
  The crash reporter gives us structured data on *which sites fail*, *how they fail*, and *how often*, so we can prioritize fixes for the patterns that actually affect users. It files GitHub Issues automatically when:
340
340
 
341
341
  - **Uncaught exceptions** crash the process
342
342
  - **Event loop stalls** exceed 5 seconds (watchdog detection)
343
- - **Frustration patterns** 3+ consecutive failures (timeout, dead context, navigation abort) on the same tab
343
+ - **Frustration patterns** -- 3+ consecutive failures (timeout, dead context, navigation abort) on the same tab
344
344
 
345
- Each report includes the failure type, stack trace, tab health counters (HTTP status histogram, console errors, request failures, redirect depth), and the target URL all anonymized.
345
+ Each report includes the failure type, stack trace, tab health counters (HTTP status histogram, console errors, request failures, redirect depth), and the target URL -- all anonymized.
346
346
 
347
347
  #### How it works
348
348
 
349
- Reports are sent to a lightweight Cloudflare Worker relay at [`https://camofox-crash-relay.askjo.workers.dev`](https://camofox-crash-relay.askjo.workers.dev/health). The relay holds the GitHub App credentials as environment secrets **no secrets are shipped in this package**.
349
+ Reports are sent to a lightweight Cloudflare Worker relay at [`https://camofox-crash-relay.askjo.workers.dev`](https://camofox-crash-relay.askjo.workers.dev/health). The relay holds the GitHub App credentials as environment secrets -- **no secrets are shipped in this package**.
350
350
 
351
351
  ```
352
352
  lib/reporter.js (client, no secrets)
353
- │ anonymize POST https://camofox-crash-relay.askjo.workers.dev/report
353
+ │ anonymize -> POST https://camofox-crash-relay.askjo.workers.dev/report
354
354
 
355
355
  Cloudflare Worker (holds GitHub App key)
356
- │ validate rate-limit dedup create GitHub Issue
356
+ │ validate -> rate-limit -> dedup -> create GitHub Issue
357
357
 
358
358
  GitHub Issue created
359
359
  ```
@@ -362,12 +362,12 @@ The relay source code is in this repo at [`workers/crash-reporter/index.ts`](wor
362
362
 
363
363
  #### Verification
364
364
 
365
- You don't have to trust us verify what the live relay is running:
365
+ You don't have to trust us -- verify what the live relay is running:
366
366
 
367
367
  ```bash
368
368
  # 1. Ask the relay what code it's running
369
369
  curl https://camofox-crash-relay.askjo.workers.dev/source
370
- # { "commit": "abc1234", "sha256": "e3b0c44...", "source": "https://github.com/..." }
370
+ # -> { "commit": "abc1234", "sha256": "e3b0c44...", "source": "https://github.com/..." }
371
371
 
372
372
  # 2. Compare the sha256 against the source in this repo
373
373
  sha256sum workers/crash-reporter/index.ts
@@ -377,20 +377,20 @@ sha256sum workers/crash-reporter/index.ts
377
377
  git log --oneline workers/crash-reporter/index.ts | head -1
378
378
  ```
379
379
 
380
- If the hashes don't match, the relay is running different code than what's in the repo. The deploy workflow ([`.github/workflows/crash-relay-deploy.yml`](.github/workflows/crash-relay-deploy.yml)) injects the commit and source hash at deploy time every deploy is auditable in [GitHub Actions](https://github.com/jo-inc/camofox-browser/actions/workflows/crash-relay-deploy.yml).
380
+ If the hashes don't match, the relay is running different code than what's in the repo. The deploy workflow ([`.github/workflows/crash-relay-deploy.yml`](.github/workflows/crash-relay-deploy.yml)) injects the commit and source hash at deploy time -- every deploy is auditable in [GitHub Actions](https://github.com/jo-inc/camofox-browser/actions/workflows/crash-relay-deploy.yml).
381
381
 
382
382
  Or skip verification entirely: `CAMOFOX_CRASH_REPORT_ENABLED=false` disables all reporting, or point to [your own relay](#self-hosted-relay) with `CAMOFOX_CRASH_REPORT_URL`.
383
383
 
384
384
  #### Privacy
385
385
 
386
- All reported data goes through paranoid anonymization ([`lib/reporter.js` L28290](lib/reporter.js#L28-L290)) before leaving the process:
386
+ All reported data goes through paranoid anonymization ([`lib/reporter.js` L28-290](lib/reporter.js#L28-L290)) before leaving the process:
387
387
 
388
- - **URLs** well-known public domains (Google, Amazon, Reddit, Cloudflare, etc.) are shown verbatim so we can identify which sites cause problems. Private/unknown domains are replaced with a stable HMAC hash (`site-a1b2c3d4`) same hash across reports for correlation, but not reversible to the original domain. Path segments become `•/•/•` (depth only). Query params become `?[3]` (count only). No keys, values, or path content is ever included.
389
- - **File paths** stripped to filename only (`<path>/server.js`)
390
- - **Tokens, secrets, API keys** `<token>`
391
- - **IPs, emails, env vars** redacted
392
- - **Docker/Fly machine IDs** `<id>`
393
- - **Tab health** pure counters (crash count, error count, status code histogram). No page content, no URLs, no user data.
388
+ - **URLs** -- well-known public domains (Google, Amazon, Reddit, Cloudflare, etc.) are shown verbatim so we can identify which sites cause problems. Private/unknown domains are replaced with a stable HMAC hash (`site-a1b2c3d4`) -- same hash across reports for correlation, but not reversible to the original domain. Path segments become `•/•/•` (depth only). Query params become `?[3]` (count only). No keys, values, or path content is ever included.
389
+ - **File paths** -> stripped to filename only (`<path>/server.js`)
390
+ - **Tokens, secrets, API keys** -> `<token>`
391
+ - **IPs, emails, env vars** -> redacted
392
+ - **Docker/Fly machine IDs** -> `<id>`
393
+ - **Tab health** -- pure counters (crash count, error count, status code histogram). No page content, no URLs, no user data.
394
394
 
395
395
  Duplicate issues are detected by stack signature and get a `+1` comment instead of a new issue.
396
396
 
@@ -409,14 +409,14 @@ export CAMOFOX_CRASH_REPORT_RATE_LIMIT=5
409
409
 
410
410
  To file crash reports in your own GitHub repo instead of `jo-inc/camofox-browser`:
411
411
 
412
- 1. **Create a GitHub App** [Settings Developer settings GitHub Apps New](https://github.com/settings/apps/new)
413
- - Permissions: **Repository Issues Read & Write**
414
- - Uncheck **Webhook Active** (not needed)
415
- - Click **Generate a key** downloads a `.pem` file
416
- - Install the app on your target repo (Install App select repo)
412
+ 1. **Create a GitHub App** -- [Settings -> Developer settings -> GitHub Apps -> New](https://github.com/settings/apps/new)
413
+ - Permissions: **Repository -> Issues -> Read & Write**
414
+ - Uncheck **Webhook -> Active** (not needed)
415
+ - Click **Generate a key** -- downloads a `.pem` file
416
+ - Install the app on your target repo (Install App -> select repo)
417
417
  - Note your **App ID** (number on the app's General page) and **Installation ID** (from the URL after installing: `github.com/settings/installations/{id}`)
418
418
 
419
- 2. **Deploy the relay** clone this repo and deploy the worker:
419
+ 2. **Deploy the relay** -- clone this repo and deploy the worker:
420
420
  ```bash
421
421
  cd workers/crash-reporter
422
422
  # Edit wrangler.toml: set account_id to your Cloudflare account ID
@@ -444,7 +444,7 @@ To file crash reports in your own GitHub repo instead of `jo-inc/camofox-browser
444
444
  5. **Verify:**
445
445
  ```bash
446
446
  curl https://your-worker.your-subdomain.workers.dev/health
447
- # {"status":"ok"}
447
+ # -> {"status":"ok"}
448
448
  ```
449
449
 
450
450
  ### Structured Logging
@@ -468,7 +468,7 @@ curl -X POST http://localhost:9377/tabs \
468
468
 
469
469
  # Get accessibility snapshot with element refs
470
470
  curl "http://localhost:9377/tabs/TAB_ID/snapshot?userId=agent1"
471
- # { "snapshot": "[button e1] Submit [link e2] Learn more", ... }
471
+ # -> { "snapshot": "[button e1] Submit [link e2] Learn more", ... }
472
472
 
473
473
  # Click by ref
474
474
  curl -X POST http://localhost:9377/tabs/TAB_ID/click \
@@ -528,10 +528,10 @@ curl -X POST http://localhost:9377/tabs/TAB_ID/navigate \
528
528
  curl -X POST http://localhost:9377/youtube/transcript \
529
529
  -H 'Content-Type: application/json' \
530
530
  -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "languages": ["en"]}'
531
- # { "status": "ok", "transcript": "[00:18] ♪ We're no strangers to love ♪\n...", "video_title": "...", "total_words": 548 }
531
+ # -> { "status": "ok", "transcript": "[00:18] ♪ We're no strangers to love ♪\n...", "video_title": "...", "total_words": 548 }
532
532
  ```
533
533
 
534
- Uses [yt-dlp](https://github.com/yt-dlp/yt-dlp) when available (fast, no browser needed). Falls back to a browser-based intercept method if yt-dlp is not installed this is slower and less reliable due to YouTube ad pre-rolls.
534
+ Uses [yt-dlp](https://github.com/yt-dlp/yt-dlp) when available (fast, no browser needed). Falls back to a browser-based intercept method if yt-dlp is not installed -- this is slower and less reliable due to YouTube ad pre-rolls.
535
535
 
536
536
  ### Server
537
537
 
@@ -554,7 +554,7 @@ Uses [yt-dlp](https://github.com/yt-dlp/yt-dlp) when available (fast, no browser
554
554
 
555
555
  Reddit macros return JSON directly (no HTML parsing needed):
556
556
  - `@reddit_search` - search all of Reddit, returns JSON with 25 results
557
- - `@reddit_subreddit` - browse a subreddit (e.g., query `"programming"` `/r/programming.json`)
557
+ - `@reddit_subreddit` - browse a subreddit (e.g., query `"programming"` -> `/r/programming.json`)
558
558
 
559
559
  ## Environment Variables
560
560
 
@@ -610,7 +610,7 @@ Browser Instance (Camoufox)
610
610
 
611
611
  Sessions auto-expire after 30 minutes of inactivity. The browser itself shuts down after 5 minutes with no active sessions, and relaunches on the next request.
612
612
 
613
- When a session's tab limit is reached, the oldest/least-used tab is automatically recycled instead of returning an error so long-running agent sessions don't hit dead ends.
613
+ When a session's tab limit is reached, the oldest/least-used tab is automatically recycled instead of returning an error -- so long-running agent sessions don't hit dead ends.
614
614
 
615
615
  ## Testing
616
616
 
@@ -2,7 +2,31 @@
2
2
  "id": "camofox-browser",
3
3
  "name": "Camofox Browser",
4
4
  "description": "Anti-detection browser automation for AI agents using Camoufox (Firefox-based)",
5
- "version": "1.8.7",
5
+ "version": "1.8.8",
6
+ "envVars": {
7
+ "CAMOFOX_API_KEY": {
8
+ "description": "Secret key for the cookie-import endpoint. Cookie import is disabled when unset. Only set this if you need to import browser cookies and the server is local or access-controlled.",
9
+ "required": false,
10
+ "sensitive": true
11
+ },
12
+ "CAMOFOX_ACCESS_KEY": {
13
+ "description": "Global bearer token for all routes (except /health). When set, every request must include Authorization: Bearer <key>. Recommended when exposing the server beyond localhost.",
14
+ "required": false,
15
+ "sensitive": true
16
+ },
17
+ "CAMOFOX_CRASH_REPORT_ENABLED": {
18
+ "description": "Enable or disable anonymized crash/hang reporting. Set to 'false' to disable all outbound crash reports.",
19
+ "required": false,
20
+ "sensitive": false,
21
+ "default": "true"
22
+ },
23
+ "CAMOFOX_CRASH_REPORT_URL": {
24
+ "description": "Crash report relay endpoint. Override to point to a self-hosted relay instead of the default Cloudflare Worker.",
25
+ "required": false,
26
+ "sensitive": false,
27
+ "default": "https://camofox-crash-relay.askjo.workers.dev/report"
28
+ }
29
+ },
6
30
  "configSchema": {
7
31
  "type": "object",
8
32
  "properties": {
@@ -68,7 +92,7 @@
68
92
  },
69
93
  "telemetry": {
70
94
  "crashReporter": {
71
- "description": "Anonymized crash/hang reports sent to a Cloudflare Worker relay. All credentials are environment secrets on the relay nothing sensitive ships in this package.",
95
+ "description": "Anonymized crash/hang reports sent to a Cloudflare Worker relay. All credentials are environment secrets on the relay -- nothing sensitive ships in this package.",
72
96
  "enabled": true,
73
97
  "optOut": "CAMOFOX_CRASH_REPORT_ENABLED=false",
74
98
  "relay": "https://camofox-crash-relay.askjo.workers.dev/report",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askjo/camofox-browser",
3
- "version": "1.8.7",
3
+ "version": "1.8.8",
4
4
  "description": "Headless browser automation server and OpenClaw plugin for AI agents - anti-detection, element refs, and session isolation",
5
5
  "type": "module",
6
6
  "main": "server.js",