camofox-browser 2.1.0 → 2.4.1
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/CHANGELOG.md +126 -0
- package/README.md +304 -33
- package/dist/src/cli/commands/content.d.ts.map +1 -1
- package/dist/src/cli/commands/content.js +37 -0
- package/dist/src/cli/commands/content.js.map +1 -1
- package/dist/src/cli/commands/core.d.ts.map +1 -1
- package/dist/src/cli/commands/core.js +21 -4
- package/dist/src/cli/commands/core.js.map +1 -1
- package/dist/src/cli/commands/interaction.d.ts.map +1 -1
- package/dist/src/cli/commands/interaction.js +5 -14
- package/dist/src/cli/commands/interaction.js.map +1 -1
- package/dist/src/cli/commands/navigation.d.ts.map +1 -1
- package/dist/src/cli/commands/navigation.js +12 -6
- package/dist/src/cli/commands/navigation.js.map +1 -1
- package/dist/src/cli/commands/server.d.ts.map +1 -1
- package/dist/src/cli/commands/server.js +9 -3
- package/dist/src/cli/commands/server.js.map +1 -1
- package/dist/src/cli/commands/session.d.ts.map +1 -1
- package/dist/src/cli/commands/session.js +23 -5
- package/dist/src/cli/commands/session.js.map +1 -1
- package/dist/src/cli/server/manager.d.ts +1 -0
- package/dist/src/cli/server/manager.d.ts.map +1 -1
- package/dist/src/cli/server/manager.js +7 -12
- package/dist/src/cli/server/manager.js.map +1 -1
- package/dist/src/middleware/lifecycle-activity.d.ts +9 -0
- package/dist/src/middleware/lifecycle-activity.d.ts.map +1 -0
- package/dist/src/middleware/lifecycle-activity.js +21 -0
- package/dist/src/middleware/lifecycle-activity.js.map +1 -0
- package/dist/src/openapi/spec.d.ts +4 -0
- package/dist/src/openapi/spec.d.ts.map +1 -0
- package/dist/src/openapi/spec.js +730 -0
- package/dist/src/openapi/spec.js.map +1 -0
- package/dist/src/routes/core.d.ts.map +1 -1
- package/dist/src/routes/core.js +428 -53
- package/dist/src/routes/core.js.map +1 -1
- package/dist/src/routes/docs.d.ts +3 -0
- package/dist/src/routes/docs.d.ts.map +1 -0
- package/dist/src/routes/docs.js +23 -0
- package/dist/src/routes/docs.js.map +1 -0
- package/dist/src/routes/openclaw.d.ts.map +1 -1
- package/dist/src/routes/openclaw.js +244 -90
- package/dist/src/routes/openclaw.js.map +1 -1
- package/dist/src/server.js +55 -4
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/context-pool.d.ts +19 -3
- package/dist/src/services/context-pool.d.ts.map +1 -1
- package/dist/src/services/context-pool.js +248 -65
- package/dist/src/services/context-pool.js.map +1 -1
- package/dist/src/services/download.d.ts +2 -0
- package/dist/src/services/download.d.ts.map +1 -1
- package/dist/src/services/download.js +110 -80
- package/dist/src/services/download.js.map +1 -1
- package/dist/src/services/lifecycle-controller.d.ts +40 -0
- package/dist/src/services/lifecycle-controller.d.ts.map +1 -0
- package/dist/src/services/lifecycle-controller.js +106 -0
- package/dist/src/services/lifecycle-controller.js.map +1 -0
- package/dist/src/services/resource-extractor.d.ts +1 -0
- package/dist/src/services/resource-extractor.d.ts.map +1 -1
- package/dist/src/services/resource-extractor.js +7 -0
- package/dist/src/services/resource-extractor.js.map +1 -1
- package/dist/src/services/session.d.ts +84 -2
- package/dist/src/services/session.d.ts.map +1 -1
- package/dist/src/services/session.js +349 -47
- package/dist/src/services/session.js.map +1 -1
- package/dist/src/services/structured-extractor.d.ts +39 -0
- package/dist/src/services/structured-extractor.d.ts.map +1 -0
- package/dist/src/services/structured-extractor.js +487 -0
- package/dist/src/services/structured-extractor.js.map +1 -0
- package/dist/src/services/tab.d.ts +30 -3
- package/dist/src/services/tab.d.ts.map +1 -1
- package/dist/src/services/tab.js +877 -124
- package/dist/src/services/tab.js.map +1 -1
- package/dist/src/services/tracing.d.ts +7 -0
- package/dist/src/services/tracing.d.ts.map +1 -1
- package/dist/src/services/tracing.js +162 -19
- package/dist/src/services/tracing.js.map +1 -1
- package/dist/src/services/vnc.d.ts.map +1 -1
- package/dist/src/services/vnc.js +5 -3
- package/dist/src/services/vnc.js.map +1 -1
- package/dist/src/services/youtube.js +1 -1
- package/dist/src/services/youtube.js.map +1 -1
- package/dist/src/types.d.ts +71 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/config.d.ts +79 -3
- package/dist/src/utils/config.d.ts.map +1 -1
- package/dist/src/utils/config.js +145 -3
- package/dist/src/utils/config.js.map +1 -1
- package/dist/src/utils/presets.d.ts.map +1 -1
- package/dist/src/utils/presets.js +3 -1
- package/dist/src/utils/presets.js.map +1 -1
- package/dist/src/utils/proxy-profiles.d.ts +18 -0
- package/dist/src/utils/proxy-profiles.d.ts.map +1 -0
- package/dist/src/utils/proxy-profiles.js +197 -0
- package/dist/src/utils/proxy-profiles.js.map +1 -0
- package/dist/src/utils/sidecar-version.d.ts +12 -0
- package/dist/src/utils/sidecar-version.d.ts.map +1 -0
- package/dist/src/utils/sidecar-version.js +63 -0
- package/dist/src/utils/sidecar-version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/openclaw.plugin.json +39 -0
- package/package.json +16 -4
- package/plugin.ts +949 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,131 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## Release Audit: v2.3.0 -> v2.4.1
|
|
6
|
+
|
|
7
|
+
### What shipped in this line
|
|
8
|
+
- **Security hardening** tightened exposed deployment defaults with loopback-only bind, non-loopback API key enforcement, private-network navigation blocking, and fail-fast proxy deployment validation.
|
|
9
|
+
- **Proxy and geo session identity** moved from user-only scoping to `userId + sessionKey`, allowing parallel sessions with distinct proxy and geo profiles without unsafe reuse or eviction collisions.
|
|
10
|
+
- **Lifecycle control** added staged idle cleanup plus daemon exit policy, with activity-aware timer disarming so live sessions are not collected accidentally.
|
|
11
|
+
- **Fingerprint environment controls** added deployment-level defaults for OS, WebGL, screen dimensions, and humanization, with strict parsing and clear generation-time versus launch-time behavior.
|
|
12
|
+
- **Structured extraction** introduced schema-driven extraction across core API, CLI, and OpenClaw, including validation-time 400s and runtime 422s with stable field-path reporting.
|
|
13
|
+
- **OpenAPI and interactive docs** added `/openapi.json` and `/api/docs`, then hardened the spec and origin handling to match real server behavior.
|
|
14
|
+
- **Release-lane hardening** shipped in `v2.4.1`, ensuring Docker/GHCR publication no longer fails solely because optional GeoLite download during `camoufox-js fetch` is temporarily unavailable.
|
|
15
|
+
|
|
16
|
+
### Reading guide
|
|
17
|
+
- **`2.4.0`** is the main Wave 2 delivery release.
|
|
18
|
+
- **`2.4.1`** is the follow-up patch that fixes the release-distribution lane while inheriting the full `2.4.0` surface.
|
|
19
|
+
|
|
20
|
+
## [2.4.1] - 2026-05-05
|
|
21
|
+
|
|
22
|
+
### Upgrade Notes
|
|
23
|
+
- **Patch scope**: `2.4.1` keeps the full Wave 2 surface from `2.4.0` and only changes release-distribution behavior.
|
|
24
|
+
- **Operator impact**: Docker/GHCR publication no longer fails solely because `camoufox-js fetch` cannot download the optional GeoLite database during image build.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Docker release builds** now tolerate transient `camoufox-js fetch` / GeoLite MMDB download failures during image creation.
|
|
28
|
+
- **Release-lane consistency** now matches the existing best-effort `postinstall` fetch contract already used by package installation.
|
|
29
|
+
|
|
30
|
+
## [2.4.0] - 2026-05-05
|
|
31
|
+
|
|
32
|
+
### Upgrade Notes
|
|
33
|
+
- **Wave 2 delivery** adds OpenAPI documentation, deployment-level fingerprint controls, staged idle lifecycle management, session-level proxy/geo overrides, and structured extraction without removing previous route aliases.
|
|
34
|
+
- **Operational posture** is more defensive than in `2.3.0`: exposed deployments now default to loopback-only binding, require an API key on non-loopback binds, reject unsafe private-network navigation by default, and fail fast on unsupported proxy deployment assumptions.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- **OpenAPI 3.1.0 specification** at `/openapi.json` with request/response schemas, auth requirements, and representative route coverage.
|
|
38
|
+
- **Interactive Swagger UI** at `/api/docs` for live inspection and request testing.
|
|
39
|
+
- **Fingerprint environment controls** for `CAMOFOX_OS`, `CAMOFOX_ALLOW_WEBGL`, `CAMOFOX_SCREEN_WIDTH`, `CAMOFOX_SCREEN_HEIGHT`, and `CAMOFOX_HUMANIZE`.
|
|
40
|
+
- **Idle lifecycle policy** with staged cleanup (`CAMOFOX_IDLE_TIMEOUT_MS`) and daemon exit (`CAMOFOX_IDLE_EXIT_TIMEOUT_MS`).
|
|
41
|
+
- **Session-level proxy/geo overrides** through `proxyProfile`, raw `proxy` fields, and `geoMode`.
|
|
42
|
+
- **OpenClaw proxy/geo parity** for `/tabs/open`.
|
|
43
|
+
- **Structured extraction** across core API, CLI, and OpenClaw with schema validation and deterministic JSON output.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
- **Session identity and reuse** now key proxy/geo behavior on `userId + sessionKey` instead of `userId` alone.
|
|
47
|
+
- **Context pool eviction** now uses `profileKey`, preventing sibling sessions from evicting each other incorrectly.
|
|
48
|
+
- **OpenAPI docs behavior** now derives server origin from the incoming request and safe defaults instead of assuming a single static external origin.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
- **Proxy profile validation** now rejects malformed configuration and preserves conflict behavior when an existing session profile disagrees with new proxy/geo input.
|
|
52
|
+
- **Lifecycle cleanup correctness** now avoids cleanup reentry, preserves reused/live contexts, and only arms daemon exit under valid idle conditions.
|
|
53
|
+
- **Fingerprint env application** now routes screen constraints into fingerprint generation rather than launch-only options, preserving the intended sidecar semantics.
|
|
54
|
+
- **Structured extraction contracts** now reject invalid root schemas/selectors and align API, CLI, and OpenClaw error semantics.
|
|
55
|
+
- **OpenAPI request contracts** now mark required fields correctly and remove mismatched schema claims such as unsupported `/act` coverage.
|
|
56
|
+
|
|
57
|
+
### Security
|
|
58
|
+
- Default server bind is `127.0.0.1` via `CAMOFOX_HOST`, and non-loopback binds require `CAMOFOX_API_KEY`.
|
|
59
|
+
- Navigation target validation blocks loopback/private/link-local/metadata hosts by default on exposed deployments unless `CAMOFOX_ALLOW_PRIVATE_NETWORK=true`.
|
|
60
|
+
- Proxy-enabled exposed deployments fail fast unless the operator explicitly opts into private-network allowance.
|
|
61
|
+
|
|
62
|
+
### Docs
|
|
63
|
+
- README, skills, and agent-facing references were updated to document the shipped Wave 2 surfaces.
|
|
64
|
+
- OpenAPI discovery wording, subset-scope wording, request contracts, and origin handling were corrected to match actual shipped behavior.
|
|
65
|
+
|
|
66
|
+
### Tests
|
|
67
|
+
- Added E2E coverage for security hardening, proxy/geo overrides, OpenClaw proxy/geo support, fingerprint env controls, lifecycle cleanup/exit, OpenAPI docs, and structured extraction.
|
|
68
|
+
- Added unit coverage for profile-key eviction, lifecycle state handling, proxy profile parsing, structured extractor schema/runtime contracts, and URL security validation.
|
|
69
|
+
|
|
70
|
+
## [2.3.0] - 2026-05-03
|
|
71
|
+
|
|
72
|
+
### Upgrade Notes
|
|
73
|
+
- **New Wave 1 surfaces** add trace artifact retrieval and image-only extraction on top of the existing tracing/resource services. These are additive endpoints and do not remove any previous route or alias.
|
|
74
|
+
- **Conditional auth coverage** now includes the image listing route when `CAMOFOX_API_KEY` is set, aligning it with the surrounding extraction/tracing surfaces.
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- **Trace artifact management** — `GET /sessions/:userId/traces`, `GET /sessions/:userId/traces/:filename`, and `DELETE /sessions/:userId/traces/:filename`
|
|
78
|
+
- **Image listing route** — `GET /tabs/:tabId/images` for image-only extraction with selector, extension, blob-resolution, and lazy-load options
|
|
79
|
+
- **Wave 1 regression coverage** for trace ownership/path handling, timeout cleanup, chunk-stop coordination, and image-route auth/behavior
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
- Trace artifact ownership now uses collision-safe owner tokens rather than lossy userId sanitization
|
|
83
|
+
- Trace artifact handling now rejects spoofed paths, keeps managed files inside the traces root, and tolerates vanished files during list operations
|
|
84
|
+
- Trace timeout cleanup now stays coordinated with both manual stop and in-flight chunk-stop operations
|
|
85
|
+
- `extractImages()` no longer requires a fake `userId` shim in its shared extractor contract
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
- README and release metadata now reflect shipped Wave 1 trace/image capabilities
|
|
89
|
+
- Package and OpenClaw plugin versions now advance together to `2.3.0`
|
|
90
|
+
|
|
91
|
+
## [2.2.1] - 2026-04-09
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
- Version bump for release-prep (v2.2.0 tag exists; this patch carries final release framing)
|
|
95
|
+
|
|
96
|
+
## [2.2.0] - 2026-04-09
|
|
97
|
+
|
|
98
|
+
### Upgrade Notes
|
|
99
|
+
- **Local-state sidecar versioning** introduces fail-closed compatibility checks. If local state files are incompatible with the running version, the server will refuse to start the affected session and log an error with the specific path to delete. For sidecar metadata files, only the indicated file needs removal. For profile-level incompatibilities (e.g., Camoufox engine version mismatch), the error may indicate deleting the entire profile directory — follow the error message guidance.
|
|
100
|
+
- **API key guard** is now conditionally applied to core and OpenClaw protected endpoints (tab creation, navigation, interaction, session management, downloads, tracing, console) when `CAMOFOX_API_KEY` is set. The `POST /stop` route requires `CAMOFOX_ADMIN_KEY` unconditionally. Unset deployments are unaffected.
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
- **Conditional API-key guard** (`CAMOFOX_API_KEY`) on core and OpenClaw protected endpoints — tab creation, navigation, interaction, session management, downloads, tracing, console. Guard enforced only when env var is set; unset deployments are unaffected. `POST /stop` uses a separate unconditional `CAMOFOX_ADMIN_KEY` guard
|
|
104
|
+
- **Canonical profile invariants** — staged first-use, rollback-on-failure, cookie race guard
|
|
105
|
+
- **Local-state sidecar versioning** with fail-closed compatibility checks and migration support
|
|
106
|
+
- **Snapshot pagination** with offset-based windowing for large page snapshots
|
|
107
|
+
- **OpenClaw parity** — snapshot, navigate, scroll endpoints aligned with plugin contract
|
|
108
|
+
- **Macro navigate** and scroll parity with initial-download capture
|
|
109
|
+
- **Plugin surface cleanup** — publish/install/plugin artifact contract validation
|
|
110
|
+
|
|
111
|
+
### Fixed
|
|
112
|
+
- Server env whitelist: added `DISPLAY`, `HANDLER_TIMEOUT_MS`, `MAX_CONCURRENT_PER_USER`
|
|
113
|
+
- Unified CLI port and idle-timeout defaults with canonical config
|
|
114
|
+
- Session lifecycle: staged first-use + rollback, cookie race guard, dist rebuild, tab-cap test
|
|
115
|
+
|
|
116
|
+
### Changed
|
|
117
|
+
- README, skills, and governance docs synced to shipped behavior
|
|
118
|
+
|
|
119
|
+
## [2.1.1] - 2026-03-08
|
|
120
|
+
|
|
121
|
+
### Fixed
|
|
122
|
+
- Unknown element ref now returns HTTP 400 with guidance message instead of ambiguous error
|
|
123
|
+
|
|
124
|
+
## [2.1.0] - 2026-03-08
|
|
125
|
+
|
|
126
|
+
### Fixed
|
|
127
|
+
- **Ref system improvements** — strict ref parsing, expanded element roles in snapshot, stale ref detection
|
|
128
|
+
|
|
3
129
|
## [2.0.5] - 2026-03-08
|
|
4
130
|
|
|
5
131
|
### Fixed
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
- [Why CamoFox?](#why-camofox)
|
|
13
13
|
- [Features](#features)
|
|
14
|
+
- [Preview Status](#preview-status)
|
|
14
15
|
- [Quick Start](#quick-start)
|
|
15
16
|
- [CLI](#cli)
|
|
16
17
|
- [Console Capture](#console-capture)
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
- [Usage with AI Agents](#usage-with-ai-agents)
|
|
20
21
|
- [Architecture](#architecture)
|
|
21
22
|
- [API Reference](#api-reference)
|
|
23
|
+
- [Structured Extract](#structured-extract)
|
|
22
24
|
- [Search Macros](#search-macros)
|
|
23
25
|
- [Geo Presets](#geo-presets)
|
|
24
26
|
- [Environment Variables](#environment-variables)
|
|
@@ -50,19 +52,53 @@
|
|
|
50
52
|
- **Multi-Session** — concurrent isolated browser contexts per `userId` (defaults: max 50 sessions, max 10 tabs/session)
|
|
51
53
|
- **Persistent Browser Profiles** — Each user gets a dedicated Firefox profile. Cookies, localStorage, IndexedDB, and all browser storage persist across sessions automatically.
|
|
52
54
|
- **Geo Presets** — 8 built-in region presets (locale/timezone/geolocation) + custom presets file
|
|
55
|
+
- **Session-Level Proxy/Geo Overrides** — per-session proxy configuration via named profiles or raw credentials, with hybrid geo modes (`explicit-wins` or `proxy-locked`)
|
|
53
56
|
- **14 Search Macros** — Google, YouTube, Amazon, Reddit (search + subreddit JSON), Wikipedia, Twitter, Yelp, Spotify, Netflix, LinkedIn, Instagram, TikTok, Twitch
|
|
54
57
|
- **Element Refs** — accessibility snapshots annotated with stable `eN` element references for precise interaction
|
|
55
|
-
- **Cookie Persistence** — import Netscape/Playwright-style cookies into a session (
|
|
58
|
+
- **Cookie Persistence** — import Netscape/Playwright-style cookies into a session (bearer auth required only when `CAMOFOX_API_KEY` is set)
|
|
56
59
|
- **OpenClaw Plugin** — OpenClaw-compatible endpoints (`/start`, `/tabs/open`, `/act`, etc.)
|
|
57
60
|
- **TypeScript** — strict mode, typed request shapes, modular Express routes
|
|
58
|
-
- **YouTube Transcript Extraction** — yt-dlp
|
|
61
|
+
- **YouTube Transcript Extraction** — yt-dlp + browser fallback (service-level; no public API route currently exposed)
|
|
59
62
|
- **Snapshot Pagination** — offset-based windowing for large page snapshots
|
|
63
|
+
- **Image Listing Route** — image-only extraction over the shared resource extractor with selector, extension, lazy-load, and blob-resolution controls
|
|
64
|
+
- **Structured Extract** — deterministic schema-driven JSON extraction across core API, CLI, and OpenClaw without arbitrary JavaScript
|
|
60
65
|
- **Browser Health Monitoring** — health probe with recovery/degraded state tracking
|
|
61
66
|
- 🖥️ **CLI Mode** — 50+ commands for terminal-based browser automation
|
|
62
67
|
- 🔐 **Auth Vault** — AES-256-GCM encrypted credential storage (LLM-safe)
|
|
63
68
|
- 📜 **Pipeline Scripting** — Execute command scripts from files
|
|
64
69
|
- 🔍 **Console Capture** — capture and filter browser console messages and uncaught errors
|
|
65
70
|
- 📼 **Playwright Tracing** — record and export Playwright traces for debugging
|
|
71
|
+
- 🗂️ **Trace Artifact Management** — list, download, and delete managed trace ZIPs per user session
|
|
72
|
+
|
|
73
|
+
## Preview Status
|
|
74
|
+
|
|
75
|
+
CamoFox Browser Server is in **Preview** (Phase 1). Preview releases are functional for browser automation and agent integration, but carry specific compatibility commitments and explicit non-goals.
|
|
76
|
+
|
|
77
|
+
### What Preview Means
|
|
78
|
+
- The REST API and CLI are usable for agent workflows today; [CamoFox MCP](https://github.com/redf0x1/camofox-mcp) is available as an external companion integration
|
|
79
|
+
- New features may be added between minor versions
|
|
80
|
+
- Backward-compatible aliases are maintained for renamed or moved endpoints (see [Compatibility Policy](#compatibility-policy))
|
|
81
|
+
- Local state (profiles, registries, sessions) uses versioned formats with fail-closed integrity checks
|
|
82
|
+
|
|
83
|
+
### What Preview Does NOT Guarantee
|
|
84
|
+
- **Frozen API surface** — endpoint behavior, request shapes, or response formats may change between minor versions
|
|
85
|
+
- **Automatic local-state migration** — browser profiles, download registries, and session files use versioned sidecar formats; incompatible upgrades require manual reset (see [Local State Recovery](#local-state-recovery))
|
|
86
|
+
- **Downgrade safety** — rolling back to an older version may require clearing local state
|
|
87
|
+
- **Fixed GA timeline** — promotion to GA requires meeting evidence-based exit criteria, not a calendar date
|
|
88
|
+
|
|
89
|
+
### Compatibility Policy
|
|
90
|
+
During Preview, CamoFox follows an **additive-only deprecation model**:
|
|
91
|
+
- **Legacy aliases** (e.g., `listItemId` accepted alongside `sessionKey`, OpenClaw `/act` routing to core endpoints) continue to work alongside their replacements
|
|
92
|
+
- **Deprecated fields** are accepted silently; no removal until GA or a documented migration window with advance notice in CHANGELOG
|
|
93
|
+
- **No existing endpoint** is removed in a minor version — removals happen only in major versions with prior CHANGELOG notice
|
|
94
|
+
|
|
95
|
+
### Local State Recovery
|
|
96
|
+
Browser profiles, download registries, and CLI session files use versioned sidecar formats. When upgrading CamoFox:
|
|
97
|
+
- **Compatible versions**: State loads normally
|
|
98
|
+
- **Incompatible or corrupt state**: The server refuses to load incompatible profiles and download registries; the CLI rejects incompatible saved-session files. Both log an actionable error with the specific recovery path.
|
|
99
|
+
- **Recovery**: Delete the affected profile directory, session file, or download registry as indicated in the error message. Clean state is recreated on next use.
|
|
100
|
+
|
|
101
|
+
Supported sidecars include limited forward-migration paths (e.g., fingerprint v0 → v1); when no migration path exists for a given version, the server refuses to load the file and logs an actionable recovery message. There is no silent repair or downgrade path — this fail-closed default prevents data corruption at the cost of manual intervention on unsupported version jumps.
|
|
66
102
|
|
|
67
103
|
## Quick Start
|
|
68
104
|
|
|
@@ -102,6 +138,8 @@ docker run -d \
|
|
|
102
138
|
--name camofox-browser \
|
|
103
139
|
-p 9377:9377 \
|
|
104
140
|
-p 6080:6080 \
|
|
141
|
+
-e CAMOFOX_HOST=0.0.0.0 \
|
|
142
|
+
-e CAMOFOX_API_KEY=change-me \
|
|
105
143
|
-v ~/.camofox:/home/node/.camofox \
|
|
106
144
|
camofox-browser
|
|
107
145
|
```
|
|
@@ -117,9 +155,10 @@ services:
|
|
|
117
155
|
ports:
|
|
118
156
|
- "9377:9377"
|
|
119
157
|
environment:
|
|
158
|
+
CAMOFOX_HOST: "0.0.0.0"
|
|
120
159
|
CAMOFOX_PORT: "9377"
|
|
121
|
-
#
|
|
122
|
-
|
|
160
|
+
# Required when CAMOFOX_HOST is non-loopback
|
|
161
|
+
CAMOFOX_API_KEY: "change-me"
|
|
123
162
|
# CAMOFOX_ADMIN_KEY: "change-me"
|
|
124
163
|
# Optional: proxy routing (also enables Camoufox geoip mode)
|
|
125
164
|
# PROXY_HOST: ""
|
|
@@ -146,7 +185,7 @@ CamoFox Browser includes a powerful CLI for browser automation directly from the
|
|
|
146
185
|
npm install -g camofox-browser
|
|
147
186
|
|
|
148
187
|
# Or use npx (no install needed)
|
|
149
|
-
npx camofox open https://example.com
|
|
188
|
+
npx camofox-browser open https://example.com
|
|
150
189
|
```
|
|
151
190
|
|
|
152
191
|
### Quick Start
|
|
@@ -176,6 +215,7 @@ camofox get-url # Get current page URL
|
|
|
176
215
|
camofox get-text # Get page text content
|
|
177
216
|
camofox get-links # Get all links on page
|
|
178
217
|
camofox get-tabs # List open tabs
|
|
218
|
+
camofox extract-structured @schema.json # Extract deterministic JSON from a schema
|
|
179
219
|
|
|
180
220
|
# Interaction
|
|
181
221
|
camofox click <ref> # Click element by ref
|
|
@@ -426,57 +466,75 @@ AI Agent (MCP / OpenClaw / REST Client)
|
|
|
426
466
|
|
|
427
467
|
Base URL: `http://localhost:9377`
|
|
428
468
|
|
|
469
|
+
> **Security defaults:** `CAMOFOX_HOST` now defaults to `127.0.0.1`. If you bind beyond loopback (for example `0.0.0.0` in Docker or PaaS), `CAMOFOX_API_KEY` becomes required at startup. On non-loopback binds, navigation targets on loopback/private/link-local/metadata hosts are blocked by default unless you explicitly set `CAMOFOX_ALLOW_PRIVATE_NETWORK=true`. If you also configure `PROXY_HOST`/`PROXY_PORT`, exposed deployments must opt into `CAMOFOX_ALLOW_PRIVATE_NETWORK=true` until proxy-side private-target validation exists.
|
|
470
|
+
|
|
471
|
+
### API Documentation
|
|
472
|
+
|
|
473
|
+
The Camofox Browser API includes OpenAPI 3.1.0 docs for a representative subset of the shipped route surface:
|
|
474
|
+
|
|
475
|
+
- **Interactive API Explorer**: [http://localhost:9377/api/docs](http://localhost:9377/api/docs) — Swagger UI with live request testing
|
|
476
|
+
- **OpenAPI Specification**: [http://localhost:9377/openapi.json](http://localhost:9377/openapi.json) — Machine-readable OpenAPI 3.1.0 spec
|
|
477
|
+
|
|
478
|
+
The OpenAPI spec covers a representative subset of core and OpenClaw endpoints, including request schemas, response shapes, authentication requirements, and validation rules.
|
|
479
|
+
|
|
429
480
|
### Core Endpoints
|
|
430
481
|
|
|
431
482
|
Note: For any endpoint that targets an existing tab (`/tabs/:tabId/...`), the server resolves `tabId` **within a `userId` scope**. If you omit `userId`, you will typically get `404 Tab not found`.
|
|
432
483
|
|
|
433
484
|
| Method | Endpoint | Description | Required | Auth |
|
|
434
485
|
|--------|----------|-------------|----------|------|
|
|
435
|
-
| POST | `/sessions/:userId/cookies` | Import cookies into a user session (Playwright cookie objects) | Path: `userId`; Body: `{ "cookies": Cookie[] }` | `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
486
|
+
| POST | `/sessions/:userId/cookies` | Import cookies into a user session (Playwright cookie objects) | Path: `userId`; Body: `{ "cookies": Cookie[] }` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
436
487
|
| GET | `/health` | Health check (also pre-launches the browser) | None | None |
|
|
437
488
|
| GET | `/presets` | List available geo presets (built-in + custom) | None | None |
|
|
438
|
-
| POST | `/tabs` | Create a new tab (supports `preset` + per-field overrides) | Body: `userId` + (`sessionKey` or `listItemId`) |
|
|
489
|
+
| POST | `/tabs` | Create a new tab (supports `preset` + per-field overrides) | Body: `userId` + (`sessionKey` or `listItemId`) | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
439
490
|
| GET | `/tabs?userId=...` | List all tabs for a user (OpenClaw-compatible response shape) | Query: `userId` | None |
|
|
440
|
-
| POST | `/tabs/:tabId/navigate` | Navigate to a URL, or expand a search `macro` + `query` | Body: `userId` + (`url` or `macro`) |
|
|
491
|
+
| POST | `/tabs/:tabId/navigate` | Navigate to a URL, or expand a search `macro` + `query` | Body: `userId` + (`url` or `macro`) | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
441
492
|
| GET | `/tabs/:tabId/snapshot?userId=...` | Accessibility snapshot annotated with `eN` element refs | Query: `userId` | None |
|
|
442
|
-
| POST | `/tabs/:tabId/wait` | Wait for page readiness (DOM + optional network idle) | Body: `userId` |
|
|
443
|
-
| POST | `/tabs/:tabId/click` | Click by `ref` (e.g. `e12`) or CSS `selector` | Body: `userId` + (`ref` or `selector`) |
|
|
444
|
-
| POST | `/tabs/:tabId/type` | Type into an element by `ref` or CSS `selector` | Body: `userId` + (`ref` or `selector`) + `text` |
|
|
445
|
-
| POST | `/tabs/:tabId/press` | Press a key (e.g. `Enter`, `Escape`) | Body: `userId` + `key` |
|
|
446
|
-
| POST | `/tabs/:tabId/scroll` | Scroll up/down by pixels | Body: `userId` |
|
|
447
|
-
| POST | `/tabs/:tabId/scroll-element` | Scroll specific element into view | Body: userId, ref/selector |
|
|
448
|
-
| POST | `/tabs/:tabId/back` | Go back | Body: `userId` |
|
|
449
|
-
| POST | `/tabs/:tabId/forward` | Go forward | Body: `userId` |
|
|
450
|
-
| POST | `/tabs/:tabId/refresh` | Refresh | Body: `userId` |
|
|
493
|
+
| POST | `/tabs/:tabId/wait` | Wait for page readiness (DOM + optional network idle) | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
494
|
+
| POST | `/tabs/:tabId/click` | Click by `ref` (e.g. `e12`) or CSS `selector` | Body: `userId` + (`ref` or `selector`) | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
495
|
+
| POST | `/tabs/:tabId/type` | Type into an element by `ref` or CSS `selector` | Body: `userId` + (`ref` or `selector`) + `text` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
496
|
+
| POST | `/tabs/:tabId/press` | Press a key (e.g. `Enter`, `Escape`) | Body: `userId` + `key` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
497
|
+
| POST | `/tabs/:tabId/scroll` | Scroll up/down/left/right by pixels | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
498
|
+
| POST | `/tabs/:tabId/scroll-element` | Scroll specific element into view | Body: userId, ref/selector | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
499
|
+
| POST | `/tabs/:tabId/back` | Go back | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
500
|
+
| POST | `/tabs/:tabId/forward` | Go forward | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
501
|
+
| POST | `/tabs/:tabId/refresh` | Refresh | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
451
502
|
| GET | `/tabs/:tabId/links?userId=...&limit=50&offset=0` | Extract links (paginated) | Query: `userId` | None |
|
|
503
|
+
| GET | `/tabs/:tabId/images?userId=...` | List extracted images | Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
452
504
|
| GET | `/tabs/:tabId/screenshot?userId=...&fullPage=true` | Screenshot (PNG bytes) | Query: `userId` | None |
|
|
453
505
|
| GET | `/tabs/:tabId/stats?userId=...` | Tab stats + visited URLs | Query: `userId` | None |
|
|
454
|
-
| DELETE | `/tabs/:tabId` | Close a tab (expects JSON body: `{ "userId": "..." }`) | Body: `userId` |
|
|
455
|
-
| DELETE | `/tabs/group/:listItemId` | Close a tab group (expects JSON body: `{ "userId": "..." }`) | Body: `userId` |
|
|
456
|
-
| DELETE | `/sessions/:userId` | Close all sessions for a user | Path: `userId` |
|
|
506
|
+
| DELETE | `/tabs/:tabId` | Close a tab (expects JSON body: `{ "userId": "..." }`) | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
507
|
+
| DELETE | `/tabs/group/:listItemId` | Close a tab group (expects JSON body: `{ "userId": "..." }`) | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
508
|
+
| DELETE | `/sessions/:userId` | Close all sessions for a user | Path: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
509
|
+
| POST | `/sessions/:userId/toggle-display` | Toggle display mode (headless/headed/virtual) | Path: `userId`; Body: `{ "headless": true\|false\|"virtual" }` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
457
510
|
| GET | `/tabs/:tabId/cookies` | Export tab cookies | Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
458
511
|
| GET | `/tabs/:tabId/downloads` | List tab downloads | Query: `userId` | None |
|
|
459
512
|
| GET | `/users/:userId/downloads` | List user downloads | Path: `userId` | None |
|
|
460
513
|
| GET | `/downloads/:downloadId` | Download metadata | Query: `userId` | None |
|
|
461
514
|
| GET | `/downloads/:downloadId/content` | Stream download content | Query: `userId` | None |
|
|
462
|
-
| DELETE | `/downloads/:downloadId` | Delete tracked download | Body or Query: `userId` |
|
|
463
|
-
| POST | `/tabs/:tabId/extract-resources` | Extract downloadable resources | Body: `userId` |
|
|
464
|
-
| POST | `/tabs/:tabId/batch-download` | Batch download resources | Body: `userId` |
|
|
515
|
+
| DELETE | `/downloads/:downloadId` | Delete tracked download | Body or Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
516
|
+
| POST | `/tabs/:tabId/extract-resources` | Extract downloadable resources | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
517
|
+
| POST | `/tabs/:tabId/batch-download` | Batch download resources | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
465
518
|
| POST | `/tabs/:tabId/resolve-blobs` | Resolve blob URLs to base64 | Body: `userId` + `urls[]` | None |
|
|
466
519
|
| POST | `/tabs/:tabId/trace/start` | Start trace recording | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
467
520
|
| POST | `/tabs/:tabId/trace/stop` | Stop and save trace ZIP | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
468
521
|
| POST | `/tabs/:tabId/trace/chunk/start` | Start trace chunk | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
469
522
|
| POST | `/tabs/:tabId/trace/chunk/stop` | Stop chunk and save ZIP | Body: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
470
523
|
| GET | `/tabs/:tabId/trace/status` | Check trace status | Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
524
|
+
| GET | `/sessions/:userId/traces` | List managed trace ZIPs for a user | Path: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
525
|
+
| GET | `/sessions/:userId/traces/:filename` | Download a managed trace ZIP | Path: `userId`, `filename` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
526
|
+
| DELETE | `/sessions/:userId/traces/:filename` | Delete a managed trace ZIP | Path: `userId`, `filename` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
471
527
|
| GET | `/tabs/:tabId/console` | Get console messages | Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
472
528
|
| GET | `/tabs/:tabId/errors` | Get uncaught JS errors | Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
473
529
|
| POST | `/tabs/:tabId/console/clear` | Clear console + errors | Body or Query: `userId` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
530
|
+
| POST | `/tabs/:tabId/extract-structured` | Extract deterministic JSON from a structured schema | Body: `userId` + `schema` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
474
531
|
|
|
475
532
|
### Toggle Display Mode
|
|
476
533
|
```bash
|
|
477
534
|
POST /sessions/:userId/toggle-display
|
|
478
535
|
{"headless": "virtual"}
|
|
479
536
|
```
|
|
537
|
+
**Auth:** Conditional — requires `Authorization: Bearer $CAMOFOX_API_KEY` when `CAMOFOX_API_KEY` is set.
|
|
480
538
|
Switch browser between headless and headed mode. When encountering CAPTCHAs or issues requiring visual interaction, switch to headed mode to show the browser window.
|
|
481
539
|
|
|
482
540
|
Returns:
|
|
@@ -538,12 +596,75 @@ OpenClaw-compatible aliases (used by the OpenClaw plugin).
|
|
|
538
596
|
| Method | Endpoint | Description | Required | Auth |
|
|
539
597
|
|--------|----------|-------------|----------|------|
|
|
540
598
|
| GET | `/` | Status (alias of `/health`) | None | None |
|
|
541
|
-
| POST | `/tabs/open` | Open tab (OpenClaw request/response shape) | Body: `userId` + `url` |
|
|
599
|
+
| POST | `/tabs/open` | Open tab (OpenClaw request/response shape) | Body: `userId` + `url` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
542
600
|
| POST | `/start` | Start browser engine | None | None |
|
|
543
601
|
| POST | `/stop` | Stop browser engine | None | `x-admin-key: $CAMOFOX_ADMIN_KEY` |
|
|
544
|
-
| POST | `/navigate` | Navigate (OpenClaw request shape: `targetId` in body) | Body: `userId` + `targetId` + `url` |
|
|
602
|
+
| POST | `/navigate` | Navigate (OpenClaw request shape: `targetId` in body) | Body: `userId` + `targetId` + `url` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
545
603
|
| GET | `/snapshot?userId=...&targetId=...` | Snapshot (OpenClaw response shape) | Query: `userId` + `targetId` | None |
|
|
546
|
-
| POST | `/act` | Combined actions (`click`, `type`, `press`, `scroll`, `scrollIntoView`, `hover`, `wait`, `close`) | Body: `userId` + `targetId` + `kind` |
|
|
604
|
+
| POST | `/act` | Combined actions (`click`, `type`, `press`, `scroll`, `scrollIntoView`, `hover`, `wait`, `close`, `extractStructured`) | Body: `userId` + `targetId` + `kind` | Conditional: `Authorization: Bearer $CAMOFOX_API_KEY` |
|
|
605
|
+
|
|
606
|
+
### Structured Extract
|
|
607
|
+
|
|
608
|
+
Structured extract returns deterministic JSON from a DOM schema without arbitrary JavaScript. Use it when you want stable data contracts instead of ad-hoc `evaluate()` calls.
|
|
609
|
+
|
|
610
|
+
Core API:
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
curl -X POST "$CAMOFOX_URL/tabs/$TAB_ID/extract-structured" \
|
|
614
|
+
-H 'Content-Type: application/json' \
|
|
615
|
+
-d '{
|
|
616
|
+
"userId": "agent1",
|
|
617
|
+
"schema": {
|
|
618
|
+
"kind": "object",
|
|
619
|
+
"fields": {
|
|
620
|
+
"title": { "kind": "text", "selector": "h1", "required": true, "trim": true },
|
|
621
|
+
"products": {
|
|
622
|
+
"kind": "list",
|
|
623
|
+
"selector": ".product",
|
|
624
|
+
"item": {
|
|
625
|
+
"kind": "object",
|
|
626
|
+
"fields": {
|
|
627
|
+
"name": { "kind": "text", "selector": ".name", "required": true, "trim": true },
|
|
628
|
+
"href": { "kind": "url", "selector": "a.product-link", "attr": "href", "required": true }
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}'
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
CLI:
|
|
638
|
+
|
|
639
|
+
```bash
|
|
640
|
+
camofox extract-structured @schema.json <tabId> --user <userId> --format json
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
OpenClaw:
|
|
644
|
+
|
|
645
|
+
```bash
|
|
646
|
+
curl -X POST "$CAMOFOX_URL/act" \
|
|
647
|
+
-H 'Content-Type: application/json' \
|
|
648
|
+
-d '{
|
|
649
|
+
"kind": "extractStructured",
|
|
650
|
+
"targetId": "tab-123",
|
|
651
|
+
"userId": "agent1",
|
|
652
|
+
"schema": {
|
|
653
|
+
"kind": "object",
|
|
654
|
+
"fields": {
|
|
655
|
+
"title": { "kind": "text", "selector": "h1", "required": true }
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}'
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
Notes:
|
|
662
|
+
|
|
663
|
+
- invalid schemas fail with HTTP 400
|
|
664
|
+
- required runtime misses fail the whole request with HTTP 422 and `fieldPath`
|
|
665
|
+
- optional scalar/object/list nodes normalize to `null` / `null` / `[]`
|
|
666
|
+
- selectors must be CSS; no XPath, arbitrary JavaScript, or AI extraction
|
|
667
|
+
- raw resource extraction and structured extraction stay separate on purpose
|
|
547
668
|
|
|
548
669
|
## Search Macros
|
|
549
670
|
|
|
@@ -591,6 +712,119 @@ curl -X POST http://localhost:9377/tabs \
|
|
|
591
712
|
|
|
592
713
|
Custom presets: set `CAMOFOX_PRESETS_FILE=/path/to/presets.json` (JSON object; keys become preset names).
|
|
593
714
|
|
|
715
|
+
## Session-Level Proxy and Geo Overrides
|
|
716
|
+
|
|
717
|
+
CamoFox supports session-level proxy and geolocation configuration with a hybrid model that combines server defaults with per-session overrides.
|
|
718
|
+
|
|
719
|
+
### Proxy Configuration Model
|
|
720
|
+
|
|
721
|
+
**Server-level baseline** (via environment variables):
|
|
722
|
+
- `PROXY_HOST`, `PROXY_PORT`, `PROXY_USERNAME`, `PROXY_PASSWORD` — applied as the default for all sessions
|
|
723
|
+
- Enables Camoufox geoip mode when configured
|
|
724
|
+
|
|
725
|
+
**Session-level overrides** (via `POST /tabs` or CLI):
|
|
726
|
+
- `proxyProfile` — select a named proxy profile from `CAMOFOX_PROXY_PROFILES_FILE`
|
|
727
|
+
- `proxy` — provide raw proxy fields (`host`, `port`, `username`, `password`) directly
|
|
728
|
+
- Session-level proxy overrides the server baseline for that specific `userId + sessionKey` combination
|
|
729
|
+
|
|
730
|
+
**Session identity rules**:
|
|
731
|
+
- The same `userId` may run different `sessionKey` profiles in parallel with different proxy/geo configurations
|
|
732
|
+
- The same `userId + sessionKey` combination maintains a stable proxy/geo identity — requests with conflicting proxy/geo fields are rejected
|
|
733
|
+
- Session reuse and cleanup scope proxy/geo identity by `userId + sessionKey`, not just `userId`
|
|
734
|
+
|
|
735
|
+
### Geo Mode Behavior
|
|
736
|
+
|
|
737
|
+
CamoFox offers two geo modes that control how explicit geo fields (locale, timezone, geolocation) interact with proxy-derived geo:
|
|
738
|
+
|
|
739
|
+
**`geoMode=explicit-wins`** (default):
|
|
740
|
+
- Explicit geo fields (locale, timezone, geolocation) remain authoritative
|
|
741
|
+
- Proxy-derived geo suggestions are ignored
|
|
742
|
+
- Use this mode when you want precise geo control regardless of proxy location
|
|
743
|
+
|
|
744
|
+
**`geoMode=proxy-locked`**:
|
|
745
|
+
- Explicit geo fields that conflict with proxy-derived geo are rejected
|
|
746
|
+
- Proxy-derived geo is authoritative
|
|
747
|
+
- Use this mode to ensure geo consistency with proxy exit location
|
|
748
|
+
|
|
749
|
+
### CLI Examples
|
|
750
|
+
|
|
751
|
+
Session-level proxy with named profile:
|
|
752
|
+
```bash
|
|
753
|
+
camofox open https://example.com --proxy-profile tokyo-exit --user agent1
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
Session-level proxy with raw fields:
|
|
757
|
+
```bash
|
|
758
|
+
camofox open https://example.com \
|
|
759
|
+
--proxy-host proxy.example.com \
|
|
760
|
+
--proxy-port 8080 \
|
|
761
|
+
--proxy-username user \
|
|
762
|
+
--proxy-password pass \
|
|
763
|
+
--user agent1
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
Combine proxy with geo mode:
|
|
767
|
+
```bash
|
|
768
|
+
camofox open https://example.com \
|
|
769
|
+
--proxy-profile london-exit \
|
|
770
|
+
--geo uk \
|
|
771
|
+
--geo-mode proxy-locked \
|
|
772
|
+
--user agent1
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
### API Examples
|
|
776
|
+
|
|
777
|
+
Using a named proxy profile with explicit geo:
|
|
778
|
+
```bash
|
|
779
|
+
curl -X POST http://localhost:9377/tabs \
|
|
780
|
+
-H 'Content-Type: application/json' \
|
|
781
|
+
-d '{
|
|
782
|
+
"userId": "agent1",
|
|
783
|
+
"sessionKey": "task1",
|
|
784
|
+
"url": "https://example.com",
|
|
785
|
+
"proxyProfile": "tokyo-exit",
|
|
786
|
+
"preset": "japan",
|
|
787
|
+
"geoMode": "explicit-wins"
|
|
788
|
+
}'
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
Using raw proxy fields with proxy-locked geo:
|
|
792
|
+
```bash
|
|
793
|
+
curl -X POST http://localhost:9377/tabs \
|
|
794
|
+
-H 'Content-Type: application/json' \
|
|
795
|
+
-d '{
|
|
796
|
+
"userId": "agent1",
|
|
797
|
+
"sessionKey": "task2",
|
|
798
|
+
"url": "https://example.com",
|
|
799
|
+
"proxy": {
|
|
800
|
+
"host": "proxy.example.com",
|
|
801
|
+
"port": 8080,
|
|
802
|
+
"username": "user",
|
|
803
|
+
"password": "pass"
|
|
804
|
+
},
|
|
805
|
+
"geoMode": "proxy-locked"
|
|
806
|
+
}'
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### Named Proxy Profiles
|
|
810
|
+
|
|
811
|
+
Define proxy profiles in a JSON file and point `CAMOFOX_PROXY_PROFILES_FILE` to it:
|
|
812
|
+
|
|
813
|
+
```json
|
|
814
|
+
{
|
|
815
|
+
"tokyo-exit": {
|
|
816
|
+
"server": "http://tokyo.proxy.example.com:8080",
|
|
817
|
+
"username": "user",
|
|
818
|
+
"password": "pass"
|
|
819
|
+
},
|
|
820
|
+
"london-exit": {
|
|
821
|
+
"server": "http://london.proxy.example.com:8080"
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
Then use profiles by name in API requests or CLI commands.
|
|
827
|
+
|
|
594
828
|
## Environment Variables
|
|
595
829
|
|
|
596
830
|
| Variable | Default | Description |
|
|
@@ -598,8 +832,10 @@ Custom presets: set `CAMOFOX_PRESETS_FILE=/path/to/presets.json` (JSON object; k
|
|
|
598
832
|
| `CAMOFOX_PORT` | `9377` | Server port |
|
|
599
833
|
| `PORT` | (optional) | Alternative port env var (common in PaaS) |
|
|
600
834
|
| `NODE_ENV` | `development` | Node environment |
|
|
835
|
+
| `CAMOFOX_HOST` | `127.0.0.1` | Server bind host. Set `0.0.0.0` for Docker/PaaS/network exposure. Non-loopback binds require `CAMOFOX_API_KEY`. |
|
|
601
836
|
| `CAMOFOX_ADMIN_KEY` | (empty) | Required for `POST /stop` (sent via `x-admin-key`) |
|
|
602
|
-
| `CAMOFOX_API_KEY` | (empty) |
|
|
837
|
+
| `CAMOFOX_API_KEY` | (empty) | Guards protected endpoints (tab creation, navigation, interaction, session management, downloads, image extraction, tracing, console) via `Authorization: Bearer` header when set. Required whenever `CAMOFOX_HOST` exposes the server beyond loopback. |
|
|
838
|
+
| `CAMOFOX_ALLOW_PRIVATE_NETWORK` | `true` on loopback binds, `false` otherwise | Allows navigation to loopback/private/link-local/metadata targets. Leave unset for the safe default; enable only for trusted deployments that intentionally need internal-network reachability. |
|
|
603
839
|
| `CAMOFOX_HEADLESS` | `true` | Display mode: `true` (headless), `false` (headed), `virtual` (Xvfb) |
|
|
604
840
|
| `CAMOFOX_VNC_RESOLUTION` | `1920x1080x24` | Virtual Xvfb display resolution (`WIDTHxHEIGHTxDEPTH`) |
|
|
605
841
|
| `CAMOFOX_VNC_TIMEOUT_MS` | `120000` | Max VNC session duration in ms before auto-stop |
|
|
@@ -618,15 +854,17 @@ Custom presets: set `CAMOFOX_PRESETS_FILE=/path/to/presets.json` (JSON object; k
|
|
|
618
854
|
| `CAMOFOX_VNC_BASE_PORT` | `6080` | noVNC/websockify base port |
|
|
619
855
|
| `CAMOFOX_VNC_HOST` | `localhost` | noVNC host in returned URL |
|
|
620
856
|
| `CAMOFOX_CLI_USER` | `cli-default` | Default CLI user id |
|
|
621
|
-
| `CAMOFOX_IDLE_TIMEOUT_MS` | `1800000` |
|
|
857
|
+
| `CAMOFOX_IDLE_TIMEOUT_MS` | `1800000` | Stage 1 idle cleanup threshold (ms) |
|
|
858
|
+
| `CAMOFOX_IDLE_EXIT_TIMEOUT_MS` | `1800000` | Stage 2 daemon exit quiet window (ms, defaults to match Stage 1) |
|
|
622
859
|
| `CAMOFOX_PRESETS_FILE` | (unset) | Optional JSON file defining/overriding geo presets |
|
|
860
|
+
| `CAMOFOX_PROXY_PROFILES_FILE` | (unset) | Optional JSON file defining named proxy profiles for session-level overrides |
|
|
623
861
|
| `CAMOFOX_SESSION_TIMEOUT` | `1800000` | Session idle timeout in ms (min `60000`) |
|
|
624
862
|
| `CAMOFOX_MAX_SESSIONS` | `50` | Maximum concurrent sessions |
|
|
625
863
|
| `CAMOFOX_MAX_TABS` | `10` | Maximum tabs per session |
|
|
626
|
-
| `PROXY_HOST` | (empty) | Proxy host (enables proxy routing) |
|
|
627
|
-
| `PROXY_PORT` | (empty) | Proxy port |
|
|
628
|
-
| `PROXY_USERNAME` | (empty) | Proxy username |
|
|
629
|
-
| `PROXY_PASSWORD` | (empty) | Proxy password |
|
|
864
|
+
| `PROXY_HOST` | (empty) | Proxy host (server-level default; enables proxy routing) |
|
|
865
|
+
| `PROXY_PORT` | (empty) | Proxy port (server-level default) |
|
|
866
|
+
| `PROXY_USERNAME` | (empty) | Proxy username (server-level default) |
|
|
867
|
+
| `PROXY_PASSWORD` | (empty) | Proxy password (server-level default) |
|
|
630
868
|
| `CAMOFOX_MAX_SNAPSHOT_CHARS` | `80000` | Max characters in snapshot before truncation |
|
|
631
869
|
| `CAMOFOX_SNAPSHOT_TAIL_CHARS` | `5000` | Characters preserved at end of truncated snapshot |
|
|
632
870
|
| `CAMOFOX_BUILDREFS_TIMEOUT_MS` | `12000` | Timeout for building element refs |
|
|
@@ -635,6 +873,34 @@ Custom presets: set `CAMOFOX_PRESETS_FILE=/path/to/presets.json` (JSON object; k
|
|
|
635
873
|
| `CAMOFOX_FAILURE_THRESHOLD` | `3` | Consecutive failures before health degradation |
|
|
636
874
|
| `CAMOFOX_YT_DLP_TIMEOUT_MS` | `30000` | Timeout for yt-dlp subtitle extraction |
|
|
637
875
|
| `CAMOFOX_YT_BROWSER_TIMEOUT_MS` | `25000` | Timeout for browser transcript fallback |
|
|
876
|
+
| `CAMOFOX_OS` | (unset) | Optional server-wide Camoufox OS override (`windows`, `macos`, `linux`, or comma-separated list for randomization) |
|
|
877
|
+
| `CAMOFOX_ALLOW_WEBGL` | (unset) | Optional server-wide WebGL override; malformed values fail startup |
|
|
878
|
+
| `CAMOFOX_SCREEN_WIDTH` | (unset) | Optional screen width override; applied only with `CAMOFOX_SCREEN_HEIGHT` |
|
|
879
|
+
| `CAMOFOX_SCREEN_HEIGHT` | (unset) | Optional screen height override; applied only with `CAMOFOX_SCREEN_WIDTH` |
|
|
880
|
+
| `CAMOFOX_HUMANIZE` | (unset) | Optional server-wide humanization override |
|
|
881
|
+
|
|
882
|
+
> `CAMOFOX_OS` and `CAMOFOX_SCREEN_*` are **generation-time** controls: they affect only newly generated fingerprints and have no effect while an existing `fingerprint.json` sidecar is in use. Reset the profile or delete `fingerprint.json` to force regeneration under the new defaults. `CAMOFOX_ALLOW_WEBGL` and `CAMOFOX_HUMANIZE` are **launch-time** overrides and apply on every browser launch regardless of whether a sidecar is reused.
|
|
883
|
+
|
|
884
|
+
### Idle Lifecycle Policy
|
|
885
|
+
|
|
886
|
+
CamoFox implements a two-stage idle lifecycle for graceful cleanup and daemon exit:
|
|
887
|
+
|
|
888
|
+
**Stage 1 — Idle Cleanup**
|
|
889
|
+
- After `CAMOFOX_IDLE_TIMEOUT_MS` of idle time (default: 30 minutes), the server runs cleanup to close idle sessions and tabs
|
|
890
|
+
- Cleanup is delayed if browser contexts are launching or sessions are being created
|
|
891
|
+
- New interactive activity (tab creation, navigation, interaction) cancels any pending cleanup
|
|
892
|
+
|
|
893
|
+
**Stage 2 — Daemon Exit**
|
|
894
|
+
- After Stage 1 cleanup completes, the server waits for `CAMOFOX_IDLE_EXIT_TIMEOUT_MS` (default: matches Stage 1 timeout)
|
|
895
|
+
- If no new activity occurs during this quiet window, the daemon process exits gracefully
|
|
896
|
+
- Any new request activity cancels the pending exit timer
|
|
897
|
+
|
|
898
|
+
**Activity detection**:
|
|
899
|
+
- Live tabs, launching browser contexts, or staged session creation count as active work and prevent cleanup
|
|
900
|
+
- Empty sessions (sessions with no tabs) do not block cleanup but do disarm pending daemon exit
|
|
901
|
+
- New interactive activity resets both cleanup and exit timers
|
|
902
|
+
|
|
903
|
+
This two-stage model ensures cleanup runs before daemon exit, preventing resource leaks while allowing the server to shut down cleanly when fully idle.
|
|
638
904
|
|
|
639
905
|
## Deployment
|
|
640
906
|
|
|
@@ -644,7 +910,9 @@ Custom presets: set `CAMOFOX_PRESETS_FILE=/path/to/presets.json` (JSON object; k
|
|
|
644
910
|
docker build -t camofox-browser .
|
|
645
911
|
docker run -p 9377:9377 -p 6080:6080 \
|
|
646
912
|
-v ~/.camofox:/home/node/.camofox \
|
|
913
|
+
-e CAMOFOX_HOST=0.0.0.0 \
|
|
647
914
|
-e CAMOFOX_PORT=9377 \
|
|
915
|
+
-e CAMOFOX_API_KEY=change-me \
|
|
648
916
|
camofox-browser
|
|
649
917
|
```
|
|
650
918
|
|
|
@@ -660,6 +928,8 @@ fly deploy
|
|
|
660
928
|
### Railway
|
|
661
929
|
|
|
662
930
|
- Create a new project → deploy from this GitHub repo
|
|
931
|
+
- Set `CAMOFOX_HOST=0.0.0.0`
|
|
932
|
+
- Set `CAMOFOX_API_KEY` to a strong secret
|
|
663
933
|
- Set `CAMOFOX_PORT=9377` (Railway will also provide `PORT`, which is supported)
|
|
664
934
|
- Ensure the service exposes port `9377`
|
|
665
935
|
|
|
@@ -667,6 +937,8 @@ fly deploy
|
|
|
667
937
|
|
|
668
938
|
- Create a new Web Service → deploy from this GitHub repo
|
|
669
939
|
- Use Docker (recommended) and expose port `9377`
|
|
940
|
+
- Set `CAMOFOX_HOST=0.0.0.0`
|
|
941
|
+
- Set `CAMOFOX_API_KEY` to a strong secret
|
|
670
942
|
- Set `CAMOFOX_PORT=9377` (or rely on Render `PORT`)
|
|
671
943
|
|
|
672
944
|
### System Requirements
|
|
@@ -747,4 +1019,3 @@ This project is based on [camofox-browser](https://github.com/jo-inc/camofox-bro
|
|
|
747
1019
|
## Crypto Scam Warning
|
|
748
1020
|
|
|
749
1021
|
Sketchy people are doing sketchy things with crypto tokens named "Camofox" now that this project is getting attention. **Camofox is not a crypto project and will never be one.** Any token, coin, or NFT using the Camofox name has nothing to do with us.
|
|
750
|
-
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/content.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/content.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkF3C,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAoTnF"}
|