@web-auto/camo 0.1.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Jason Zhang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,243 @@
1
+ # Camo CLI
2
+
3
+ [![CI](https://github.com/Jasonzhangf/camo/actions/workflows/ci.yml/badge.svg)](https://github.com/Jasonzhangf/camo/actions/workflows/ci.yml)
4
+ [![npm version](https://badge.fury.io/js/@web-auto%2Fcamo.svg)](https://www.npmjs.com/package/@web-auto/camo)
5
+
6
+ A cross-platform command-line interface for Camoufox browser automation.
7
+
8
+ ## Installation
9
+
10
+ ### npm (Recommended)
11
+
12
+ ```bash
13
+ npm install -g @web-auto/camo
14
+ ```
15
+
16
+ ### From Source
17
+
18
+ ```bash
19
+ git clone https://github.com/Jasonzhangf/camo.git
20
+ cd camo
21
+ npm run build:global
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```bash
27
+ # Initialize environment
28
+ camo init
29
+
30
+ # Create a profile
31
+ camo profile create myprofile
32
+
33
+ # Set as default
34
+ camo profile default myprofile
35
+
36
+ # Start browser
37
+ camo start --url https://example.com
38
+
39
+ # Navigate
40
+ camo goto https://www.xiaohongshu.com
41
+
42
+ # Interact
43
+ camo click "#search-input"
44
+ camo type "#search-input" "hello world"
45
+ camo scroll --down --amount 500
46
+ ```
47
+
48
+ ## Commands
49
+
50
+ ### Profile Management
51
+
52
+ ```bash
53
+ camo profiles # List profiles with default profile
54
+ camo profile create <profileId> # Create a profile
55
+ camo profile delete <profileId> # Delete a profile
56
+ camo profile default [profileId] # Get or set default profile
57
+ ```
58
+
59
+ ### Initialization
60
+
61
+ ```bash
62
+ camo init # Ensure camoufox + browser-service
63
+ camo init geoip # Download GeoIP database
64
+ camo init list # List available OS and regions
65
+ camo create fingerprint --os <os> --region <region>
66
+ ```
67
+
68
+ ### Browser Control
69
+
70
+ ```bash
71
+ camo start [profileId] [--url <url>] [--headless]
72
+ camo stop [profileId]
73
+ camo status [profileId]
74
+ camo shutdown # Shutdown browser-service (all sessions)
75
+ ```
76
+
77
+ ### Lifecycle & Cleanup
78
+
79
+ ```bash
80
+ camo sessions # List active browser sessions
81
+ camo cleanup [profileId] # Cleanup session (release lock + stop)
82
+ camo cleanup all # Cleanup all active sessions
83
+ camo cleanup locks # Cleanup stale lock files
84
+ camo force-stop [profileId] # Force stop session (for stuck sessions)
85
+ camo lock list # List active session locks
86
+ camo recover [profileId] # Recover orphaned session
87
+ ```
88
+
89
+ ### Navigation
90
+
91
+ ```bash
92
+ camo goto [profileId] <url> # Navigate to URL
93
+ camo back [profileId] # Navigate back
94
+ camo screenshot [profileId] [--output <file>] [--full]
95
+ ```
96
+
97
+ ### Interaction
98
+
99
+ ```bash
100
+ camo scroll [profileId] [--down|--up|--left|--right] [--amount <px>]
101
+ camo click [profileId] <selector> # Click element by CSS selector
102
+ camo type [profileId] <selector> <text> # Type text into element
103
+ camo highlight [profileId] <selector> # Highlight element (red border, 2s)
104
+ camo clear-highlight [profileId] # Clear all highlights
105
+ camo viewport [profileId] --width <w> --height <h>
106
+ ```
107
+
108
+ ### Pages
109
+
110
+ ```bash
111
+ camo new-page [profileId] [--url <url>]
112
+ camo close-page [profileId] [index]
113
+ camo switch-page [profileId] <index>
114
+ camo list-pages [profileId]
115
+ ```
116
+
117
+ ### Cookies
118
+
119
+ ```bash
120
+ camo cookies get [profileId] Get all cookies for profile
121
+ camo cookies save [profileId] --path <file> Save cookies to file
122
+ camo cookies load [profileId] --path <file> Load cookies from file
123
+ camo cookies auto start [profileId] [--interval <ms>] Start auto-saving cookies
124
+ camo cookies auto stop [profileId] Stop auto-saving
125
+ camo cookies auto status [profileId] Check auto-save status
126
+ ```
127
+
128
+ ### Window Control
129
+
130
+ ```bash
131
+ camo window move [profileId] --x <x> --y <y>
132
+ camo window resize [profileId] --width <w> --height <h>
133
+ ```
134
+
135
+ ### Mouse Control
136
+
137
+ ```bash
138
+ camo mouse move [profileId] --x <x> --y <y> [--steps <n>]
139
+ camo mouse click [profileId] --x <x> --y <y> [--button left|right|middle] [--clicks <n>] [--delay <ms>]
140
+ camo mouse wheel [profileId] [--deltax <px>] [--deltay <px>]
141
+ ```
142
+
143
+ ### System
144
+
145
+ ```bash
146
+ camo system display # Show display metrics
147
+ ```
148
+
149
+ ## Fingerprint Options
150
+
151
+ ### OS Options
152
+
153
+ - `mac` (default) - macOS (auto architecture)
154
+ - `mac-m1` - macOS with Apple Silicon
155
+ - `mac-intel` - macOS with Intel
156
+ - `windows` - Windows 11
157
+ - `windows-10` - Windows 10
158
+ - `linux` - Ubuntu 22.04
159
+
160
+ ### Region Options
161
+
162
+ - `us` (default) - United States (New York)
163
+ - `us-west` - United States (Los Angeles)
164
+ - `uk` - United Kingdom (London)
165
+ - `de` - Germany (Berlin)
166
+ - `fr` - France (Paris)
167
+ - `jp` - Japan (Tokyo)
168
+ - `sg` - Singapore
169
+ - `au` - Australia (Sydney)
170
+ - `hk` - Hong Kong
171
+ - `tw` - Taiwan (Taipei)
172
+ - `br` - Brazil (Sao Paulo)
173
+ - `in` - India (Mumbai)
174
+
175
+ ## Configuration
176
+
177
+ - Config file: `~/.webauto/camo-cli.json`
178
+ - Profiles directory: `~/.webauto/profiles/`
179
+ - Fingerprints directory: `~/.webauto/fingerprints/`
180
+ - Session registry: `~/.webauto/sessions/`
181
+ - Lock files: `~/.webauto/locks/`
182
+ - GeoIP database: `~/.webauto/geoip/GeoLite2-City.mmdb`
183
+
184
+ ### Environment Variables
185
+
186
+ - `WEBAUTO_BROWSER_URL` - Browser service URL (default: `http://127.0.0.1:7704`)
187
+ - `WEBAUTO_REPO_ROOT` - WebAuto repository root (optional)
188
+
189
+ ## Session Persistence
190
+
191
+ Camo CLI persists session information locally:
192
+
193
+ - Sessions are registered in `~/.webauto/sessions/`
194
+ - On restart, `camo sessions` shows both live and orphaned sessions
195
+ - Use `camo recover <profileId>` to reconnect or cleanup orphaned sessions
196
+ - Stale sessions (>7 days) are automatically cleaned up
197
+
198
+ ## Requirements
199
+
200
+ - Node.js >= 20.0.0
201
+ - Python 3 with `camoufox` package
202
+
203
+ ## Development
204
+
205
+ ```bash
206
+ # Install dependencies
207
+ npm install
208
+
209
+ # Build
210
+ npm run build
211
+
212
+ # Test
213
+ npm test
214
+
215
+ # Global install (build + test + install)
216
+ npm run build:global
217
+
218
+ # Bump version
219
+ npm run version:bump
220
+ ```
221
+
222
+ ## Release
223
+
224
+ ```bash
225
+ # Create a release (bumps version, runs tests, creates tag)
226
+ ./scripts/release.sh
227
+
228
+ # Or manually:
229
+ npm run version:bump
230
+ npm test
231
+ git add package.json
232
+ git commit -m "chore: release v$(node -p "require('./package.json').version")"
233
+ git tag "v$(node -p "require('./package.json').version")"
234
+ git push --follow-tags
235
+ ```
236
+
237
+ GitHub Actions will automatically:
238
+ 1. Run tests on push to main
239
+ 2. Publish to npm when a release is created
240
+
241
+ ## License
242
+
243
+ MIT
package/bin/camo.mjs ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ import { fileURLToPath } from 'node:url';
3
+ import path from 'node:path';
4
+ import { spawn } from 'node:child_process';
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const cliPath = path.join(__dirname, '..', 'src', 'cli.mjs');
8
+
9
+ // Delegate to the modular CLI
10
+ const child = spawn(process.execPath, [cliPath, ...process.argv.slice(2)], {
11
+ stdio: 'inherit',
12
+ env: process.env,
13
+ });
14
+
15
+ child.on('error', (err) => {
16
+ console.error(`Failed to start camo: ${err.message}`);
17
+ process.exit(1);
18
+ });
19
+
20
+ child.on('exit', (code) => {
21
+ process.exit(code || 0);
22
+ });
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@web-auto/camo",
3
+ "version": "0.1.0002",
4
+ "description": "Camoufox Browser CLI - Cross-platform browser automation",
5
+ "type": "module",
6
+ "bin": {
7
+ "camo": "./bin/camo.mjs"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/",
12
+ "scripts/",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "build": "node scripts/build.mjs",
18
+ "test": "node --test tests/*.test.mjs",
19
+ "version:bump": "node scripts/bump-version.mjs",
20
+ "install:global": "npm run build && npm install -g .",
21
+ "uninstall:global": "npm uninstall -g @web-auto/camo",
22
+ "build:global": "npm run build && npm test && npm install -g ."
23
+ },
24
+ "keywords": [
25
+ "browser",
26
+ "automation",
27
+ "camoufox",
28
+ "cli",
29
+ "playwright"
30
+ ],
31
+ "license": "MIT",
32
+ "engines": {
33
+ "node": ">=20.0.0"
34
+ },
35
+ "dependencies": {},
36
+ "peerDependencies": {
37
+ "camoufox": "^0.1.0"
38
+ }
39
+ }
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { copyFileSync, chmodSync, mkdirSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const root = path.resolve(__dirname, '..');
8
+
9
+ // Ensure bin directory exists
10
+ const binDir = path.join(root, 'bin');
11
+ try { mkdirSync(binDir, { recursive: true }); } catch {}
12
+
13
+ // Copy source files to dist (if needed)
14
+ // For now, we're running directly from src/
15
+
16
+ // Make bin/camo.mjs executable
17
+ const binFile = path.join(binDir, 'camo.mjs');
18
+ chmodSync(binFile, 0o755);
19
+ console.log('Build: bin/camo.mjs ready');
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Version bumper for camo CLI
4
+ * Increments patch version maintaining 4-digit format (0.1.0001 -> 0.1.0002)
5
+ */
6
+
7
+ import { readFileSync, writeFileSync } from 'fs';
8
+ import { fileURLToPath } from 'url';
9
+ import { dirname, join } from 'path';
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+ const packageJsonPath = join(__dirname, '..', 'package.json');
14
+
15
+ function bumpVersion() {
16
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
17
+ const currentVersion = pkg.version;
18
+
19
+ // Parse version: 0.1.0001 -> [0, 1, 1]
20
+ const parts = currentVersion.split('.');
21
+ const major = parseInt(parts[0], 10);
22
+ const minor = parseInt(parts[1], 10);
23
+ let patch = parseInt(parts[2], 10);
24
+
25
+ // Increment patch
26
+ patch += 1;
27
+
28
+ // Format with 4 digits
29
+ const newVersion = `${major}.${minor}.${patch.toString().padStart(4, '0')}`;
30
+
31
+ pkg.version = newVersion;
32
+ writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n');
33
+
34
+ console.log(`Version bumped: ${currentVersion} -> ${newVersion}`);
35
+ return newVersion;
36
+ }
37
+
38
+ bumpVersion();
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * camo CLI Global Installer
4
+ * Usage: node scripts/install.mjs [--prefix /usr/local]
5
+ */
6
+ import { execSync } from 'node:child_process';
7
+ import fs from 'node:fs';
8
+ import path from 'node:path';
9
+ import os from 'node:os';
10
+
11
+ const isWin = os.platform() === 'win32';
12
+
13
+ function detectPrefix() {
14
+ const prefixIdx = process.argv.indexOf('--prefix');
15
+ if (prefixIdx >= 0 && process.argv[prefixIdx + 1]) {
16
+ return process.argv[prefixIdx + 1];
17
+ }
18
+
19
+ const candidates = [
20
+ isWin ? path.join(os.homedir(), 'AppData', 'Local', 'camo') : null,
21
+ '/opt/homebrew',
22
+ '/usr/local',
23
+ '/usr',
24
+ path.join(os.homedir(), '.local'),
25
+ ].filter(Boolean);
26
+
27
+ for (const p of candidates) {
28
+ try {
29
+ fs.accessSync(path.dirname(p), fs.constants.W_OK);
30
+ return p;
31
+ } catch {}
32
+ }
33
+
34
+ return path.join(os.homedir(), '.local');
35
+ }
36
+
37
+ function install() {
38
+ const prefix = detectPrefix();
39
+ const binDir = path.join(prefix, 'bin');
40
+ const targetDir = path.join(prefix, 'share', 'camo');
41
+
42
+ console.log(`Installing camo CLI...`);
43
+ console.log(` Prefix: ${prefix}`);
44
+ console.log(` Target: ${targetDir}`);
45
+ console.log(` Bin: ${binDir}`);
46
+
47
+ fs.mkdirSync(targetDir, { recursive: true });
48
+ fs.mkdirSync(binDir, { recursive: true });
49
+
50
+ const thisDir = path.dirname(new URL(import.meta.url).pathname);
51
+ const moduleDir = path.resolve(thisDir, '..');
52
+ const srcFile = path.join(moduleDir, 'bin', 'camoufox.mjs');
53
+
54
+ if (!fs.existsSync(srcFile)) {
55
+ console.error(`Source not found: ${srcFile}`);
56
+ console.error('Run: cp src/cli.mjs bin/camoufox.mjs');
57
+ process.exit(1);
58
+ }
59
+
60
+ const targetFile = path.join(targetDir, 'camoufox.mjs');
61
+ fs.copyFileSync(srcFile, targetFile);
62
+ fs.chmodSync(targetFile, 0o755);
63
+
64
+ const binPath = path.join(binDir, 'camo');
65
+ const wrapper = `#!/usr/bin/env sh
66
+ exec node "${targetFile}" "$@"`;
67
+ fs.writeFileSync(binPath, wrapper);
68
+ fs.chmodSync(binPath, 0o755);
69
+
70
+ console.log(`\n✅ camo CLI installed!`);
71
+ console.log(`\nAdd to PATH if needed:`);
72
+ console.log(` export PATH="${binDir}:$PATH"`);
73
+ console.log(`\nUsage: camo --help`);
74
+ }
75
+
76
+ install();
@@ -0,0 +1,54 @@
1
+ #!/bin/bash
2
+ # Release script for camo CLI
3
+ # Usage: ./scripts/release.sh [patch|minor|major]
4
+
5
+ set -e
6
+
7
+ RELEASE_TYPE="${1:-patch}"
8
+
9
+ # Ensure we're on main branch
10
+ CURRENT_BRANCH=$(git branch --show-current)
11
+ if [ "$CURRENT_BRANCH" != "main" ] && [ "$CURRENT_BRANCH" != "master" ]; then
12
+ echo "Error: Must be on main or master branch"
13
+ exit 1
14
+ fi
15
+
16
+ # Ensure working tree is clean
17
+ if [ -n "$(git status --porcelain)" ]; then
18
+ echo "Error: Working tree is not clean. Commit or stash changes first."
19
+ exit 1
20
+ fi
21
+
22
+ # Pull latest
23
+ git pull --rebase
24
+
25
+ # Bump version
26
+ echo "Bumping version..."
27
+ npm run version:bump
28
+
29
+ # Get new version
30
+ NEW_VERSION=$(node -p "require('./package.json').version")
31
+ echo "New version: $NEW_VERSION"
32
+
33
+ # Run tests
34
+ echo "Running tests..."
35
+ npm test
36
+
37
+ # Build
38
+ echo "Building..."
39
+ npm run build
40
+
41
+ # Commit version bump
42
+ git add package.json
43
+ git commit -m "chore: release v$NEW_VERSION"
44
+
45
+ # Create tag
46
+ git tag "v$NEW_VERSION"
47
+
48
+ # Push commit and tag
49
+ echo "Pushing to remote..."
50
+ git push origin HEAD
51
+ git push origin "v$NEW_VERSION"
52
+
53
+ echo "Release v$NEW_VERSION created successfully!"
54
+ echo "GitHub Actions will automatically publish to npm."