mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0ba21faa1 | ||
|
|
b501d8f158 | ||
|
|
6007a6e511 | ||
|
|
96c55352e0 |
@@ -59,9 +59,6 @@ jobs:
|
|||||||
needs: [test, validate-version]
|
needs: [test, validate-version]
|
||||||
if: always() && needs.test.result == 'success' && (needs.validate-version.result == 'success' || needs.validate-version.result == 'skipped')
|
if: always() && needs.test.result == 'success' && (needs.validate-version.result == 'success' || needs.validate-version.result == 'skipped')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment:
|
|
||||||
name: pypi
|
|
||||||
url: https://pypi.org/p/cloakbrowser
|
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write # OIDC trusted publishing — no PYPI_TOKEN needed
|
id-token: write # OIDC trusted publishing — no PYPI_TOKEN needed
|
||||||
steps:
|
steps:
|
||||||
@@ -80,9 +77,6 @@ jobs:
|
|||||||
needs: [test, validate-version]
|
needs: [test, validate-version]
|
||||||
if: always() && needs.test.result == 'success' && (needs.validate-version.result == 'success' || needs.validate-version.result == 'skipped')
|
if: always() && needs.test.result == 'success' && (needs.validate-version.result == 'success' || needs.validate-version.result == 'skipped')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment:
|
|
||||||
name: npm
|
|
||||||
url: https://www.npmjs.com/package/cloakbrowser
|
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write # OIDC trusted publishing + provenance — no NPM_TOKEN needed
|
id-token: write # OIDC trusted publishing + provenance — no NPM_TOKEN needed
|
||||||
steps:
|
steps:
|
||||||
@@ -102,9 +96,6 @@ jobs:
|
|||||||
needs: [test, validate-version]
|
needs: [test, validate-version]
|
||||||
if: always() && needs.test.result == 'success' && (needs.validate-version.result == 'success' || needs.validate-version.result == 'skipped')
|
if: always() && needs.test.result == 'success' && (needs.validate-version.result == 'success' || needs.validate-version.result == 'skipped')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
environment:
|
|
||||||
name: docker
|
|
||||||
url: https://hub.docker.com/r/cloakhq/cloakbrowser
|
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write # Cosign keyless signing + attestations
|
id-token: write # Cosign keyless signing + attestations
|
||||||
contents: read
|
contents: read
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ test-infra/
|
|||||||
# Website (deployed separately)
|
# Website (deployed separately)
|
||||||
site/
|
site/
|
||||||
|
|
||||||
|
# Browser profile manager (deployed separately)
|
||||||
|
manager/
|
||||||
|
|
||||||
# Release scripts
|
# Release scripts
|
||||||
publish.sh
|
publish.sh
|
||||||
deploy.sh
|
deploy.sh
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ Changes are tagged: **[wrapper]** for Python/JS wrapper, **[binary]** for Chromi
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [0.3.14] — 2026-03-12
|
||||||
|
|
||||||
|
- **[binary]** Upgrade Linux build to 145.0.7632.159.6 — fix persistent context detection by FingerprintJS
|
||||||
|
- **[binary]** Storage quota normalization for persistent context profiles
|
||||||
|
- **[binary]** Fix outerHeight calculation for non-incognito contexts
|
||||||
|
- **[wrapper]** Add CLI for binary management — `python -m cloakbrowser install` / `npx cloakbrowser install` with visible download progress (closes #43)
|
||||||
|
|
||||||
## [0.3.13] — 2026-03-10
|
## [0.3.13] — 2026-03-10
|
||||||
|
|
||||||
- **[wrapper]** Suppress Playwright's `--enable-unsafe-swiftshader` default arg — eliminates SwiftShader software renderer detection signal, letting the binary's GPU spoofing work cleanly
|
- **[wrapper]** Suppress Playwright's `--enable-unsafe-swiftshader` default arg — eliminates SwiftShader software renderer detection signal, letting the binary's GPU spoofing work cleanly
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ page.goto("https://example.com")
|
|||||||
|
|
||||||
> ⭐ **Star** to show support — **[Watch releases](https://github.com/CloakHQ/CloakBrowser/subscription)** to get notified when new builds drop.
|
> ⭐ **Star** to show support — **[Watch releases](https://github.com/CloakHQ/CloakBrowser/subscription)** to get notified when new builds drop.
|
||||||
|
|
||||||
## Latest: v0.3.13 (Chromium 145.0.7632.159.5)
|
## Latest: v0.3.14 (Chromium 145.0.7632.159.6)
|
||||||
|
|
||||||
- **`humanize=True`** — one flag makes all mouse, keyboard, and scroll interactions behave like a real user. Bézier curves, per-character typing, realistic scroll patterns. Two presets: `default` and `careful`
|
- **`humanize=True`** — one flag makes all mouse, keyboard, and scroll interactions behave like a real user. Bézier curves, per-character typing, realistic scroll patterns. Two presets: `default` and `careful`
|
||||||
- **CDP input behavior mimicking** — input events sent via CDP now produce the same signals as real user interactions. 5 new source-level patches covering pointer, keyboard, and mouse behavior
|
- **CDP input behavior mimicking** — input events sent via CDP now produce the same signals as real user interactions. 5 new source-level patches covering pointer, keyboard, and mouse behavior
|
||||||
@@ -313,6 +313,17 @@ Supports all the same options as `launch_context()`: `proxy`, `user_agent`, `vie
|
|||||||
|
|
||||||
Async version: `launch_persistent_context_async()`.
|
Async version: `launch_persistent_context_async()`.
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
Pre-download the binary or check installation status from the command line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m cloakbrowser install # Download binary with progress output
|
||||||
|
python -m cloakbrowser info # Show version, path, platform
|
||||||
|
python -m cloakbrowser update # Check for and download newer binary
|
||||||
|
python -m cloakbrowser clear-cache # Remove cached binaries
|
||||||
|
```
|
||||||
|
|
||||||
### Utility Functions
|
### Utility Functions
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -706,6 +717,15 @@ COPY your_script.py /app/
|
|||||||
CMD ["python", "your_script.py"]
|
CMD ["python", "your_script.py"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Building your own image from pip** — use `python -m cloakbrowser install` to download the binary during build with visible progress:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
FROM python:3.12-slim
|
||||||
|
RUN pip install cloakbrowser && python -m cloakbrowser install
|
||||||
|
COPY your_script.py /app/
|
||||||
|
CMD ["python", "/app/your_script.py"]
|
||||||
|
```
|
||||||
|
|
||||||
**Building from source** — a [`Dockerfile`](Dockerfile) is also included if you prefer to build your own image:
|
**Building from source** — a [`Dockerfile`](Dockerfile) is also included if you prefer to build your own image:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -938,7 +958,7 @@ All releases are signed for supply chain verification.
|
|||||||
```bash
|
```bash
|
||||||
# Verify GPG signature (binary release tag)
|
# Verify GPG signature (binary release tag)
|
||||||
gpg --keyserver keyserver.ubuntu.com --recv-keys C60C0DDC9D0DE2DD
|
gpg --keyserver keyserver.ubuntu.com --recv-keys C60C0DDC9D0DE2DD
|
||||||
git verify-tag chromium-v145.0.7632.159.5
|
git verify-tag chromium-v145.0.7632.159.6
|
||||||
|
|
||||||
# Verify GitHub binary attestation (Sigstore)
|
# Verify GitHub binary attestation (Sigstore)
|
||||||
gh attestation verify cloakbrowser-linux-x64.tar.gz --repo CloakHQ/cloakbrowser
|
gh attestation verify cloakbrowser-linux-x64.tar.gz --repo CloakHQ/cloakbrowser
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
"""CLI for cloakbrowser — download and manage the stealth Chromium binary.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python -m cloakbrowser install # Download binary (with progress)
|
||||||
|
python -m cloakbrowser info # Show binary version, path, platform
|
||||||
|
python -m cloakbrowser update # Check for and download newer binary
|
||||||
|
python -m cloakbrowser clear-cache # Remove cached binaries
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_logging() -> None:
|
||||||
|
"""Route cloakbrowser logger to stderr with clean output."""
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(message)s",
|
||||||
|
stream=sys.stderr,
|
||||||
|
force=True,
|
||||||
|
)
|
||||||
|
# Suppress noisy HTTP request logs from httpx
|
||||||
|
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_install(args: argparse.Namespace) -> None:
|
||||||
|
from .download import ensure_binary
|
||||||
|
|
||||||
|
path = ensure_binary()
|
||||||
|
print(path)
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_info(args: argparse.Namespace) -> None:
|
||||||
|
from .config import get_local_binary_override
|
||||||
|
from .download import binary_info
|
||||||
|
|
||||||
|
info = binary_info()
|
||||||
|
override = get_local_binary_override()
|
||||||
|
|
||||||
|
print(f"Version: {info['version']}")
|
||||||
|
print(f"Platform: {info['platform']}")
|
||||||
|
print(f"Binary: {info['binary_path']}")
|
||||||
|
print(f"Installed: {info['installed']}")
|
||||||
|
print(f"Cache: {info['cache_dir']}")
|
||||||
|
if override:
|
||||||
|
print(f"Override: {override} (CLOAKBROWSER_BINARY_PATH)")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_update(args: argparse.Namespace) -> None:
|
||||||
|
from .download import check_for_update
|
||||||
|
|
||||||
|
logger = logging.getLogger("cloakbrowser")
|
||||||
|
logger.info("Checking for updates...")
|
||||||
|
new_version = check_for_update()
|
||||||
|
if new_version:
|
||||||
|
print(f"Updated to Chromium {new_version}")
|
||||||
|
else:
|
||||||
|
print("Already up to date.")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_clear_cache(args: argparse.Namespace) -> None:
|
||||||
|
from .config import get_cache_dir
|
||||||
|
from .download import clear_cache
|
||||||
|
|
||||||
|
if not get_cache_dir().exists():
|
||||||
|
print("No cache to clear.")
|
||||||
|
return
|
||||||
|
clear_cache()
|
||||||
|
print("Cache cleared.")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog="cloakbrowser",
|
||||||
|
description="Manage the CloakBrowser stealth Chromium binary.",
|
||||||
|
)
|
||||||
|
sub = parser.add_subparsers(dest="command")
|
||||||
|
|
||||||
|
sub.add_parser("install", help="Download the Chromium binary")
|
||||||
|
sub.add_parser("info", help="Show binary version, path, and platform")
|
||||||
|
sub.add_parser("update", help="Check for and download a newer binary")
|
||||||
|
sub.add_parser("clear-cache", help="Remove all cached binaries")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
if not args.command:
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
_setup_logging()
|
||||||
|
|
||||||
|
commands = {
|
||||||
|
"install": cmd_install,
|
||||||
|
"info": cmd_info,
|
||||||
|
"update": cmd_update,
|
||||||
|
"clear-cache": cmd_clear_cache,
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
commands[args.command](args)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit(130)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -1 +1 @@
|
|||||||
__version__ = "0.3.13"
|
__version__ = "0.3.14"
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ from ._version import __version__
|
|||||||
# CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
# CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
||||||
# Use get_chromium_version() for the current platform's actual version.
|
# Use get_chromium_version() for the current platform's actual version.
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
CHROMIUM_VERSION = "145.0.7632.159.5"
|
CHROMIUM_VERSION = "145.0.7632.159.6"
|
||||||
|
|
||||||
PLATFORM_CHROMIUM_VERSIONS: dict[str, str] = {
|
PLATFORM_CHROMIUM_VERSIONS: dict[str, str] = {
|
||||||
"linux-x64": "145.0.7632.159.5",
|
"linux-x64": "145.0.7632.159.6",
|
||||||
"darwin-arm64": "145.0.7632.109.2",
|
"darwin-arm64": "145.0.7632.109.2",
|
||||||
"darwin-x64": "145.0.7632.109.2",
|
"darwin-x64": "145.0.7632.109.2",
|
||||||
"windows-x64": "145.0.7632.109.2",
|
"windows-x64": "145.0.7632.109.2",
|
||||||
|
|||||||
@@ -133,6 +133,17 @@ const browser = await launch({ proxy: 'http://proxy:8080', geoip: true, timezone
|
|||||||
|
|
||||||
> **Note:** For rotating residential proxies, the DNS-resolved IP may differ from the exit IP. Pass explicit `timezone`/`locale` in those cases.
|
> **Note:** For rotating residential proxies, the DNS-resolved IP may differ from the exit IP. Pass explicit `timezone`/`locale` in those cases.
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
Pre-download the binary or check installation status from the command line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx cloakbrowser install # Download binary with progress output
|
||||||
|
npx cloakbrowser info # Show version, path, platform
|
||||||
|
npx cloakbrowser update # Check for and download newer binary
|
||||||
|
npx cloakbrowser clear-cache # Remove cached binaries
|
||||||
|
```
|
||||||
|
|
||||||
### Utilities
|
### Utilities
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cloakbrowser",
|
"name": "cloakbrowser",
|
||||||
"version": "0.3.13",
|
"version": "0.3.14",
|
||||||
"description": "Stealth Chromium that passes every bot detection test. Drop-in Playwright/Puppeteer replacement with source-level fingerprint patches.",
|
"description": "Stealth Chromium that passes every bot detection test. Drop-in Playwright/Puppeteer replacement with source-level fingerprint patches.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
"import": "./dist/puppeteer.js"
|
"import": "./dist/puppeteer.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"cloakbrowser": "./dist/cli.js"
|
||||||
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* CLI for cloakbrowser — download and manage the stealth Chromium binary.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* npx cloakbrowser install # Download binary (with progress)
|
||||||
|
* npx cloakbrowser info # Show binary version, path, platform
|
||||||
|
* npx cloakbrowser update # Check for and download newer binary
|
||||||
|
* npx cloakbrowser clear-cache # Remove cached binaries
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ensureBinary, binaryInfo, checkForUpdate, clearCache } from "./download.js";
|
||||||
|
import { getLocalBinaryOverride, getCacheDir } from "./config.js";
|
||||||
|
import fs from "node:fs";
|
||||||
|
|
||||||
|
const USAGE = `Usage: cloakbrowser <command>
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
install Download the Chromium binary
|
||||||
|
info Show binary version, path, and platform
|
||||||
|
update Check for and download a newer binary
|
||||||
|
clear-cache Remove all cached binaries`;
|
||||||
|
|
||||||
|
async function cmdInstall(): Promise<void> {
|
||||||
|
const binaryPath = await ensureBinary();
|
||||||
|
console.log(binaryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cmdInfo(): void {
|
||||||
|
const info = binaryInfo();
|
||||||
|
const override = getLocalBinaryOverride();
|
||||||
|
|
||||||
|
console.log(`Version: ${info.version}`);
|
||||||
|
console.log(`Platform: ${info.platform}`);
|
||||||
|
console.log(`Binary: ${info.binaryPath}`);
|
||||||
|
console.log(`Installed: ${info.installed}`);
|
||||||
|
console.log(`Cache: ${info.cacheDir}`);
|
||||||
|
if (override) {
|
||||||
|
console.log(`Override: ${override} (CLOAKBROWSER_BINARY_PATH)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cmdUpdate(): Promise<void> {
|
||||||
|
console.error("Checking for updates...");
|
||||||
|
const newVersion = await checkForUpdate();
|
||||||
|
if (newVersion) {
|
||||||
|
console.log(`Updated to Chromium ${newVersion}`);
|
||||||
|
} else {
|
||||||
|
console.log("Already up to date.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cmdClearCache(): void {
|
||||||
|
const cacheDir = getCacheDir();
|
||||||
|
if (!fs.existsSync(cacheDir)) {
|
||||||
|
console.log("No cache to clear.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearCache();
|
||||||
|
console.log("Cache cleared.");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main(): Promise<void> {
|
||||||
|
const command = process.argv[2];
|
||||||
|
|
||||||
|
if (!command || command === "--help" || command === "-h") {
|
||||||
|
console.log(USAGE);
|
||||||
|
process.exit(command ? 0 : 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (command) {
|
||||||
|
case "install":
|
||||||
|
await cmdInstall();
|
||||||
|
break;
|
||||||
|
case "info":
|
||||||
|
cmdInfo();
|
||||||
|
break;
|
||||||
|
case "update":
|
||||||
|
await cmdUpdate();
|
||||||
|
break;
|
||||||
|
case "clear-cache":
|
||||||
|
cmdClearCache();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Unknown command: ${command}\n`);
|
||||||
|
console.log(USAGE);
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
console.error(`Error: ${message}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
+2
-2
@@ -27,10 +27,10 @@ export { WRAPPER_VERSION };
|
|||||||
// CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
// CHROMIUM_VERSION is the latest across all platforms (for display/reference).
|
||||||
// Use getChromiumVersion() for the current platform's actual version.
|
// Use getChromiumVersion() for the current platform's actual version.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
export const CHROMIUM_VERSION = "145.0.7632.159.5";
|
export const CHROMIUM_VERSION = "145.0.7632.159.6";
|
||||||
|
|
||||||
export const PLATFORM_CHROMIUM_VERSIONS: Record<string, string> = {
|
export const PLATFORM_CHROMIUM_VERSIONS: Record<string, string> = {
|
||||||
"linux-x64": "145.0.7632.159.5",
|
"linux-x64": "145.0.7632.159.6",
|
||||||
"darwin-arm64": "145.0.7632.109.2",
|
"darwin-arm64": "145.0.7632.109.2",
|
||||||
"darwin-x64": "145.0.7632.109.2",
|
"darwin-x64": "145.0.7632.109.2",
|
||||||
"windows-x64": "145.0.7632.109.2",
|
"windows-x64": "145.0.7632.109.2",
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ geoip = ["geoip2>=4.0"]
|
|||||||
patchright = ["patchright>=1.40"]
|
patchright = ["patchright>=1.40"]
|
||||||
dev = ["pytest>=7.0", "pytest-asyncio>=0.23"]
|
dev = ["pytest>=7.0", "pytest-asyncio>=0.23"]
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
cloakbrowser = "cloakbrowser.__main__:main"
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Homepage = "https://github.com/CloakHQ/CloakBrowser"
|
Homepage = "https://github.com/CloakHQ/CloakBrowser"
|
||||||
Documentation = "https://github.com/CloakHQ/CloakBrowser#readme"
|
Documentation = "https://github.com/CloakHQ/CloakBrowser#readme"
|
||||||
|
|||||||
Reference in New Issue
Block a user