- Updated dependencies [dcf3dd2]
- @mochi.js/core@0.9.5
- Updated dependencies [7bd80bb]
- @mochi.js/consistency@0.1.5
- @mochi.js/behavioral@0.1.7
- @mochi.js/core@0.9.4
- @mochi.js/profiles@0.2.1
- Updated dependencies [8dd25a8]
- @mochi.js/core@0.9.3
- Updated dependencies [b0c5987]
- @mochi.js/core@0.9.2
- @mochi.js/core@0.9.1
- Updated dependencies [c8e2055]
- @mochi.js/core@0.9.0
- @mochi.js/behavioral@0.1.6
- Updated dependencies [080e418]
- @mochi.js/core@0.8.2
-
22b2a02: Wire real captured profile baselines into
mochi.launchand bump the placeholder + CfT pin to Chrome 148.The bug. Every user shipping a string
profile:got the hardcoded Chrome/131 placeholder UA against an installed Chromium-for-Testing v148. R-004's relational matrix dutifully emittedChrome/131.0.6778.110(canonical for the bogusminVersion: "131"the placeholder hardcoded), but the binary serving TLS, fonts, and media-device IDs is real Chromium 148. Fingerprint validators that compare the spoofed UA against the actual binary's behavior caught the mismatch.Three compounding causes, fixed in one pass.
@mochi.js/profiles.getProfile()was athrow new Error("not yet implemented")stub. The six captured baselines on disk underdata/<id>/profile.json(Chrome/146–147 UAs, Mac M4 / Mac Intel / Linux / Windows / mac-brave / mac-beta) were never read by the runtime. Now:getProfile(id)reads the capturedprofile.jsonviaBun.file(). New error classesUnknownProfileIdError(id outsideKNOWN_PROFILE_IDS) andProfileBaselineMissingError(id known but no baseline shipped yet) let callers distinguish the two failure modes.hasProfile(id)helper added.synthesizePlaceholderProfile()in@mochi.js/core/launch.tswas hardcodedminVersion: "131",Chrome/131.0.0.0UA. The launcher always called the placeholder for string ids, nevergetProfile(). Now: the launcher triesgetProfile(id)first and only falls back tosynthesizePlaceholderProfileonProfileBaselineMissingError(catalog ids without captures yet) or on truly unknown ids (with aconsole.warnso typos stay visible — preserves the pre-0.8 contract that any string id produces a working session, important for synthetic test-fixture ids). The placeholder itself bumps131 → 148.@mochi.js/consistency'sBROWSER_TIP_FULL_VERSIONtable topped out at"147"for chrome / edge / brave / arc. Now: adds"148": "148.0.7778.97"so R-004's tip-locked lookup resolves the new placeholder major to a real published patch.@mochi.js/cliPINNED_FALLBACK_VERSIONwas131.0.6778.85(very stale). Now:148.0.7778.97, the live CfT stable pin verified in manifest tests. Capture-flow defaults that hardcoded Chrome/131 inderive-profile.ts,capture/index.ts, andprovenance.tsJSDoc also bump to Chrome/148 so a freshmochi captureproduces a profile whose UA major matches the running binary.
Profile data fix —
linux-chrome-stable. The captured Linux baseline shipped with degraded GPU/display values that read as headless-server (SwiftShader) to Cloudflare Turnstile:gpu.renderer: "Generic Renderer",webglUnmaskedRenderer: "ANGLE (Generic)", 1280×800 display, 32 cores / 64GB, and asec-ch-uamissing the branded "Google Chrome" entry (only"Chromium";v="147"). Now: realistic Intel Iris Xe values (Intel Iris Xe Graphics/ANGLE (Intel Inc., Intel Iris Xe Graphics, OpenGL 4.1)), 1920×1080, 8 cores / 16GB, andsec-ch-ua: "Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"— empirically validated as passing FingerprintJS Pro (bot=notDetected) and Cloudflare Turnstile in the wild.Harness conformance — host-OS-matched profile + per-baseline asserts.
CONFORMANCE_PROFILEwas hardcoded tomac-m4-chrome-stablefor every host; this was silently masked pre-0.8 because the placeholder always returned a Linux profile regardless of id. Post-0.8 it loads the real Mac baseline on Linux CI, producing an OS mismatch that Cloudflare Turnstile catches. Now:CONFORMANCE_PROFILEresolves viadefaultProfileForHost()(same decision table the launcher uses) — Linux CI getslinux-chrome-stable, Mac dev getsmac-m4-chrome-stable, etc. The audio + canvas fingerprint conformance test loads expected byte-exact hashes from the host-matched profile'sbaseline.manifest.jsoninstead of hardcoding Mac M4's values, so it passes for any profile in the catalog with a captured baseline. -
Updated dependencies [22b2a02]
- @mochi.js/profiles@0.2.0
- @mochi.js/core@0.8.1
- @mochi.js/consistency@0.1.4
- @mochi.js/behavioral@0.1.5
- Updated dependencies [52b5a45]
- @mochi.js/core@0.8.0
- Updated dependencies [5705d38]
- Updated dependencies [d79b782]
- Updated dependencies [dd9a3c9]
- @mochi.js/core@0.6.0
- @mochi.js/consistency@0.1.3
- @mochi.js/profiles@0.1.1
- @mochi.js/behavioral@0.1.4
- Updated dependencies [60dac27]
- Updated dependencies [a92cebf]
- Updated dependencies [5cb8160]
- @mochi.js/core@0.4.0
- Updated dependencies [6761997]
- Updated dependencies [61ee52c]
- Updated dependencies [92b8a57]
- @mochi.js/profiles@0.1.0
- @mochi.js/core@0.3.0
- @mochi.js/consistency@0.1.2
- @mochi.js/behavioral@0.1.3
- Updated dependencies [92eda96]
- Updated dependencies [7cb4997]
- @mochi.js/core@0.2.2
- Updated dependencies [59d7b91]
- Updated dependencies [2855668]
- Updated dependencies [a7d8ca9]
- Updated dependencies [ddcc49e]
- Updated dependencies [ef00f63]
- @mochi.js/core@0.2.1
- Updated dependencies [be1c69b]
- Updated dependencies [4f1b81e]
- Updated dependencies [1231131]
- @mochi.js/core@0.2.0
- @mochi.js/consistency@0.1.1
- @mochi.js/behavioral@0.1.2
- @mochi.js/profiles@0.0.4
- Updated dependencies [707e42d]
- @mochi.js/core@0.1.2
-
7073097: Hot-fix v0.1.0's broken
workspace:*references in published package.json files. v0.1.0 leaked the Bun workspace protocol verbatim into published tarballs becausechangeset publish(which wrapsnpm publish) does NOT rewriteworkspace:*to concrete semver ranges — that's a pnpm/yarn courtesy npm doesn't replicate. As a result,bun add @mochi.js/core@0.1.0fails withWorkspace dependency not foundfor every internal dep (behavioral, consistency, inject, net), and the same for the 6 other packages with internal deps.The fix adds
scripts/rewrite-workspace-deps.tsas a publish-time pre-hook in the rootreleasescript. Pre-publish, everyworkspace:*inpackages/<name>/package.jsonis rewritten to^<sibling-version>resolved from the local workspace map. Bun's workspace links during dev still resolve via thenamefield, so concrete versions on disk between cycles don't break local development.Verified by
bun pack-ing the affected packages locally and inspecting the resulting tarball'spackage.jsondeps before pushing v0.1.1.@mochi.js/consistencyand@mochi.js/net-rsare leaf packages with no internal deps; they ship at v0.1.0/0.1.0 already and don't need a bump. -
Updated dependencies [7073097]
- @mochi.js/behavioral@0.1.1
- @mochi.js/core@0.1.1
- @mochi.js/profiles@0.0.3
-
c38d7aa: Phase 0.5 —
@mochi.js/harnessMVP +mochi harnesssubcommand.@mochi.js/harnessships the five public functions (capture,normalize,diff,categorize,report) and therunHarnessAgainstProfileorchestrator. Drives a Mochi-spoofed session throughtests/fixtures/probe-page.html, normalizes per-session entropy on both the captured manifest and the committed baseline, structurally diffs the two, and categorizes each divergence asguid-class|intentional|material. PR gate:counts.material === 0(PLAN.md §13.6).mochi harness <profile-id>+mochi harness allruns the harness from the CLI. Without--out, prints verdict + counts. With--out <dir>, writesreport.json+report.htmlfor each profile.- Per-profile
expected-divergences.jsonships atpackages/profiles/data/<id>/expected-divergences.json. Glob paths are categorized asintentional. Every entry has a human-readablecomment— phase-0.7-deferred surfaces (audio bytes, canvas hash, full WebGL extensions, full font lists, MediaDevices, SpeechSynthesis voices, etc.) are pre-populated formac-m4-chrome-stable. - Root
bun harness:smoke/bun harness:full/bun harness:diff <id>scripts replace the v0.0 echo placeholders. pr-fast.ymlgains a soft-failbun harness:smokestep. Hard-fail flips on at the end of phase 0.7.
-
f0c1a8a: Task 0150 — humanize conformance suite + supporting Page surface.
@mochi.js/harnessgains a new conformance suite undersrc/conformance/humanize/__tests__/— a mochi-native port of CloakHQ/CloakBrowser'stests/test_humanize_unit.mjs+tests/test_human_visual.mjs. Seven test files cover config resolution, Bezier math, mouse trajectory (E2E), keystroke timing, fill clearing (E2E), patching integrity, and (online,MOCHI_ONLINE=1) thedeviceandbrowserinfo.combot-detection form. Run viabun run conformance:humanize(offline) orbun run conformance:humanize:online.@mochi.js/coreships three Page-surface additions:Page.humanMove(x, y, opts?)— animate the cursor to (x, y) along a Bezier trajectory without dispatching a click. Same underlying synth ashumanClickminus the press/release.Page.cursorPosition()— read the tracked cursor (x, y) so sequences ofhumanMove/humanClickchain realistically.Page.humanType("", selector)— clearing semantics. Emits Backspace ×value.lengthwith realistic key timing instead of being a no-op as it was before.
- Companion correctness fix:
Input.dispatchKeyEventnow carries the propercode+windowsVirtualKeyCodefor control keys (Backspace/Enter/Tab/Escape/Delete) so Chromium fires the edit-action handler, not just the JS keydown event. Printable letters/digits/space also get plausibleKeyA/Digit0/Spacecodes for layout-aware page code. - Root scripts + CI gates wired:
bun run conformance:humanizeis a PR-fast hard-fail step.bun run conformance:humanizeis a release-pre-publish gate.
- Initial cursor position now defaults to the matrix's
display.width/2, display.height/2(PLAN.md I-5) instead of (0, 0) — a real human's pointer is never at the viewport origin.
-
74443f7: Phase 0.5.x — stealth conformance suite (port of CloakBrowser
tests/test_stealth.py).@mochi.js/harnessgains a newconformance/stealth/subtree. Layer 1 (webdriver-detection.test.ts) runs as the load-bearing PR-fast gate alongsidebun harness:smoke— six offline assertions ported verbatim from CloakBrowser'sTestWebDriverDetection:navigator.webdriver===false, noHeadlessChromeUA,typeof window.chrome === "object",navigator.plugins.length >= 5,navigator.languages.length >= 1, nocdc_*/__webdriver*window keys. Layer 2 (bot-detection-sites.test.ts) runs gated byMOCHI_ONLINE=1against bot.sannysoft, bot.incolumitas, browserscan, deviceandbrowserinfo, and demo.fingerprint.com/web-scraping. Three online tests carry typed expected-failure entries (incolumitas anti-debugger trap, sannysoft MQ_SCREEN, fingerprint.com IP-class blocking) — seedocs/limits.md.@mochi.js/injectgains two CloakBrowser-surfaced defensive shim modules:window-chrome.ts(mirrors Chrome'swindow.chromeshape withloadTimes/csi/apponly when the underlying browser doesn't already expose it;runtimeis intentionally undefined for non-extension contexts) andplugins.ts(curated 5-plugin PluginArray + 2-mimetype MimeTypeArray, matching themac-m4-chrome-stablebaseline; only installed when the underlying browser reports an empty list). Both shims no-op on real Chrome.app where the surfaces are native, so the existing harness Zero-Diff gate is unchanged at runtime.- New scripts:
bun conformance:stealth(Layer 1, PR-fast) andbun conformance:stealth:online(Layer 2, network-gated). Wired into.github/workflows/pr-fast.yml(Layer 1 hard-fail) and.github/workflows/release.yml(both layers gate publish). - Vendored upstream source:
tests/fixtures/cloakbrowser/test_stealth.py(sha-pinned to13b1b98b6840b68316e43fd46f43ffa7f50fd967).
-
4f09750: Initial v0.0.1 claim release with placeholder exports. Surface lands incrementally per PLAN.md §14.
-
ff75595: Land proxy authentication for HTTP / HTTPS / SOCKS5 / SOCKS4 proxies, wire the live
conformance:stealth:onlinegate to a residential proxy via theHTTP_PROXYrepo secret, and harden thebot.incolumitas.comtest against goto soft-fail timeouts.-
@mochi.js/coreships a newproxy-auth.tsthat attaches a CDPFetch.authRequiredlistener on session start when credentials are present, answering proxy auth challenges withFetch.continueWithAuth. No extension, noRuntime.enable, noPage.createIsolatedWorld— PLAN.md §8.2 invariants preserved (Fetch.enableis not on the forbidden list and produces no page-observable signals). The handler is wired with emptypatternsso regular request flow is unaffected; a defensiveFetch.requestPausedhandler short-circuits viaFetch.continueRequestif Chromium ever pauses a request despite the empty pattern set.Fetch.disableruns on session close.parseProxyUrl(url)is exported and handles the four protocols, with and without auth, percent-encoded credentials, IPv6 hosts, and missing ports (defaults: HTTP=80, HTTPS=443, SOCKS5/4=1080).LaunchOptions.proxyaccepts both the string form (http://user:pass@host:port) and theProxyConfigrecord shape; both feed the same auth path. Credentials are forwarded to the network FFI too, soSession.fetchshares the same authenticated egress as the browser. -
@mochi.js/harness—launchSharedSession()now readsMOCHI_PROXYand feeds it tomochi.launch({ proxy })when set. Empty / unset = unproxied (fork PRs without secrets still run cleanly). Thebot.incolumitas.comtest short-circuits to its registered expected-failure whenbestEffortGotoreportsnavigated: false, preventing the 12s sleep + 30s evaluate + worker-injection cascade from eating the 90s test budget. -
CI — both
release.yml(existing Layer 2 step) andpr-fast.yml(newly added Layer 2 step, gatedif: github.event_name == 'pull_request') now passMOCHI_PROXY: ${{ secrets.HTTP_PROXY }}so the live runs egress from a residential IP. The secret value is never echoed.
-
-
Updated dependencies [3fefd93]
-
Updated dependencies [e97c732]
-
Updated dependencies [5ea34c6]
-
Updated dependencies [29e1bb2]
-
Updated dependencies [f0c1a8a]
-
Updated dependencies [4f09750]
-
Updated dependencies [e7cc610]
-
Updated dependencies [ff75595]
- @mochi.js/behavioral@0.1.0
- @mochi.js/consistency@0.1.0
- @mochi.js/core@0.1.0
- @mochi.js/profiles@0.0.2