@askjo/camoufox-browser 1.0.2 → 1.0.3
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/package.json +37 -1
- package/.env.bak +0 -4
- package/.github/workflows/deploy.yml +0 -21
- package/AGENTS.md +0 -153
- package/experimental/chromium/Dockerfile +0 -35
- package/experimental/chromium/README.md +0 -47
- package/experimental/chromium/run.sh +0 -24
- package/experimental/chromium/server.js +0 -812
- package/fly.toml +0 -29
- package/jest.config.js +0 -41
- package/tests/e2e/concurrency.test.js +0 -103
- package/tests/e2e/formSubmission.test.js +0 -129
- package/tests/e2e/macroNavigation.test.js +0 -92
- package/tests/e2e/navigation.test.js +0 -128
- package/tests/e2e/scroll.test.js +0 -81
- package/tests/e2e/snapshotLinks.test.js +0 -141
- package/tests/e2e/tabLifecycle.test.js +0 -149
- package/tests/e2e/typingEnter.test.js +0 -147
- package/tests/helpers/client.js +0 -222
- package/tests/helpers/startJoBrowser.js +0 -95
- package/tests/helpers/testSite.js +0 -238
- package/tests/live/googleSearch.test.js +0 -93
- package/tests/live/macroExpansion.test.js +0 -132
- package/tests/unit/macros.test.js +0 -123
package/package.json
CHANGED
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askjo/camoufox-browser",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Headless browser automation server and OpenClaw plugin for AI agents - anti-detection, element refs, and session isolation",
|
|
5
5
|
"main": "server-camoufox.js",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Jo Inc <hello@askjo.ai>",
|
|
8
|
+
"homepage": "https://github.com/jo-inc/camoufox-browser#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/jo-inc/camoufox-browser.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/jo-inc/camoufox-browser/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"browser",
|
|
18
|
+
"automation",
|
|
19
|
+
"headless",
|
|
20
|
+
"scraping",
|
|
21
|
+
"camoufox",
|
|
22
|
+
"anti-detection",
|
|
23
|
+
"ai-agent",
|
|
24
|
+
"openclaw",
|
|
25
|
+
"playwright",
|
|
26
|
+
"firefox"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"server-camoufox.js",
|
|
33
|
+
"lib/",
|
|
34
|
+
"plugin.ts",
|
|
35
|
+
"openclaw.plugin.json",
|
|
36
|
+
"run-camoufox.sh",
|
|
37
|
+
"Dockerfile.camoufox",
|
|
38
|
+
"SKILL.md",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
6
42
|
"openclaw": {
|
|
7
43
|
"extensions": ["plugin.ts"]
|
|
8
44
|
},
|
package/.env.bak
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
name: Deploy to Fly.io
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
- main
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
deploy:
|
|
11
|
-
name: Deploy to Fly.io
|
|
12
|
-
runs-on: ubuntu-latest
|
|
13
|
-
concurrency: deploy-group
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@v4
|
|
16
|
-
|
|
17
|
-
- uses: superfly/flyctl-actions/setup-flyctl@master
|
|
18
|
-
|
|
19
|
-
- run: flyctl deploy --remote-only
|
|
20
|
-
env:
|
|
21
|
-
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
package/AGENTS.md
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
# camoufox-browser Agent Guide
|
|
2
|
-
|
|
3
|
-
Headless browser automation server for AI agents. Run locally or deploy to any cloud provider.
|
|
4
|
-
|
|
5
|
-
## Quick Start for Agents
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# Install and start
|
|
9
|
-
npm install && npm start
|
|
10
|
-
# Server runs on http://localhost:3000
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Core Workflow
|
|
14
|
-
|
|
15
|
-
1. **Create a tab** → Get `tabId`
|
|
16
|
-
2. **Navigate** → Go to URL or use search macro
|
|
17
|
-
3. **Get snapshot** → Receive page content with element refs (`e1`, `e2`, etc.)
|
|
18
|
-
4. **Interact** → Click/type using refs
|
|
19
|
-
5. **Repeat** steps 3-4 as needed
|
|
20
|
-
|
|
21
|
-
## API Reference
|
|
22
|
-
|
|
23
|
-
### Create Tab
|
|
24
|
-
```bash
|
|
25
|
-
POST /tabs
|
|
26
|
-
{"userId": "agent1", "listItemId": "task1", "url": "https://example.com"}
|
|
27
|
-
```
|
|
28
|
-
Returns: `{"tabId": "abc123", "url": "...", "title": "..."}`
|
|
29
|
-
|
|
30
|
-
### Navigate
|
|
31
|
-
```bash
|
|
32
|
-
POST /tabs/:tabId/navigate
|
|
33
|
-
{"userId": "agent1", "url": "https://google.com"}
|
|
34
|
-
# Or use macro:
|
|
35
|
-
{"userId": "agent1", "macro": "@google_search", "query": "weather today"}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Get Snapshot
|
|
39
|
-
```bash
|
|
40
|
-
GET /tabs/:tabId/snapshot?userId=agent1
|
|
41
|
-
```
|
|
42
|
-
Returns accessibility tree with refs:
|
|
43
|
-
```
|
|
44
|
-
[heading] Example Domain
|
|
45
|
-
[paragraph] This domain is for use in examples.
|
|
46
|
-
[link e1] More information...
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Click Element
|
|
50
|
-
```bash
|
|
51
|
-
POST /tabs/:tabId/click
|
|
52
|
-
{"userId": "agent1", "ref": "e1"}
|
|
53
|
-
# Or CSS selector:
|
|
54
|
-
{"userId": "agent1", "selector": "button.submit"}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Type Text
|
|
58
|
-
```bash
|
|
59
|
-
POST /tabs/:tabId/type
|
|
60
|
-
{"userId": "agent1", "ref": "e2", "text": "hello world"}
|
|
61
|
-
# Add enter: {"userId": "agent1", "ref": "e2", "text": "search query", "pressEnter": true}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### Scroll
|
|
65
|
-
```bash
|
|
66
|
-
POST /tabs/:tabId/scroll
|
|
67
|
-
{"userId": "agent1", "direction": "down", "amount": 500}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Navigation
|
|
71
|
-
```bash
|
|
72
|
-
POST /tabs/:tabId/back {"userId": "agent1"}
|
|
73
|
-
POST /tabs/:tabId/forward {"userId": "agent1"}
|
|
74
|
-
POST /tabs/:tabId/refresh {"userId": "agent1"}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Get Links
|
|
78
|
-
```bash
|
|
79
|
-
GET /tabs/:tabId/links?userId=agent1&limit=50
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Close Tab
|
|
83
|
-
```bash
|
|
84
|
-
DELETE /tabs/:tabId?userId=agent1
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Search Macros
|
|
88
|
-
|
|
89
|
-
Use these instead of constructing URLs:
|
|
90
|
-
|
|
91
|
-
| Macro | Site |
|
|
92
|
-
|-------|------|
|
|
93
|
-
| `@google_search` | Google |
|
|
94
|
-
| `@youtube_search` | YouTube |
|
|
95
|
-
| `@amazon_search` | Amazon |
|
|
96
|
-
| `@reddit_search` | Reddit |
|
|
97
|
-
| `@wikipedia_search` | Wikipedia |
|
|
98
|
-
| `@twitter_search` | Twitter/X |
|
|
99
|
-
| `@yelp_search` | Yelp |
|
|
100
|
-
| `@linkedin_search` | LinkedIn |
|
|
101
|
-
|
|
102
|
-
## Element Refs
|
|
103
|
-
|
|
104
|
-
Refs like `e1`, `e2` are stable identifiers for page elements:
|
|
105
|
-
|
|
106
|
-
1. Call `/snapshot` to get current refs
|
|
107
|
-
2. Use ref in `/click` or `/type`
|
|
108
|
-
3. Refs reset on navigation - get new snapshot after
|
|
109
|
-
|
|
110
|
-
## Session Management
|
|
111
|
-
|
|
112
|
-
- `userId` isolates cookies/storage between users
|
|
113
|
-
- `listItemId` groups tabs by conversation/task
|
|
114
|
-
- Sessions timeout after 30 minutes of inactivity
|
|
115
|
-
- Delete all user data: `DELETE /sessions/:userId`
|
|
116
|
-
|
|
117
|
-
## Running Engines
|
|
118
|
-
|
|
119
|
-
### Camoufox (Default - Recommended)
|
|
120
|
-
```bash
|
|
121
|
-
npm start
|
|
122
|
-
# Or: ./run-camoufox.sh
|
|
123
|
-
```
|
|
124
|
-
Firefox-based with anti-detection. Bypasses Google captcha.
|
|
125
|
-
|
|
126
|
-
### Chrome (Legacy)
|
|
127
|
-
```bash
|
|
128
|
-
npm run start:chrome
|
|
129
|
-
# Or: ./run.sh
|
|
130
|
-
```
|
|
131
|
-
Playwright + stealth plugin. May be blocked by Google.
|
|
132
|
-
|
|
133
|
-
## Testing
|
|
134
|
-
|
|
135
|
-
```bash
|
|
136
|
-
npm test # E2E tests
|
|
137
|
-
npm run test:live # Live Google tests
|
|
138
|
-
npm run test:debug # With server output
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Docker
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
docker build -f Dockerfile.camoufox -t camoufox-browser .
|
|
145
|
-
docker run -p 3000:3000 camoufox-browser
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Key Files
|
|
149
|
-
|
|
150
|
-
- `server-camoufox.js` - Camoufox engine (default)
|
|
151
|
-
- `server.js` - Chrome engine (legacy)
|
|
152
|
-
- `Dockerfile.camoufox` - Production container
|
|
153
|
-
- `fly.toml` - Fly.io deployment config
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
FROM debian:bookworm-slim
|
|
2
|
-
|
|
3
|
-
# Install Chromium and dependencies
|
|
4
|
-
RUN apt-get update && apt-get install -y \
|
|
5
|
-
chromium \
|
|
6
|
-
fonts-liberation \
|
|
7
|
-
fonts-noto-color-emoji \
|
|
8
|
-
libnss3 \
|
|
9
|
-
libatk-bridge2.0-0 \
|
|
10
|
-
libdrm2 \
|
|
11
|
-
libxkbcommon0 \
|
|
12
|
-
libgbm1 \
|
|
13
|
-
libasound2 \
|
|
14
|
-
libxshmfence1 \
|
|
15
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
16
|
-
|
|
17
|
-
# Install Node.js
|
|
18
|
-
RUN apt-get update && apt-get install -y \
|
|
19
|
-
nodejs \
|
|
20
|
-
npm \
|
|
21
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
22
|
-
|
|
23
|
-
WORKDIR /app
|
|
24
|
-
|
|
25
|
-
COPY package.json ./
|
|
26
|
-
RUN npm install --production
|
|
27
|
-
|
|
28
|
-
COPY server.js ./
|
|
29
|
-
|
|
30
|
-
ENV NODE_ENV=production
|
|
31
|
-
ENV PORT=3000
|
|
32
|
-
|
|
33
|
-
EXPOSE 3000
|
|
34
|
-
|
|
35
|
-
CMD ["node", "server.js"]
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# Chromium Engine (Experimental)
|
|
2
|
-
|
|
3
|
-
Legacy Chromium/Playwright-based browser engine using stealth plugin.
|
|
4
|
-
|
|
5
|
-
> ⚠️ **Not recommended**: Gets blocked by Google and other anti-bot systems. Use the Camoufox engine instead.
|
|
6
|
-
|
|
7
|
-
## Why Experimental?
|
|
8
|
-
|
|
9
|
-
The Playwright + stealth plugin approach is detected by:
|
|
10
|
-
- Google (captcha on search)
|
|
11
|
-
- Cloudflare
|
|
12
|
-
- Many other anti-bot systems
|
|
13
|
-
|
|
14
|
-
The main Camoufox engine uses Firefox with C++ level fingerprint spoofing, which bypasses these protections.
|
|
15
|
-
|
|
16
|
-
## Usage
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# From repo root
|
|
20
|
-
cd experimental/chromium
|
|
21
|
-
|
|
22
|
-
# Install dependencies (from repo root)
|
|
23
|
-
npm install
|
|
24
|
-
|
|
25
|
-
# Run (requires Chromium installed)
|
|
26
|
-
CHROMIUM_PATH=/usr/bin/chromium node server.js
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Docker
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
docker build -t camoufox-browser-chromium .
|
|
33
|
-
docker run -p 3000:3000 camoufox-browser-chromium
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## API
|
|
37
|
-
|
|
38
|
-
Same API as the main Camoufox engine - see root [README.md](../../README.md).
|
|
39
|
-
|
|
40
|
-
## When to Use
|
|
41
|
-
|
|
42
|
-
Only use this if:
|
|
43
|
-
- You're accessing sites that don't have anti-bot protection
|
|
44
|
-
- You need Chromium-specific features
|
|
45
|
-
- You're debugging Playwright issues
|
|
46
|
-
|
|
47
|
-
For all other cases, use `./run-camoufox.sh` from the repo root.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Local development script for jo-browser with auto-reload
|
|
3
|
-
|
|
4
|
-
# Use Playwright's bundled Chromium (has full accessibility API support)
|
|
5
|
-
# Only set CHROMIUM_PATH for Docker/production where we install Chromium separately
|
|
6
|
-
unset CHROMIUM_PATH
|
|
7
|
-
|
|
8
|
-
# Install deps if needed
|
|
9
|
-
if [ ! -d "node_modules" ]; then
|
|
10
|
-
echo "Installing dependencies..."
|
|
11
|
-
npm install
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
# Install nodemon globally if not available
|
|
15
|
-
if ! command -v nodemon &> /dev/null; then
|
|
16
|
-
echo "Installing nodemon..."
|
|
17
|
-
npm install -g nodemon
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
echo "Starting jo-browser on http://localhost:3000 (with auto-reload)"
|
|
21
|
-
echo "Logs: /tmp/jo-browser.log"
|
|
22
|
-
nodemon --watch server.js --exec "node server.js" 2>&1 | while IFS= read -r line; do
|
|
23
|
-
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $line"
|
|
24
|
-
done | tee -a /tmp/jo-browser.log
|