camoufox-cli 0.4.0__tar.gz → 0.5.0__tar.gz

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.

Potentially problematic release.


This version of camoufox-cli might be problematic. Click here for more details.

Files changed (108) hide show
  1. camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0/.claude-plugin/marketplace.json +20 -0
  2. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/browser.ts +5 -0
  3. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/browser.py +6 -0
  4. camoufox_cli-0.5.0/.gitignore +30 -0
  5. camoufox_cli-0.5.0/LICENSE +21 -0
  6. camoufox_cli-0.5.0/Makefile +30 -0
  7. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0}/PKG-INFO +28 -1
  8. camoufox_cli-0.5.0/README.md +253 -0
  9. camoufox_cli-0.5.0/js/.gitignore +2 -0
  10. camoufox_cli-0.5.0/js/LICENSE +21 -0
  11. camoufox_cli-0.5.0/js/package-lock.json +2719 -0
  12. camoufox_cli-0.5.0/js/package.json +47 -0
  13. camoufox_cli-0.5.0/js/pnpm-lock.yaml +1599 -0
  14. camoufox_cli-0.5.0/js/scripts/postinstall.js +11 -0
  15. camoufox_cli-0.5.0/js/src/browser.ts +192 -0
  16. camoufox_cli-0.5.0/js/src/cli.ts +505 -0
  17. camoufox_cli-0.5.0/js/src/commands.ts +352 -0
  18. camoufox_cli-0.5.0/js/src/config.ts +140 -0
  19. camoufox_cli-0.5.0/js/src/daemon.ts +27 -0
  20. camoufox_cli-0.5.0/js/src/identity.ts +206 -0
  21. camoufox_cli-0.5.0/js/src/protocol.ts +32 -0
  22. camoufox_cli-0.5.0/js/src/proxy.ts +40 -0
  23. camoufox_cli-0.5.0/js/src/refs.ts +65 -0
  24. camoufox_cli-0.5.0/js/src/server.ts +131 -0
  25. camoufox_cli-0.5.0/js/tests/browser.test.ts +61 -0
  26. camoufox_cli-0.5.0/js/tests/cli.test.ts +455 -0
  27. camoufox_cli-0.5.0/js/tests/commands.test.ts +194 -0
  28. camoufox_cli-0.5.0/js/tests/e2e.test.ts +216 -0
  29. camoufox_cli-0.5.0/js/tests/protocol.test.ts +98 -0
  30. camoufox_cli-0.5.0/js/tests/proxy.test.ts +55 -0
  31. camoufox_cli-0.5.0/js/tests/refs.test.ts +150 -0
  32. camoufox_cli-0.5.0/js/tests/server.test.ts +193 -0
  33. camoufox_cli-0.5.0/js/tsconfig.json +14 -0
  34. camoufox_cli-0.5.0/js/vitest.config.ts +7 -0
  35. camoufox_cli-0.5.0/pyproject.toml +46 -0
  36. camoufox_cli-0.5.0/skills/camoufox-cli/SKILL.md +351 -0
  37. camoufox_cli-0.5.0/skills/camoufox-cli/references/commands.md +143 -0
  38. camoufox_cli-0.5.0/skills/camoufox-cli/references/snapshot-refs.md +221 -0
  39. camoufox_cli-0.5.0/src/camoufox_cli/__init__.py +0 -0
  40. camoufox_cli-0.5.0/src/camoufox_cli/__main__.py +38 -0
  41. camoufox_cli-0.5.0/src/camoufox_cli/browser.py +190 -0
  42. camoufox_cli-0.5.0/src/camoufox_cli/cli.py +518 -0
  43. camoufox_cli-0.5.0/src/camoufox_cli/commands.py +390 -0
  44. camoufox_cli-0.5.0/src/camoufox_cli/config.py +130 -0
  45. camoufox_cli-0.5.0/src/camoufox_cli/identity.py +215 -0
  46. camoufox_cli-0.5.0/src/camoufox_cli/protocol.py +24 -0
  47. camoufox_cli-0.5.0/src/camoufox_cli/proxy.py +30 -0
  48. camoufox_cli-0.5.0/src/camoufox_cli/refs.py +83 -0
  49. camoufox_cli-0.5.0/src/camoufox_cli/server.py +145 -0
  50. camoufox_cli-0.5.0/tests/__init__.py +0 -0
  51. camoufox_cli-0.5.0/tests/fixture.html +22 -0
  52. camoufox_cli-0.5.0/tests/test_cli.py +392 -0
  53. camoufox_cli-0.5.0/tests/test_commands.py +556 -0
  54. camoufox_cli-0.5.0/tests/test_e2e.py +217 -0
  55. camoufox_cli-0.5.0/tests/test_protocol.py +63 -0
  56. camoufox_cli-0.5.0/tests/test_proxy.py +37 -0
  57. camoufox_cli-0.5.0/tests/test_refs.py +112 -0
  58. camoufox_cli-0.4.0/.claude/settings.local.json +0 -20
  59. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/.gitignore +0 -0
  60. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/LICENSE +0 -0
  61. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/Makefile +0 -0
  62. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/README.md +0 -0
  63. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/.gitignore +0 -0
  64. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/LICENSE +0 -0
  65. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/package-lock.json +0 -0
  66. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/package.json +0 -0
  67. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/pnpm-lock.yaml +0 -0
  68. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/scripts/postinstall.js +0 -0
  69. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/cli.ts +0 -0
  70. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/commands.ts +0 -0
  71. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/daemon.ts +0 -0
  72. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/identity.ts +0 -0
  73. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/protocol.ts +0 -0
  74. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/proxy.ts +0 -0
  75. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/refs.ts +0 -0
  76. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/src/server.ts +0 -0
  77. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/browser.test.ts +0 -0
  78. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/cli.test.ts +0 -0
  79. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/commands.test.ts +0 -0
  80. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/e2e.test.ts +0 -0
  81. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/protocol.test.ts +0 -0
  82. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/proxy.test.ts +0 -0
  83. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/refs.test.ts +0 -0
  84. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tests/server.test.ts +0 -0
  85. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/tsconfig.json +0 -0
  86. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/js/vitest.config.ts +0 -0
  87. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/pyproject.toml +0 -0
  88. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/skills/camoufox-cli/SKILL.md +0 -0
  89. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/skills/camoufox-cli/references/commands.md +0 -0
  90. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/skills/camoufox-cli/references/snapshot-refs.md +0 -0
  91. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/__init__.py +0 -0
  92. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/__main__.py +0 -0
  93. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/cli.py +0 -0
  94. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/commands.py +0 -0
  95. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/identity.py +0 -0
  96. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/protocol.py +0 -0
  97. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/proxy.py +0 -0
  98. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/refs.py +0 -0
  99. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/src/camoufox_cli/server.py +0 -0
  100. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/__init__.py +0 -0
  101. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/fixture.html +0 -0
  102. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/test_cli.py +0 -0
  103. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/test_commands.py +0 -0
  104. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/test_e2e.py +0 -0
  105. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/test_protocol.py +0 -0
  106. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/test_proxy.py +0 -0
  107. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0/.claude/worktrees/hungry-mclaren-0aa1c0}/tests/test_refs.py +0 -0
  108. {camoufox_cli-0.4.0 → camoufox_cli-0.5.0}/.claude-plugin/marketplace.json +0 -0
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "camoufox-cli",
3
+ "owner": {
4
+ "name": "Benn Huang"
5
+ },
6
+ "metadata": {
7
+ "description": "Anti-detect browser automation CLI & Skills for AI agents, powered by Camoufox",
8
+ "version": "0.1.0"
9
+ },
10
+ "plugins": [
11
+ {
12
+ "name": "camoufox-cli",
13
+ "description": "Anti-detect browser automation skill with fingerprint spoofing for AI agents",
14
+ "source": "./",
15
+ "skills": [
16
+ "./skills/camoufox-cli"
17
+ ]
18
+ }
19
+ ]
20
+ }
@@ -8,6 +8,8 @@ import { loadOrCreate, toLaunchOptions } from "./identity.js";
8
8
  import { parseProxySettings } from "./proxy.js";
