Commit Graph
100 Commits
Author SHA1 Message Date
CloakHQ 3c7f1ac843 fix(license): surface license exits on Puppeteer and .NET launch failures (#584)
Puppeteer reports a failed launch as 'Code: N' and .NET Playwright carries
no exit code at all, so an over-cap launch surfaced as a raw crash instead
of CloakBrowserLicenseError. Match Puppeteer's real wording and fall back
to the launch's denial file in the launch catch.
2026-10-11 00:33:49 +02:00
CloakHQ a2e77639d7 fix(humanize): select_option on emoji labels uses arrows; refuse on macOS
The dropdown search reads one UTF-16 unit per key and drops a surrogate, so
a typed emoji never moves it. The type-ahead plan no longer types one: Linux
and Windows reach such options with arrows. A macOS dropdown ignores arrows
too, so there the option raises a clear error before the popup opens.
The long-dropdown test now allows one input/change per letter on macOS.
2026-10-11 00:05:39 +02:00
CloakHQ 37d81bce9b release: v0.6.0 — unified humanize engine, persistent profile seeds, safe concurrent downloads 2026-10-08 20:51:59 +02:00
CloakHQ 89d2c27bad feat(proxy): warn when Playwright's request client skips the proxy (#579)
SOCKS5 and credentialed HTTP proxies are set on the browser, so
context.request / page.request / route.fetch() send from the real IP.
Warn once on first use (Python + JS) and document in-page fetch.
2026-10-08 20:19:34 +02:00
CloakHQ 15cb83e303 refactor(humanize): remove unused helpers and code left after #578 2026-10-08 19:53:08 +02:00
CloakHQ 3c842adc9f test: run real-browser tests against the real binary cache
Tests marked slow or real_browser skip the per-test temp cache and use
~/.cloakbrowser like a real install: the developer's key and latest
binary at a stable path. The temp cache re-downloaded the keyless
binary for every test under a new path, which path-keyed firewalls
re-prompt for. Unit tests stay isolated.
2026-10-08 08:30:49 +02:00
CloakHQ 5fb230d644 feat: persist the fingerprint seed per persistent profile
launch_persistent_context() now stores its seed in <user_data_dir>/.cloakbrowser-seed
on first launch and reuses it, so a profile keeps one identity across sessions.
Same file format in Python, JS and .NET. An explicit --fingerprint in args wins
and leaves the file alone; stealth_args=False skips it; non-persistent launches
stay random. Concurrent first launches publish without overwriting (link), so
they agree on one seed. Filesystems without hard links (FAT/exFAT, some network
mounts) fall back to an exclusive create, and an empty file is re-read briefly
as in-progress. A corrupt file is logged and regenerated.
2026-10-08 05:00:29 +02:00
CloakHQ 58eead89d2 feat(js): support CommonJS require() via a default export condition
Exports used only "import", so require('cloakbrowser') failed with ERR_PACKAGE_PATH_NOT_EXPORTED. A "default" condition lets Node's built-in require(esm) load all three subpaths. engines raised to ^20.19.0 || >=22.12.0, where require(esm) is on by default.
2026-10-08 02:39:23 +02:00
CloakHQ a7a6c1913f fix(js): write download and GeoIP status lines to stderr, not stdout
Stdout status lines corrupted MCP stdio servers and any caller parsing stdout on first run. Matches the banner, Python, and .NET. Tests assert nothing reaches stdout.
2026-10-08 02:37:19 +02:00
CloakHQ a2172a3607 docs: credit @dstosch for cloakserve idle cleanup (#558), ignore agent/ 2026-10-07 23:39:16 +02:00
CloakHQ 5fa65172f0 docs: Pro Stable is now Chromium 154 on every platform
README versions, test date, and pin examples moved to 154.0.8037.57.1; Pro banner names v154; CHANGELOG [Unreleased].
2026-10-06 20:09:34 +02:00
CloakHQ faffd76f7b test(js): zero random delays in the SecurePass humanType test to stop CI timeouts 2026-10-04 23:55:39 +02:00
CloakHQ 1c867a7046 release: v0.5.12 — humanize x-axis scroll-into-view, digit-safe typos on number inputs 2026-10-04 20:15:16 +02:00
CloakHQ 0739ca5324 fix(humanize): keep digit mistypes on digits (#573)
A letter typo on a digit is rejected by <input type=number>, so the
correcting Backspace deleted the previous real digit (1999 -> 999).
Digit neighbors are now digit-only in the Python, JS (Playwright +
Puppeteer) and .NET wrappers.
2026-10-04 19:42:07 +02:00
CloakHQ f44864b6ed ci: run JS tests on Node 22 (vitest 5 engine requirement) 2026-09-29 23:28:36 +02:00
CloakHQ 0e43a341ef fix(humanize): tolerate sub-pixel box edges in the scroll-into-view pinned check
Layout can report a top edge of -1/64 px on an unscrolled page, which skipped
the pinned-at-top check and sent a pointless upward scroll burst before the
click. Allow 1px slack in Python, JS and .NET, with regression tests.

Also credit @Shub3am in README contributors (#554).
2026-09-29 23:05:00 +02:00
CloakHQ 9bc5e374d7 release: v0.5.11 — Pro banner v152, macOS font check in info, direct archive unpack, .NET #549 fix 2026-09-25 00:03:16 +02:00
CloakHQ 9639bba2dc docs(readme): Chromium 152.0.7977.82.1 stable on Linux and Windows; bump Pro major banner to 152 2026-09-23 20:47:42 +02:00
CloakHQ 11c76ebe75 fix(dotnet): unwrap HumanizedLocator for Playwright APIs that down-cast ILocator (#549)
Under humanize, page.GetByText(...) returns our HumanizedLocator decorator. Playwright
APIs that internally down-cast an ILocator arg to the concrete Locator (as Locator)
threw NullReferenceException on it. Unwrap to the raw locator before delegating, matching
the existing DragTo/Or/And/SelectOption pattern.

Covers AddLocatorHandlerAsync (both overloads, callback re-wrapped), RemoveLocatorHandlerAsync,
Locator.Filter (Has/HasNot), and Page/ElementHandle ScreenshotAsync (Mask). Also adds
HumanizedLocator to LicenseGuard.Unwrap and a public Humanize.Unwrap(ILocator) escape hatch.
Python/JS unaffected (they monkey-patch in place, no wrapper type).
2026-09-18 19:48:08 +02:00
CloakHQ ba6e2c5e3b docs(readme): Chromium 151.0.7922.108.6 stable, 87 patches, macOS persona + new flags
- Pro Stable to 151.0.7922.108.6 (Linux + Windows); macOS on 151.0.7922.108.3
- Patch count to 87; platform tables to Chromium 151 across all rows
- Document macOS persona and --fingerprint-transparent-proxy / --fingerprint-portable-cookies
- Font Setup: add Mac fonts block and Docker (/usr/local/share/fonts) paths
2026-09-12 19:12:56 +02:00
CloakHQ 5010f99556 refactor(download): unpack verified archives directly
The download is signature/checksum-verified before extraction, so the
per-member path/symlink sanitization was redundant. Extract archives as-is
across all three wrappers (Python, JS, .NET), tar and zip.

- Python: filter="fully_trusted" (pins legacy behavior; 3.14 defaults to
  "data"), plain zip extractall
- JS: drop the tar filter callback; inline the one-line extractTar
- .NET: TarFile/ZipFile.ExtractToDirectory; remove orphan ResolveSafeEntryPath
- Drop the obsolete traversal/symlink tests
2026-09-10 23:58:58 +02:00
CloakHQ f0c0eedb2f feat(info): report macOS persona font completeness
Add a Mac fonts count to `cloakbrowser info` next to the existing Windows
font check, in the Python, JS, and .NET wrappers. Counts the macOS core
font set via fc-list on Linux and prints Mac fonts: n/20 with a conditional
nudge when incomplete. Tests added in all three wrappers.
2026-09-10 20:55:42 +02:00
CloakHQ f04c23da28 release: v0.5.10 — Windows console banner + geoip/license launch-abort fixes 2026-08-30 05:53:19 +02:00
CloakHQ bb6f2f00e4 fix(wrapper): ASCII-safe welcome banner for legacy Windows consoles
The banner wrote '->' and em dashes straight to stderr. On a cp1252/strict
console (UK/EU-locale Windows) that raised UnicodeEncodeError and aborted the
binary-download path, blocking license apply and profile launch in the Manager.

Swap the banner glyphs to ASCII and route the writes through a swallow-all
helper so a cosmetic banner can never abort a launch. Same treatment in the JS
and .NET wrappers plus the Windows-font warning. Regression tests added across
all three (ASCII-only + cp1252-no-crash).
2026-08-28 21:00:28 +02:00
CloakHQ d6bad5de26 fix(geoip): abort launch when resolution fails
Increase the default GeoIP resolution timeout from 5 to 20 seconds across the Python, JavaScript, and .NET wrappers.

Fail the launch when requested GeoIP resolution times out, cannot load its database, cannot complete a lookup, or leaves timezone or locale unresolved. Explicit timezone and locale overrides remain valid without an egress-IP result.

Add parity coverage for the new timeout and failure behavior.
2026-08-28 02:20:04 +02:00
CloakHQ 8fb3350dd1 fix(license): abort on invalid or unvalidatable key instead of silent free fallback
A supplied license key the server rejects, or one that cannot be validated
(server unreachable, no cache), now raises instead of silently downloading the
free binary. No-key (keyless) and valid-key (Pro) paths unchanged. Python, JS,
and .NET, with mirror tests in each.
2026-08-27 00:22:05 +02:00
CloakHQ 0811704e7f release: v0.5.9 — humanize selector fixes + info seat reporting 2026-08-25 16:16:33 +02:00
CloakHQ a853517e4c fix(test): run the .NET resolver check from a script file
The test inlines the resolver once per builder call, so adding the selector
engines took the script past 110 KB. Linux caps a single argv entry at
MAX_ARG_STRLEN (128 KB), so "node -e <script>" failed with E2BIG on CI while
passing on macOS, which allows a larger argument.

Write the script to a temp file and pass the path instead, which has no size
ceiling.
2026-08-25 01:48:35 +02:00
CloakHQ 1164eca332 fix(humanize): restore get_by_* selectors and harden isolated-world reads
Removing the Playwright fallback closed a main-world read leak but left every
get_by_* locator raising UnsupportedHumanizeSelectorError. Reimplement the four
cheap engines in the isolated-world resolver so those locators work again.

Selector engines (shared resolver, byte-identical in all three wrappers):
- internal:testid and internal:attr (placeholder/alt/title). The i flag is a
  case-insensitive substring on the raw attribute value; test ids stay strict.
- internal:text. Exact compares the full normalized subtree text, unlike the
  public text= engine which compares immediate fragments.
- internal:label, resolving aria-labelledby, then aria-label, then .labels.
- internal:role and >> chaining stay unsupported; the error now names what is
  supported and the workaround.

Text parity fixes in __elementText, checked against playwright-core:
- drop a <br> to newline branch Playwright does not have
- concatenate shadow-root text into the host, which Playwright does
- give the public text= engine Playwright's self/selfAndChildren rule, since
  contains() cannot see into a shadow root and kept the host as a match

Target identity: payloads carry a per-world generation (protocol v2). The world
is rebuilt on navigation and its id counter restarts, so an id alone could name
a different element. Generation is bounded to Int32, which the .NET wrapper
requires.

force=True now skips the pointer check entirely, matching Playwright, instead of
suppressing only the coverage rejection.

Also: drop dead _BOX_OP, _ACTIONABLE_OP and readSnapshot, and add a test
asserting the three hand-copied resolver literals stay identical and free of
characters that would terminate their host string literals.

Verified against Playwright's own locator resolution in a real browser:
20/20 engine parity, 7/7 text parity.
2026-08-25 01:48:35 +02:00
CloakHQ f7ca311516 fix(humanize): support display contents targets
Derive actionable geometry from rendered text and visible descendants when an element has no box of its own. Preserve existing geometry behavior for normal elements and exclude hidden descendant content. Add Python, JavaScript, and .NET unit and browser regressions covering text, nested content, visibility, and humanized clicks.
2026-08-25 01:48:35 +02:00
CloakHQ 2496cf35e3 fix(dotnet): align humanized selector behavior
Port the proven selector resolution and actionability behavior to the .NET wrapper.

- preserve exact targets across delayed interactions
- align supported locator semantics and legacy fallbacks
- add regression coverage for ordering, mutation races, and scrolling
2026-08-25 01:48:35 +02:00
CloakHQ f12e47d657 fix(js): align humanized selector behavior
Port the proven Python interaction behavior to the JavaScript wrapper.

- align selector resolution and actionability semantics
- preserve exact targets across delayed interactions
- improve text, state, and open shadow tree consistency
- add regression coverage for ordering, mutation races, and force behavior
2026-08-25 01:48:34 +02:00
CloakHQ 89b2ac0021 Match Playwright ordering across Shadow DOM
Collect light-DOM matches before recursively merging open Shadow Root
matches, preserving Playwright order for broad selectors using first or nth.

Add resolver and real-browser coverage for mixed and nested Shadow Roots.
2026-08-25 01:48:34 +02:00
CloakHQ 5c82b2fa54 Fix humanized selector resolution and actionability
Resolve #512 by ignoring non-rendered document content during text
matching and selecting the same visible target as Playwright.

Improve text, structural, selector-list, and open shadow-root handling.
Align element state checks and forced-click behavior, and prevent pointer
dispatch when the original target is detached or replaced during mouse
movement.

Add sync, async, and real-browser regression coverage.
2026-08-25 01:48:34 +02:00
CloakHQ b90c6702fe fix(banner): bump PRO_MAJOR to 151 2026-08-24 03:37:46 +02:00
CloakHQ fac70ae84f docs: add CloakBrowser Manager section to README
Self-hosted profile manager, placed after the Pro section so the shared-key
story lands. Links to the site instead of pinning installer versions here.
2026-08-22 17:34:11 +02:00
CloakHQ 7b08984976 build(docker): declare fonts-urw-base35 explicitly
The image already ships these fonts, but only as a transitive dependency of
openbox (openbox -> libimlib2 -> libspectre -> libgs10 -> fonts-urw-base35).
They are what Verdana, Georgia, Trebuchet MS and Tahoma fall back to; without
them fontconfig resolves those families to the CJK font instead of a Latin one.

Listing the package directly means a future change to the window manager or
X stack cannot silently drop the Latin fallback. No runtime change.
2026-08-21 23:39:37 +02:00
CloakHQ c2421da06d feat(info): report session seats as used/limit with real failure reasons
`cloakbrowser info` printed a bare seat count with no denominator, so a
customer could not tell whether they were at capacity (#513). It also
collapsed six distinct outcomes into one "unavailable": unreachable,
timeout, invalid key, inactive licence, rate limited, and the server
reporting the count as unknown while degraded.

Adds SessionSeats (active, limit, state, reason) and getSessionSeats to
all three wrappers; get_active_session_count keeps its signature and
delegates. The limit is read from the server, never derived from the plan
name, and falls back to the old bare count when absent.

Python, JS and .NET renderers verified byte-identical.
2026-08-21 20:22:48 +02:00
CloakHQ be75a9b9e4 docs: clarify cloakserve CDP session cleanup 2026-08-20 23:07:57 +02:00
CloakHQ d30572f070 fix(license): store denial path on persistent context before guard install
Persist _cloak_denial_path on the context object in
launch_persistent_context_async so the license guard has access to the
denial path after installation.
2026-08-19 22:21:47 +02:00
CloakHQ 0f375a3ab6 docs(readme): Chromium 151 now Stable on Linux + Windows 2026-08-18 21:33:20 +02:00
CloakHQ 2e5d493416 release: v0.5.8 — humanize post-nav, selectOption, and scroll fixes 2026-08-18 20:25:57 +02:00
CloakHQ a91d105d4d fix(humanize): refresh pre-action element checks after click/form navigation (#507)
Humanized actions could fail with an element-not-attached error after a
navigation driven by a click or form submit, since the checks only refreshed
on goto. Now refresh on any main-frame navigation. Python, JS
Playwright/Puppeteer, and .NET. Regression from 0.5.6.
2026-08-17 21:00:02 +02:00
CloakHQ 5494ac14e9 fix(humanize): skip futile scroll for fully-visible boundary elements
A fully-visible element above/below the target zone on a page pinned at
that boundary can never reach the zone, so the scroll loop ran the full
budget (~7s/click) doing nothing. Bail when it's fully visible and the
page can't scroll toward the zone. Ported to JS, Python (sync+async),
and .NET with regression tests.
2026-08-14 08:42:30 +02:00
CloakHQ b27ccd9eae fix(humanize): stop selectOption infinite recursion in JS wrapper
page.selectOption re-dispatches to the main frame's selectOption, which
patchSingleFrame routes back to page.selectOption. Binding the saved
original to the page looped forever; bind it to the main frame's native
method instead. Adds a regression test.
2026-08-14 04:43:48 +02:00
CloakHQ 2488311072 docs(release): promote Chromium 150.0.7871.114.6 2026-08-11 04:57:00 +02:00
CloakHQ 289c8205b6 release: v0.5.7 — humanize input fixes 2026-08-11 04:14:02 +02:00
CloakHQ ec88026723 fix(humanize): humanize frames nested below the first level
_iter_frames / iterFrames only walked the main frame and its direct
children, so a frame nested 2+ levels deep that already existed when
patching ran was never humanized. The frameattached listener covers
frames added after patching, so this only affected pre-existing deep
frames (e.g. manual patch_page/patch_context on a loaded page).

Recurse the full frame tree; the _human_patched guard keeps it
idempotent. Python + JS; .NET wraps frames lazily and is unaffected.
2026-08-08 18:33:42 +02:00
CloakHQ 2442c32478 fix(humanize): preserve keyboard press timing
Forward caller-provided press delays through humanized page, frame, locator, element handle, and keyboard paths across Python, JavaScript, and .NET.

Use each automation library's native press operation for shortcut chords while retaining the existing humanized pre-press timing and focus behavior.
2026-08-08 01:47:24 +02:00
CloakHQ caf21e9e51 release: v0.5.6 — humanize stealth fixes 2026-08-08 00:12:48 +02:00
CloakHQ faf6a68689 refactor(humanize): route pre-click element reads through the isolated world (.NET)
Ports the Python/JS stealth_dom fix to the .NET wrapper. Add StealthDom.cs:
reimplements the common Playwright selector grammar (css, :has-text, text=,
xpath=, trailing >> nth=N) for direct DOM resolution in the isolated execution
context, with a fallback to the regular Playwright read for unsupported grammar.
World reads are wrapped so a world/CDP failure falls back rather than propagating.

The pre-click actionability, scroll geometry, viewport, and pointer-events reads
now go through it. .NET hooks the humanized click at the locator layer with no
selector string, so page.Locator(selector) now threads the selector into
LocatorHumanizer, whose reads use the isolated world when the selector is known
(else Playwright). HumanPage's selector path is wired the same way. GetBy*/chained
locators fall back to Playwright; ElementHandle and sub-frame paths unchanged.

Tests: StealthDom builders + a Node-driven check of the shipped resolver JS
selector semantics (byte-identical to the other wrappers), and a guard that
page.Locator(selector) threads the selector into the humanized locator.
2026-08-07 23:49:56 +02:00
CloakHQ 9fa247231b refactor(humanize): route pre-click element reads through a shared DOM helper
Python + JS wrappers. Add a stealth_dom / stealthDom module: reimplements the
common Playwright selector grammar (css, :has-text, text=, xpath=, trailing
>> nth=N) for direct DOM resolution in the isolated execution context, with a
fallback to the regular Playwright read for grammar it can't resolve. World
reads are wrapped so a world/CDP failure falls back rather than propagating out
of the humanized action.

ensure_actionable, ensure_stable, scroll geometry (_get_element_box + the
no_viewport window-size read), and check_pointer_events now read through it,
sync and async. Selector-based main-page actions (click/dblclick/hover/type/
fill/focus/press) are covered; ElementHandle and sub-frame paths unchanged.

JS routes Locator actions through frame methods, so main-frame locator clicks
now delegate to the humanized page methods (which use the shared helpers)
instead of the frame-scoped Playwright reads; sub-frames unchanged.

Tests: builders + parse, the rewired helpers' branching via a mock isolated
world, a Node-driven check of the shipped resolver JS selector semantics, and a
guard that main-frame locator clicks delegate to the humanized page path.
2026-08-07 23:17:59 +02:00
CloakHQ 7f19b2fc0e fix(humanize): preserve behavior in dynamic frames
- humanize frames created after page load across Python and JavaScript\n- keep sync, async, Playwright, and Puppeteer paths idempotent\n- wrap .NET frame lifecycle event payloads without raw frame leaks\n- add cross-wrapper unit and browser regression coverage
2026-08-07 19:52:03 +02:00
CloakHQ 679122c2b6 fix(dotnet): unwrap page/frame args so NewCDPSessionAsync works through wrappers
context.NewCDPSessionAsync(page) threw NullReferenceException for any licensed
.NET user: Playwright down-casts the IPage/IFrame argument to its concrete
Page/Frame to read .Guid, which fails on the CloakBrowser proxy the wrapper
returns. The license-guard proxy (all licensed launches) and the humanize
decorator both produced a handle that fails that cast.

- guard proxy unwraps page/frame/handle arguments before forwarding, keeps
  page.Context guarded, and Wrap() is idempotent
- HumanizedBrowserContext.NewCDPSessionAsync unwraps its argument (covers the
  keyless+humanize path with no guard proxy)
- HumanizedPage.Context re-wraps so page.Context stays humanized
- public Humanize.Unwrap(page/frame) escape hatch
- regression tests build the guard proxy and assert the inner receives raw
2026-08-07 01:39:06 +02:00
CloakHQ c1dd58902a release: v0.5.5 — info --proxy geoip resolution + Python 3.14 humanize fix 2026-08-05 17:35:33 +02:00
CloakHQ 9021e0c07f feat(cli): info --proxy resolves exit IP + timezone + locale
Wire the existing launch()-time geoip resolver into the info/doctor command
across Python, JS, and .NET. With --proxy, info resolves the exit IP and the
timezone/locale a launch would apply (caching the GeoIP DB if absent) and prints
them in text and --json. Plain info is unchanged (no network) and now hints at
the flag. Adds diagnostics tests in all three suites.
2026-08-05 17:32:33 +02:00
CloakHQ f9d73d0cb8 fix(license): guard wrapper no longer breaks humanize on Python 3.14
The license guard stored each wrapped method as a functools.partial,
relying on it not being a descriptor. Python 3.14 made partial a method
descriptor, so when humanize reads the wrapped methods off a holder
instance the partial re-binds and injects a spurious positional arg —
every humanized page call raised TypeError on first use. Replace the
partial with a non-descriptor callable class. Fixes #488.
2026-08-05 16:41:16 +02:00
CloakHQ e4d4c680c9 fix(humanize): re-scroll after the settle wait so clicks land
An element scrolled into view can be pushed off screen again while we wait
for a reflowing page to settle. Nothing scrolled a second time, so the click
was dispatched outside the viewport and hit nothing, with no error raised.

Also stop the pointer-events check from turning a confirmed miss back into
'undetermined' when a late probe times out, which let that click through.

Measured on a page reflowing 10-25s: silent miss at ~32s before, clean click
now. Static pages and pages reflowing past the timeout are unchanged.
2026-08-05 16:29:07 +02:00
CloakHQ 3ceca98caf release: v0.5.4 — surface post-handshake license denials as CloakBrowserLicenseError 2026-08-04 20:59:47 +02:00
CloakHQ ed389e4435 docs(readme): copy whole Windows Fonts folder, not just *.ttf
A *.ttf glob skips .ttc collections like msgothic.ttc (MS UI Gothic),
one of the fonts the launch font-set warning requires (issue #480).
2026-08-04 15:42:22 +02:00
CloakHQ 75292ed474 feat(license): surface post-handshake license denials as CloakBrowserLicenseError
A concurrent-session denial resolves after the CDP handshake, so the browser
exits with a live connection already established. The launch-failure path never
sees it and the user gets a bare TargetClosedError on their first call (#477).

The binary records the license exit code (76-79) to a per-launch file whose path
the wrapper passes via CLOAKBROWSER_LICENSE_STATUS_FILE. The wrapper reads it
when a guarded call throws and re-raises the correct CloakBrowserLicenseError.
Discrimination is on the file, not the error type, so a genuine crash is never
mislabelled. Fail-safe (no key or unwritable dir -> feature off) and
backward-compatible (old binaries never write the file).

Guarded surfaces: new_page/new_context, a persistent context's already-open
pages (goto + the wait family), and Puppeteer user-created contexts. Orphaned
denial files are swept at mint time; an observed code is cached in-process so a
concurrent second call can't miss it; the .NET reader parses as tolerantly as
Python/JS.

Implemented across Python, JavaScript (Playwright + Puppeteer), and .NET, with
unit tests. Reproduced end-to-end with a real over-cap denial.
2026-08-01 08:26:12 +02:00
CloakHQ c2513a3c23 docs(readme): drop stale --fingerprint-fonts-dir flag 2026-07-31 18:26:51 +02:00
CloakHQ 9d978fd7c3 docs(readme): reframe Linux Windows fonts as recommended, not optional
The Windows OS fonts were labeled optional/CreepJS-only, but Linux
defaults to the Windows persona, so their absence is a font-fingerprint
tell. List the exact fonts the launch warning checks and add a verify
step (issue #480).
2026-07-31 17:21:43 +02:00
CloakHQ 59406d807c release: v0.5.3 — Windows font profile feature set + proxy identity and Windows CLI fixes 2026-07-30 03:13:56 +02:00
CloakHQ 7f78805b06 fix(args): align feature set with stock Chrome for the Windows font profile
Playwright's launch defaults switch off a feature stock Chrome ships enabled.
When the Windows font-metrics profile is requested, re-enable it so the feature
set matches a real browser rather than a test harness. Merged into any existing
--enable-features value instead of appending a second flag.

Python, JS and .NET wrappers.
2026-07-29 01:09:36 +02:00
CloakHQ 35f5eb9408 fix(js): resolve each launch's proxy exit IP independently
Node pools HTTPS connections by destination, so a second launch() in the
same process reused the first proxy's tunnel to the echo service and
inherited its exit IP, timezone and locale.
2026-07-28 23:49:22 +02:00
CloakHQ ec1ea4cef3 docs: drop removed --fingerprint-location from the flag table 2026-07-27 17:05:55 +02:00
CloakHQ d07cab1376 docs: changelog + contributor for HTTP proxy credential fix (#470) 2026-07-27 15:35:50 +02:00
CloakHQ 093a664601 fix(cli): keep info readable on a legacy Windows console
cmd.exe defaults to cp850/cp1252, which carry no check mark or arrow.
Printing one raised UnicodeEncodeError and aborted the report at the
Launch line, so everything after it was lost — including on the success
path, once the launch probe stopped failing.

Marks now degrade to plain text per glyph when the console cannot
encode them. UTF-8 consoles (Linux, macOS, Windows Terminal) keep the
original output byte for byte.

.NET substitutes rather than throwing here (verified on the reference
box), so only the Python wrapper needed the change.
2026-07-26 20:18:11 +02:00
CloakHQ 42924aaf99 fix(cli): don't report a false launch failure in info on Windows
Chromium only handles --version on POSIX, so on Windows the switch is
ignored and a browser starts instead of printing. The 10s probe then
timed out and a healthy install was reported as broken, flashing a
window on screen each run.

Probe with --no-startup-window there: it exits immediately, opens no
window, and a broken binary still exits non-zero. No version is
reported on Windows, as nothing is printed. Linux and macOS unchanged.

Test uses a stub that hangs unless the flag is passed, mirroring the
real binary rather than a print-and-exit stub.
2026-07-26 19:27:53 +02:00
CloakHQ a5f2c33ff9 release: v0.5.2 — preview release channel + Chromium 150.0.7871.114.4 (Linux) 2026-07-25 08:35:34 +02:00
CloakHQ 240bf61bec feat(cli): print the wrapper version in info across all wrappers 2026-07-25 00:53:09 +02:00
CloakHQ 69a168ae0a test: isolate Python/JS suites from the real ~/.cloakbrowser
A license.key or cached Pro marker in the developer's cache dir resolved the
box as Pro, flipping version-gated defaults (headless no_viewport, inline proxy
auth) and failing 9 Python + 4 JS tests locally. Both suites now run against a
temp cache dir.
2026-07-24 19:52:07 +02:00
CloakHQ f709dba519 feat: add preview release channel across all wrappers
Add a preview release channel system to all wrappers (Python, JavaScript, .NET),
allowing users to opt into newer binary builds before they go stable.

- Python: preview/stable channel resolution in download, launch, CLI
  (install, update, clear-cache), and license validation
- JavaScript: preview/stable channel in CLI, launch, license, and config
- .NET: preview/stable channel in CLI, license, diagnostics, and config
- All wrappers: channel fallback indicator, auto-update gate,
  CLOAKBROWSER_RELEASE_CHANNEL env var support
- Harden channel resolution: reuse the resolution sidecar on offline lookups,
  defensive marker/JSON parsing, atomic version-marker writes, a launch-time
  preview-to-stable fallback notice, channel-aware info download URL, and
  Python/JS/.NET parity for the fallback default
- Binary 150.0.7871.114.4 changelog (Linux x64 + arm64)
- Updated READMEs, CHANGELOG, and tests for all wrappers
2026-07-24 11:47:28 +02:00
CloakHQ c6673e3eda feat(cloakserve): on-demand close endpoint (POST /fingerprint/{seed}/close)
Adds ChromePool.terminate_seed() + a close route that tears down one seed's
Chrome immediately and frees its slot, instead of waiting out the idle timeout.
Profile is preserved (goes through _cleanup_process). Idempotent.
2026-07-23 03:57:42 +02:00
CloakHQ 36390b5359 release: v0.5.1 — geoip CONNECT Host header fix (js) 2026-07-23 03:36:36 +02:00
CloakHQ d640970d4a fix(geoip): send tunnel target in CONNECT Host header (js)
Node derives Host from the proxy hostname unless set explicitly; strict
backconnect proxies reject the mismatch, silently falling back to the
gateway's geo instead of the real exit IP.
2026-07-23 03:31:16 +02:00
CloakHQ efe6f503a0 release: v0.5.0 — free tier via GitHub sign-in + geoip raw-flag fix 2026-07-22 22:20:03 +02:00
CloakHQ 1b1e349815 feat(free-tier): GitHub-login free tier across all three wrappers
cloakbrowser login gets a free key via GitHub sign-in (or saves a paid key); logout reverts. Launch banner and info are now tier-aware (keyless / free / pro). A free key drops any version pin so it always gets the latest build (server force-serves latest; a pinned manifest would fail checksum). Python, JS, and .NET kept in sync. README documents the free tier + commands.
2026-07-22 22:02:09 +02:00
CloakHQ 0c2d19183a fix(geoip): preserve explicit tz/locale raw flags in args over geoip
A raw --fingerprint-timezone/--lang/--fingerprint-locale in args is now
promoted to an explicit value in maybe_resolve_geoip, so geoip only fills
the values the user did not set. Mirrors the timezone=/locale= param path.
Python, JS, and .NET, with tests.
2026-07-22 07:38:15 +02:00
CloakHQ a554a97b24 release: v0.4.13 — geoip DB refresh fix + drop 7-day trial copy 2026-07-22 04:10:39 +02:00
CloakHQ b90e249793 fix(geoip): quote cloakbrowser[geoip] in user-facing error messages
zsh globs the unquoted bracket, so a user copy-pasting the printed
install hint hits a shell error. Quote it in both messages; update the
test that pinned the old string.
2026-07-22 03:34:24 +02:00
CloakHQ d290c2ac57 fix(geoip): atomic DB replace + single-download guard (#458)
geoip.py used Path.rename which cannot overwrite on Windows, so a stale
DB never refreshed and every launch re-downloaded ~70 MB in a loop. No
lock meant concurrent launches each fired their own download.

- Python: os.replace + threading.Lock (initial + background paths)
- .NET: File.Move(overwrite) + SemaphoreSlim guard
- JS: shared in-flight promise (rename already overwrites)
- tests: overwrite + concurrent single-download coverage

pyproject: bump classifier to Production/Stable
2026-07-22 03:15:35 +02:00
CloakHQ fd2b6024c6 release: v0.4.12 — Chromium 150 version facts + banner fix
Points the READMEs at 150 as the latest Pro binary (71 patches, all five
platforms) and bumps the Pro major in the launch banner and the info
upgrade hint across Python, JS, and .NET.
2026-07-18 23:30:16 +02:00
CloakHQ 86d1d76b81 release: v0.4.11 — proxy auth + license errors + info session count 2026-07-16 12:51:16 +02:00
CloakHQ d2a72f1238 feat(cli): show active session count in info
A Pro license now gets a "Sessions: N seats in use" line, answering
"how many sessions do I have running?" without asking support.

Never cached (a cached count is a wrong count), skipped under --quick to
keep `info` network-free, and prints "unavailable" rather than a made-up
number when the count cannot be determined.

Python, JS and .NET.
2026-07-15 06:02:17 +02:00
CloakHQ ca232fd598 feat(license): surface Pro binary license failures as clear errors
The Pro binary exits with a distinct code per license failure; the wrappers ignored it, so a user got a bare "browser closed" error with no reason.

Add CloakBrowserLicenseError plus a launch-error parser that maps the exit code to a clear message, mirrored across the Python, JS, and .NET wrappers. Non-license failures pass through unchanged.
2026-07-15 01:22:13 +02:00
CloakHQ 2e379e402b docs: update BINARY-LICENSE to v1.3
Discretionary refusal/revocation, fair-use throttle, trial-abuse ban
(stacking paid subs explicitly allowed), suspend pending investigation,
self-amendment clause. Acceptable Use + Indemnification party lists
aligned with Disclaimer/Limitation of Liability.
2026-07-14 23:53:09 +02:00
CloakHQ 111b725e8c Fix authenticated HTTP proxies across all platforms
Route authenticated HTTP/HTTPS proxies through the browser's native proxy
authentication only on binaries that support it, resolved per platform and
binary version via a capability gate (sibling to the existing viewport and
window-geometry gates). Older binaries, including the free macOS and ARM
builds, fall back to the standard Playwright proxy path instead of emitting
credentials the binary cannot parse, so authenticated proxies keep working on
macOS and ARM instead of silently failing. Applied across the Python,
JavaScript, Puppeteer, and .NET wrappers.
2026-07-11 02:11:08 +02:00
CloakHQ 08415d9b26 release: v0.4.10 — iframe humanize + JS CLI npx fixes (#427, #428) 2026-07-09 23:21:52 +02:00
CloakHQ 3c3e0f477c docs: update BINARY-LICENSE to v1.2 (version-agnostic terms, pricing and key clauses) 2026-07-09 23:09:25 +02:00
CloakHQ 1ae7605a43 fix: humanize=True resolves iframe locators in the owning frame (#428)
With humanize=True, Locator/frame actions on an element inside an iframe
(frame.locator("#btn").click(), fill(), hover(), the frame.click(...)
equivalents) raised ElementNotAttachedError because the humanize layer
resolved every selector against the main frame. Route sub-frame locators
and frame-level actions through the owning frame's own document, keeping
humanized mouse motion inside the iframe; native fallback when the box
can't be read or the frame is detached. Python only (JS and .NET were
already frame-correct).

Adds mocked routing unit tests (sub-frame -> owning frame, main-frame ->
page, unpatched -> native), the human_click arg-order + _frame_fill
fallback guards, and @slow real-binary iframe integration tests.
2026-07-09 20:36:24 +02:00
CloakHQ 045219b488 fix: JS CLI silently exited via npx/symlinked bin (#427)
Entry-point guard compared import.meta.url to an unresolved process.argv[1];
Node resolves import.meta.url through symlinks but argv[1] stays as invoked,
so npm/pnpm/npx bin symlinks never matched and no subcommand ran. Realpath
the invoked path before comparing.
2026-07-09 03:40:40 +02:00
CloakHQ 0624df83fc release: v0.4.9 — Pro trial promo, info/update version parity, font check fixes 2026-07-09 03:10:53 +02:00
CloakHQ 0664bd8d0c feat: promote 7-day Pro trial in banner, CLI hint, and READMEs
Free-tier launch banner and 'cloakbrowser info' upgrade hint now advertise
the 7-day free Pro trial (Chromium 148) across Python, JS, and .NET; same
CTA added to both READMEs. Also surface binary verification failures verbatim
instead of falling back to a cached build (transient-only fallback).
2026-07-08 22:13:34 +02:00
CloakHQ a00bccac78 fix: info/update never diverge from the Pro build that actually launches
info now shows the cached build that will launch AND the server's latest
Pro version on separate lines, so the two can no longer silently diverge
(a customer saw info report latest while launch ran a stale cache).

- Pro version resolution: unpinned launch prefers the server latest when it
  is newer than or replaces a missing cached build, else stays on cache;
  advances the version marker so info and later offline launches match.
- update command is license-aware: a valid Pro key updates the Pro binary,
  everyone else updates free.
- Replace the fire-and-forget Pro background update thread with a foreground
  rate-limited check (one network call/hour), honoring CLOAKBROWSER_AUTO_UPDATE=false.
- A valid Pro license never falls back to the free binary: get_effective_version
  returns None when no Pro build is cached; resolution fails loudly instead.
- Tampering signal (BinaryVerificationError) surfaces verbatim on the unpinned
  upgrade path — the cached-Pro fallback is only for transient download failures.
- get_effective_version(pro) requires the binary be executable, so info can't
  report a build launch would reject.
- info --quick stays network-free (skips the server latest lookup); prints a
  'not downloaded yet' line instead of 'None' when offline with no cache.
- Align the JS .last_update_check marker to seconds (Python/.NET parity).
- Mirror across Python, JS, and .NET wrappers; add update/CLI tests.
2026-07-08 18:57:38 +02:00
CloakHQ ae7fd43be7 feat: info/doctor reports Windows + Office font completeness
Windows font check now covers the full 8-font set (adds the two monospace
fonts) and reports a strict N/8 count; the launch-time warning fires on any
incomplete set, not just when none are present. Adds a separate Office-font
group (10 fonts) reported as an informational N/10 with no install nudge.

Ported across all three wrappers (Python, JS, .NET) to keep them in sync.
2026-07-07 21:58:01 +02:00
CloakHQ 5a1e2978e4 docs: add 215.5 binary changelog entry + license-through-proxy 'for now' note 2026-07-05 22:10:52 +02:00
CloakHQ 330d7b851e release: v0.4.8 — geoip works proxy-free (132 locales) + maximized window + flag docs 2026-07-05 21:32:31 +02:00
CloakHQ 01c6105128 fix: harden geoip proxy-free + maximize parity (review follow-ups)
Follow-up fixes for the geoip-no-proxy and start-maximized commits:

- geoip: resolve the egress IP before the DB check so a DB-download failure
  still yields the WebRTC exit IP — the proxy WebRTC spoof survives a DB hiccup
- geoip: skip the exit-IP echo call on no-proxy + explicit tz/locale (the WebRTC
  IP would just be the real connection IP the site already sees — a no-op)
- launch_context: suppress auto --start-maximized when the caller set an explicit
  viewport, matching JS across Python and .NET
- docker: poll for X readiness before starting openbox instead of a blind sleep
  (avoids a silent window-manager startup race)
- refactor: extract the WebRTC exit-IP append into one helper per wrapper
- remove a dead isPrivateIp in the JS wrapper
- tests: fix stale no-proxy geoip assertions; add launch_context parity + .NET
  geoip coverage

Python, JS and .NET wrappers kept in parity.
2026-07-04 23:21:20 +02:00