9
9
  import { RefRegistry } from "./refs.js";
10
10
 
11
+ const MAX_HISTORY = 200;
12
+
11
13
  function ensureBrowserInstalled(): void {
12
14
  try {
13
15
  execFileSync("npx", ["camoufox-js", "path"], { stdio: "pipe" });
@@ -147,6 +149,9 @@ export class BrowserManager {
147
149
  pushHistory(url: string): void {
148
150
  this.history = this.history.slice(0, this.historyIndex + 1);
149
151
  this.history.push(url);
152
+ if (this.history.length > MAX_HISTORY) {
153
+ this.history = this.history.slice(-MAX_HISTORY);
154
+ }
150
155
  this.historyIndex = this.history.length - 1;
151
156
  }
152
157
 
@@ -13,6 +13,9 @@ from .proxy import parse_proxy_settings
13
13
  from .refs import RefRegistry
14
14
 
15
15
 
16
+ _MAX_HISTORY = 200
17
+
18
+
16
19
  def _ensure_browser_installed() -> None:
17
20
  """Check that the Camoufox browser binary is installed, raise if not."""
18
21
  try:
@@ -147,6 +150,9 @@ class BrowserManager:
147
150
  # Truncate forward history when navigating to a new page
148
151
  self._history = self._history[:self._history_index + 1]
149
152
  self._history.append(url)
153
+ # Cap history to avoid unbounded growth in long-lived daemons.
154
+ if len(self._history) > _MAX_HISTORY:
155
+ self._history = self._history[-_MAX_HISTORY:]
150
156
  self._history_index = len(self._history) - 1
151
157
 
152
158
  def go_back(self) -> str | None:
@@ -0,0 +1,30 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .venv/
9
+ .mypy_cache/
10
+ uv.lock
11
+
12
+ # Node
13
+ node_modules/
14
+ js/README.md
15
+
16
+ # IDE
17
+ .idea/
18
+ .vscode/
19
+ *.swp
20
+ *.swo
21
+
22
+ # OS
23
+ .DS_Store
24
+
25
+ # Env
26
+ .env
27
+
28
+ # Runtime
29
+ *.sock
30
+ *.pid
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Benn Huang
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.
@@ -0,0 +1,30 @@
1
+ .PHONY: test test-unit test-integration test-e2e build publish publish-pip publish-npm clean
2
+
3
+ test:
4
+ python -m pytest tests/ -v
5
+
6
+ test-unit:
7
+ python -m pytest tests/ -v -m "not integration"
8
+
9
+ test-integration:
10
+ python -m pytest tests/ -v -m integration
11
+
12
+ test-e2e:
13
+ python -m pytest tests/test_e2e.py -v
14
+ cd js && npx vitest run tests/e2e.test.ts
15
+
16
+ build: clean
17
+ uv build
18
+ cd js && npm run build
19
+
20
+ publish: publish-pip publish-npm
21
+
22
+ publish-pip: build
23
+ uvx twine upload dist/*
24
+
25
+ publish-npm: build
26
+ cd js && npm publish --access public
27
+
28
+ clean:
29
+ rm -rf dist/
30
+ rm -rf js/dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: camoufox-cli
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Anti-detect browser CLI & Skills for AI agents, powered by Camoufox
5
5
  Project-URL: Homepage, https://github.com/Bin-Huang/camoufox-cli
6
6
  Project-URL: Repository, https://github.com/Bin-Huang/camoufox-cli
@@ -180,6 +180,33 @@ camoufox-cli cookies export file.json # Export cookies
180
180
  --locale <tag> Force browser locale (e.g. "en-US" or "en-US,zh-CN")
181
181
  ```
182
182
 
183
+ ## Config File
184
+
185
+ Tired of repeating the same flags on every call? Put defaults in `~/.camoufox-cli/config.json` (override the path with `$CAMOUFOX_CLI_CONFIG`):
186
+
187
+ ```json
188
+ {
189
+ "default": {
190
+ "persistent": true,
191
+ "timeout": 3600,
192
+ "proxy": "http://user:pass@host:8080"
193
+ },
194
+ "sessions": {
195
+ "<your-session-name>": {
196
+ "proxy": "socks5://127.0.0.1:1080",
197
+ "locale": "zh-CN"
198
+ }
199
+ }
200
+ }
201
+ ```
202
+
203
+ - **`default`** applies to every session.
204
+ - **`sessions` is optional.** You never pre-register sessions — the name is just whatever you pass to `--session`. A `sessions.<name>` block only kicks in when you happen to run `--session <name>`, layering its keys on top of `default`; any other session (or no `--session` at all) just uses `default`. Above, `camoufox-cli --session <your-session-name> open <url>` swaps in that block's proxy + locale, while every other session keeps the `default` proxy.
205
+ - **Command-line flags always win** over the file, which in turn wins over built-in defaults.
206
+ - Settable keys: `proxy`, `locale`, `geoip`, `persistent` (`true` / `false` / path string), `headed`, `timeout`, `json`. `session` is command-line only (it selects which block to apply), and per-command options like `--full` or `-i` are never read from config.
207
+ - A broken config never blocks a command — it's ignored with a warning on stderr.
208
+ - Config is read when a session's daemon **first launches**. If one is already running for that session, run `camoufox-cli --session <name> close` first for changes to take effect.
209
+
183
210
  ## Persistent Identity
184
211
 
185
212
  Without `--persistent`, every launch gets a fresh random fingerprint. With `--persistent`, a `camoufox-cli.json` file is written next to the browser's user data. Fingerprint, OS, and canvas/font seeds are generated on the first launch and frozen afterwards; locale and proxy-derived timezone/geolocation are also saved but track whatever you pass on the command line. Every subsequent launch with the same path reloads the identity, so sites see the same device on every visit.
@@ -0,0 +1,253 @@
1
+ # camoufox-cli
2
+
3
+ Anti-detect browser CLI & Skills for AI agents, powered by [Camoufox](https://github.com/daijro/camoufox).
4
+
5
+ ### Highlights
6
+
7
+ - C++-level fingerprint spoofing via Camoufox (canvas, WebGL, audio, screen metrics, fonts)
8
+ - Persistent identities: stable fingerprint, OS, and locale across launches with `--persistent`
9
+ - Accessibility-tree snapshots with `@ref` element targeting
10
+ - Session isolation with cookie import/export
11
+ - Shell commands, no code generation
12
+
13
+ ### Works with
14
+
15
+ OpenClaw, Claude Code, Cursor, Codex, and any agent that can run shell commands.
16
+
17
+ ## Install
18
+
19
+ Tell your AI agent (e.g. OpenClaw):
20
+
21
+ > Install this CLI and skills from https://github.com/Bin-Huang/camoufox-cli
22
+
23
+ Or install manually:
24
+
25
+ ```bash
26
+ npm install -g camoufox-cli
27
+ camoufox-cli install # Download browser
28
+ ```
29
+
30
+ Or with pip:
31
+
32
+ ```bash
33
+ pipx install camoufox-cli
34
+ camoufox-cli install # Download browser
35
+ ```
36
+
37
+ On Linux, install system dependencies with:
38
+
39
+ ```bash
40
+ camoufox-cli install --with-deps
41
+ ```
42
+
43
+ ### Agent Skill
44
+
45
+ ```bash
46
+ # Add skills for AI agents (Claude Code, Cursor, Codex, etc.)
47
+ npx skills add Bin-Huang/camoufox-cli
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ```bash
53
+ camoufox-cli open https://example.com # Launch browser & navigate
54
+ camoufox-cli snapshot -i # Interactive elements only
55
+ # - link "More information..." [ref=e1]
56
+ camoufox-cli click @e1 # Click by ref
57
+ camoufox-cli close # Done
58
+ ```
59
+
60
+ ## Commands
61
+
62
+ ### Navigation
63
+
64
+ ```bash
65
+ camoufox-cli open <url> # Navigate to URL (starts daemon if needed)
66
+ camoufox-cli back # Go back
67
+ camoufox-cli forward # Go forward
68
+ camoufox-cli reload # Reload page
69
+ camoufox-cli url # Print current URL
70
+ camoufox-cli title # Print page title
71
+ camoufox-cli close # Close browser and stop daemon
72
+ ```
73
+
74
+ ### Snapshot
75
+
76
+ ```bash
77
+ camoufox-cli snapshot # Full accessibility tree
78
+ camoufox-cli snapshot -i # Interactive elements only
79
+ camoufox-cli snapshot -s "css-selector" # Scoped to CSS selector
80
+ ```
81
+
82
+ Output format:
83
+
84
+ ```
85
+ - heading "Example Domain" [level=1] [ref=e1]
86
+ - paragraph [ref=e2]
87
+ - link "More information..." [ref=e3]
88
+ ```
89
+
90
+ ### Interaction
91
+
92
+ ```bash
93
+ camoufox-cli click @e1 # Click element
94
+ camoufox-cli fill @e3 "search query" # Clear + type into input
95
+ camoufox-cli type @e3 "append text" # Type without clearing
96
+ camoufox-cli select @e5 "option text" # Select dropdown option
97
+ camoufox-cli check @e6 # Toggle checkbox
98
+ camoufox-cli hover @e2 # Hover over element
99
+ camoufox-cli press Enter # Press keyboard key
100
+ camoufox-cli press "Control+a" # Key combination
101
+ ```
102
+
103
+ ### Data Extraction
104
+
105
+ ```bash
106
+ camoufox-cli text @e1 # Get text content of element
107
+ camoufox-cli text body # Get all page text
108
+ camoufox-cli eval "document.title" # Execute JavaScript
109
+ camoufox-cli screenshot # Screenshot (JSON with base64)
110
+ camoufox-cli screenshot page.png # Screenshot to file
111
+ camoufox-cli screenshot --full page.png # Full page screenshot
112
+ ```
113
+
114
+ ### Scroll & Wait
115
+
116
+ ```bash
117
+ camoufox-cli scroll down # Scroll down 500px
118
+ camoufox-cli scroll up 1000 # Scroll up 1000px
119
+ camoufox-cli wait 2000 # Wait milliseconds
120
+ camoufox-cli wait @e1 # Wait for element to appear
121
+ camoufox-cli wait --url "*/dashboard" # Wait for URL pattern
122
+ ```
123
+
124
+ ### Tabs
125
+
126
+ ```bash
127
+ camoufox-cli tabs # List open tabs
128
+ camoufox-cli switch 2 # Switch to tab by index
129
+ camoufox-cli close-tab # Close current tab
130
+ ```
131
+
132
+ ### Sessions
133
+
134
+ ```bash
135
+ camoufox-cli sessions # List active sessions
136
+ camoufox-cli --session work open <url> # Use named session
137
+ camoufox-cli close --all # Close all sessions
138
+ ```
139
+
140
+ ### Cookies
141
+
142
+ ```bash
143
+ camoufox-cli cookies # Dump cookies as JSON
144
+ camoufox-cli cookies import file.json # Import cookies
145
+ camoufox-cli cookies export file.json # Export cookies
146
+ ```
147
+
148
+ ## Flags
149
+
150
+ ```
151
+ --session <name> Named session (default: "default")
152
+ --headed Show browser window (default: headless)
153
+ --timeout <seconds> Daemon idle timeout (default: 1800)
154
+ --json Output as JSON
155
+ --persistent [path] Persistent identity (see below); default path: ~/.camoufox-cli/profiles/<session>
156
+ --proxy <url> Proxy server (http:// or https://; auth: http://user:pass@host:port)
157
+ --no-geoip Disable automatic GeoIP spoofing (auto-enabled with --proxy)
158
+ --locale <tag> Force browser locale (e.g. "en-US" or "en-US,zh-CN")
159
+ ```
160
+
161
+ ## Config File
162
+
163
+ Tired of repeating the same flags on every call? Put defaults in `~/.camoufox-cli/config.json` (override the path with `$CAMOUFOX_CLI_CONFIG`):
164
+
165
+ ```json
166
+ {
167
+ "default": {
168
+ "persistent": true,
169
+ "timeout": 3600,
170
+ "proxy": "http://user:pass@host:8080"
171
+ },
172
+ "sessions": {
173
+ "<your-session-name>": {
174
+ "proxy": "socks5://127.0.0.1:1080",
175
+ "locale": "zh-CN"
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ - **`default`** applies to every session.
182
+ - **`sessions` is optional.** You never pre-register sessions — the name is just whatever you pass to `--session`. A `sessions.<name>` block only kicks in when you happen to run `--session <name>`, layering its keys on top of `default`; any other session (or no `--session` at all) just uses `default`. Above, `camoufox-cli --session <your-session-name> open <url>` swaps in that block's proxy + locale, while every other session keeps the `default` proxy.
183
+ - **Command-line flags always win** over the file, which in turn wins over built-in defaults.
184
+ - Settable keys: `proxy`, `locale`, `geoip`, `persistent` (`true` / `false` / path string), `headed`, `timeout`, `json`. `session` is command-line only (it selects which block to apply), and per-command options like `--full` or `-i` are never read from config.
185
+ - A broken config never blocks a command — it's ignored with a warning on stderr.
186
+ - Config is read when a session's daemon **first launches**. If one is already running for that session, run `camoufox-cli --session <name> close` first for changes to take effect.
187
+
188
+ ## Persistent Identity
189
+
190
+ Without `--persistent`, every launch gets a fresh random fingerprint. With `--persistent`, a `camoufox-cli.json` file is written next to the browser's user data. Fingerprint, OS, and canvas/font seeds are generated on the first launch and frozen afterwards; locale and proxy-derived timezone/geolocation are also saved but track whatever you pass on the command line. Every subsequent launch with the same path reloads the identity, so sites see the same device on every visit.
191
+
192
+ ```bash
193
+ # First launch: generates + stores identity
194
+ camoufox-cli --persistent ~/.camoufox-cli/profiles/alice open https://example.com
195
+
196
+ # Every subsequent launch: same fingerprint, same cookies, same device
197
+ camoufox-cli --persistent ~/.camoufox-cli/profiles/alice open https://example.com
198
+ ```
199
+
200
+ **Frozen** — generated on the first launch, permanent until the directory is deleted:
201
+
202
+ - Fingerprint (UA, canvas, WebGL, fonts, navigator properties)
203
+ - OS (defaults to host OS)
204
+ - Canvas/font noise seeds
205
+
206
+ **Persisted** — stored in the file, refreshed whenever you pass the flag:
207
+
208
+ - `--locale`: sets the stored locale; pass it again to change it, omit it to keep the stored value.
209
+ - Timezone / geolocation: re-derived from the current proxy's IP whenever `--proxy` is active (and `--no-geoip` isn't set), then written back. Without a proxy, the last stored values stay in effect.
210
+
211
+ **Per-launch** — never stored; pass on every launch for it to apply:
212
+
213
+ - `--proxy`: proxies rotate or expire; re-specify each launch to avoid silently running through a stale one.
214
+ - `--no-geoip`: follows the current `--proxy`.
215
+
216
+ **Multiple identities in parallel.** Each persistent path is a distinct identity. Combine with `--session` for concurrent daemons:
217
+
218
+ ```bash
219
+ camoufox-cli --session a --persistent ~/.camoufox-cli/profiles/alice open https://...
220
+ camoufox-cli --session b --persistent ~/.camoufox-cli/profiles/bob open https://...
221
+ ```
222
+
223
+ **Resetting an identity.** Just delete the directory (`rm -rf ~/.camoufox-cli/profiles/alice`). The next launch generates a fresh one.
224
+
225
+ ## Architecture
226
+
227
+ ```
228
+ CLI (camoufox-cli) ──Unix socket──▶ Daemon (Python) ──Playwright──▶ Camoufox (Firefox)
229
+ ```
230
+
231
+ The CLI sends JSON commands to a long-running daemon process via Unix socket. The daemon manages the Camoufox browser instance and maintains the ref registry between commands. The daemon auto-starts on the first command and auto-stops after 30 minutes of inactivity.
232
+
233
+ ## Related
234
+
235
+ - [google-analytics-cli](https://github.com/Bin-Huang/google-analytics-cli) -- Google Analytics CLI & Skills for AI agents (and humans)
236
+ - [google-search-console-cli](https://github.com/Bin-Huang/google-search-console-cli) -- Google Search Console CLI & Skills for AI agents (and humans)
237
+ - [youtube-analytics-cli](https://github.com/Bin-Huang/youtube-analytics-cli) -- YouTube Analytics CLI & Skills for AI agents (and humans)
238
+ - [x-analytics-cli](https://github.com/Bin-Huang/x-analytics-cli) -- X Analytics CLI & Skills for AI agents (and humans)
239
+ - [google-ads-open-cli](https://github.com/Bin-Huang/google-ads-open-cli) -- Google Ads CLI & Skills for AI agents (and humans)
240
+ - [meta-ads-open-cli](https://github.com/Bin-Huang/meta-ads-open-cli) -- Meta Ads CLI & Skills for AI agents (and humans)
241
+ - [microsoft-ads-cli](https://github.com/Bin-Huang/microsoft-ads-cli) -- Microsoft Ads CLI & Skills for AI agents (and humans)
242
+ - [amazon-ads-open-cli](https://github.com/Bin-Huang/amazon-ads-open-cli) -- Amazon Ads CLI & Skills for AI agents (and humans)
243
+ - [tiktok-ads-cli](https://github.com/Bin-Huang/tiktok-ads-cli) -- TikTok Ads CLI & Skills for AI agents (and humans)
244
+ - [linkedin-ads-cli](https://github.com/Bin-Huang/linkedin-ads-cli) -- LinkedIn Ads CLI & Skills for AI agents (and humans)
245
+ - [x-ads-cli](https://github.com/Bin-Huang/x-ads-cli) -- X Ads CLI & Skills for AI agents (and humans)
246
+ - [snapchat-ads-cli](https://github.com/Bin-Huang/snapchat-ads-cli) -- Snapchat Ads CLI & Skills for AI agents (and humans)
247
+ - [pinterest-ads-cli](https://github.com/Bin-Huang/pinterest-ads-cli) -- Pinterest Ads CLI & Skills for AI agents (and humans)
248
+ - [reddit-ads-cli](https://github.com/Bin-Huang/reddit-ads-cli) -- Reddit Ads CLI & Skills for AI agents (and humans)
249
+ - [spotify-ads-cli](https://github.com/Bin-Huang/spotify-ads-cli) -- Spotify Ads CLI & Skills for AI agents (and humans)
250
+ - [apple-ads-cli](https://github.com/Bin-Huang/apple-ads-cli) -- Apple Ads CLI & Skills for AI agents (and humans)
251
+ ## License
252
+
253
+ MIT
@@ -0,0 +1,2 @@
1
+ node_modules/
2
+ dist/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Benn Huang
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.