@mochi.js/core
Advanced tools
| /** | ||
| * Unit: `inferPlaceholderOsFromId` — pattern-match a profile id to the OS | ||
| * axis used by `synthesizePlaceholderProfile`. | ||
| * | ||
| * Regression guard for the "Linux profile forced on macOS / Windows" bug: | ||
| * pre-fix, `synthesizePlaceholderProfile` was unconditionally Linux. The | ||
| * 5 catalog ids without captured baselines (`mac-m2-`, `mac-m1-`, | ||
| * `mac-intel-`, `win11-`, `win11-edge-`) all silently produced a Linux | ||
| * UA + Linux `os.name` regardless of the id's implied platform. | ||
| */ | ||
| import { describe, expect, it } from "bun:test"; | ||
| import { inferPlaceholderOsFromId } from "../launch"; | ||
| describe("inferPlaceholderOsFromId", () => { | ||
| it("infers macOS for mac-* prefixes", () => { | ||
| expect(inferPlaceholderOsFromId("mac-m4-chrome-stable")).toBe("macos"); | ||
| expect(inferPlaceholderOsFromId("mac-m2-chrome-stable")).toBe("macos"); | ||
| expect(inferPlaceholderOsFromId("mac-m1-chrome-stable")).toBe("macos"); | ||
| expect(inferPlaceholderOsFromId("mac-intel-chrome-stable")).toBe("macos"); | ||
| expect(inferPlaceholderOsFromId("mac-chrome-stable")).toBe("macos"); | ||
| expect(inferPlaceholderOsFromId("mac-chrome-beta")).toBe("macos"); | ||
| expect(inferPlaceholderOsFromId("mac-brave-stable")).toBe("macos"); | ||
| }); | ||
| it("infers macOS for the legacy macos-* prefix", () => { | ||
| expect(inferPlaceholderOsFromId("macos-arm64")).toBe("macos"); | ||
| }); | ||
| it("infers Windows for win11-*, windows-*, win10-* prefixes", () => { | ||
| expect(inferPlaceholderOsFromId("win11-chrome-stable")).toBe("windows"); | ||
| expect(inferPlaceholderOsFromId("win11-edge-stable")).toBe("windows"); | ||
| expect(inferPlaceholderOsFromId("windows-chrome-stable")).toBe("windows"); | ||
| expect(inferPlaceholderOsFromId("win10-chrome-stable")).toBe("windows"); | ||
| }); | ||
| it("infers Linux for linux-* and the unknown-prefix fallback", () => { | ||
| expect(inferPlaceholderOsFromId("linux-chrome-stable")).toBe("linux"); | ||
| // Unknown prefix → linux fallback (preserves long-standing default). | ||
| expect(inferPlaceholderOsFromId("test-humanize")).toBe("linux"); | ||
| expect(inferPlaceholderOsFromId("custom-profile-xyz")).toBe("linux"); | ||
| expect(inferPlaceholderOsFromId("")).toBe("linux"); | ||
| }); | ||
| it("does NOT match `macarena` or other false-positive prefixes", () => { | ||
| // The hyphen requirement after `mac` rules out arbitrary words that | ||
| // happen to start with the same three letters. | ||
| expect(inferPlaceholderOsFromId("macarena-chrome")).toBe("linux"); | ||
| expect(inferPlaceholderOsFromId("machine-learning")).toBe("linux"); | ||
| }); | ||
| }); |
+1
-1
| { | ||
| "name": "@mochi.js/core", | ||
| "version": "0.9.1", | ||
| "version": "0.9.2", | ||
| "description": "The library for faithful browser automation. Bun-native; relational fingerprint matrix, biomechanical input, stock Chromium-for-Testing.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
+128
-1
@@ -653,2 +653,24 @@ /** | ||
| /** | ||
| * Pattern-match a profile id to the OS axis it implies. Used by | ||
| * {@link synthesizePlaceholderProfile} so a `mac-*` / `win11-*` id | ||
| * doesn't synthesize a Linux profile, which produced the "Linux profile | ||
| * forced on macOS / Windows" bug for the 5 catalog ids that lack a | ||
| * captured baseline (`mac-m2-`, `mac-m1-`, `mac-intel-`, `win11-`, | ||
| * `win11-edge-`). | ||
| * | ||
| * The mapping is conservative — anything that doesn't match a known | ||
| * prefix falls back to Linux to preserve the long-standing default. | ||
| * | ||
| * Exported as `@internal` for unit tests; not part of the public surface. | ||
| * | ||
| * @internal | ||
| */ | ||
| export function inferPlaceholderOsFromId(id: string): "macos" | "windows" | "linux" { | ||
| if (id.startsWith("mac-") || id.startsWith("macos-")) return "macos"; | ||
| if (id.startsWith("win11-") || id.startsWith("windows-") || id.startsWith("win10-")) | ||
| return "windows"; | ||
| return "linux"; | ||
| } | ||
| /** | ||
| * Synthesize a generic placeholder `ProfileV1` from a profile id, used as | ||
@@ -660,2 +682,10 @@ * a fallback when the catalog declares an id but no captured baseline | ||
| * | ||
| * The OS axis derives from the id (see {@link inferPlaceholderOsFromId}) | ||
| * so a `mac-*` or `win11-*` id never lands a Linux profile. Pre-fix: the | ||
| * placeholder was unconditionally Linux, which silently broke the 5 | ||
| * catalog ids that lack captured baselines (`mac-m2-`, `mac-m1-`, | ||
| * `mac-intel-`, `win11-`, `win11-edge-`). Users on macOS or Windows | ||
| * passing one of those ids saw a Linux UA against their host's actual | ||
| * Chromium-for-Testing binary — the canonical R-004 mismatch. | ||
| * | ||
| * The major version pinned here MUST track the live Chromium-for-Testing | ||
@@ -670,2 +700,99 @@ * pin (`packages/cli/src/browsers/manifest.ts:PINNED_FALLBACK_VERSION`) | ||
| function synthesizePlaceholderProfile(profile: ProfileId): ProfileV1 { | ||
| const os = inferPlaceholderOsFromId(profile); | ||
| // Per-OS skeletons — every field that varies by OS axis is bound here so | ||
| // the matrix the consistency engine produces stays self-coherent. | ||
| // (Display / audio / locale / behavior stay platform-neutral; the | ||
| // consistency DAG handles per-rule cross-references downstream.) | ||
| if (os === "macos") { | ||
| // arm64 is the modern default — Apple Silicon has been shipping since | ||
| // 2020 and the catalog's tip captures (mac-m4, mac-chrome-stable) are | ||
| // arm64. Intel Mac users should pass an inline ProfileV1 if they want | ||
| // strict x64 placement. | ||
| return { | ||
| id: profile, | ||
| version: "0.0.0-placeholder", | ||
| engine: "chromium", | ||
| browser: { name: "chrome", channel: "stable", minVersion: "148", maxVersion: "148" }, | ||
| os: { name: "macos", version: "14", arch: "arm64" }, | ||
| device: { | ||
| vendor: "Apple", | ||
| model: "Mac15,3", | ||
| cpuFamily: "apple-silicon-m3", | ||
| cores: 8, | ||
| memoryGB: 16, | ||
| }, | ||
| display: { width: 1728, height: 1117, dpr: 2, colorDepth: 30, pixelDepth: 30 }, | ||
| gpu: { | ||
| vendor: "Apple Inc.", | ||
| renderer: "Apple M3", | ||
| webglUnmaskedVendor: "Google Inc. (Apple)", | ||
| webglUnmaskedRenderer: "ANGLE (Apple, ANGLE Metal Renderer: Apple M3, Unspecified Version)", | ||
| webglMaxTextureSize: 16384, | ||
| webglMaxColorAttachments: 8, | ||
| webglExtensions: [], | ||
| }, | ||
| audio: { | ||
| contextSampleRate: 48000, | ||
| audioWorkletLatency: 0.005, | ||
| destinationMaxChannelCount: 2, | ||
| }, | ||
| fonts: { family: "macos-baseline", list: ["Helvetica"] }, | ||
| timezone: "America/Los_Angeles", | ||
| locale: "en-US", | ||
| languages: ["en-US", "en"], | ||
| behavior: { hand: "right", tremor: 0.18, wpm: 60, scrollStyle: "smooth" }, | ||
| wreqPreset: "chrome_148_macos", | ||
| userAgent: | ||
| "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36", | ||
| uaCh: {}, | ||
| entropyBudget: { fixed: [], perSeed: [] }, | ||
| }; | ||
| } | ||
| if (os === "windows") { | ||
| return { | ||
| id: profile, | ||
| version: "0.0.0-placeholder", | ||
| engine: "chromium", | ||
| browser: { name: "chrome", channel: "stable", minVersion: "148", maxVersion: "148" }, | ||
| os: { name: "windows", version: "11", arch: "x64" }, | ||
| device: { | ||
| vendor: "generic", | ||
| model: "generic-x64", | ||
| cpuFamily: "intel-core-i7", | ||
| cores: 8, | ||
| memoryGB: 16, | ||
| }, | ||
| display: { width: 1920, height: 1080, dpr: 1, colorDepth: 24, pixelDepth: 24 }, | ||
| gpu: { | ||
| vendor: "Google Inc. (Intel)", | ||
| renderer: | ||
| "ANGLE (Intel, Intel(R) UHD Graphics 770 (0x00004680) Direct3D11 vs_5_0 ps_5_0, D3D11)", | ||
| webglUnmaskedVendor: "Google Inc. (Intel)", | ||
| webglUnmaskedRenderer: | ||
| "ANGLE (Intel, Intel(R) UHD Graphics 770 (0x00004680) Direct3D11 vs_5_0 ps_5_0, D3D11)", | ||
| webglMaxTextureSize: 16384, | ||
| webglMaxColorAttachments: 8, | ||
| webglExtensions: [], | ||
| }, | ||
| audio: { | ||
| contextSampleRate: 48000, | ||
| audioWorkletLatency: 0.005, | ||
| destinationMaxChannelCount: 2, | ||
| }, | ||
| fonts: { family: "windows-baseline", list: ["Segoe UI"] }, | ||
| timezone: "America/New_York", | ||
| locale: "en-US", | ||
| languages: ["en-US", "en"], | ||
| behavior: { hand: "right", tremor: 0.18, wpm: 60, scrollStyle: "smooth" }, | ||
| wreqPreset: "chrome_148_windows", | ||
| userAgent: | ||
| "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36", | ||
| uaCh: {}, | ||
| entropyBudget: { fixed: [], perSeed: [] }, | ||
| }; | ||
| } | ||
| // Linux fallback (also catches anything that didn't match macos/windows). | ||
| return { | ||
@@ -703,3 +830,3 @@ id: profile, | ||
| // longer reads it — `Session.fetch` rides Chromium's network stack via | ||
| // CDP, so JA4 is real Chrome by definition. Drops in 0.8. | ||
| // CDP, so JA4 is real Chrome by definition. Drops in a future major. | ||
| wreqPreset: "chrome_148_linux", | ||
@@ -706,0 +833,0 @@ userAgent: |
+1
-1
| /** Single source of truth for the @mochi.js/core package version string. */ | ||
| export const VERSION = "0.9.0" as const; | ||
| export const VERSION = "0.9.1" as const; |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
555927
1.4%54
1.89%13575
1.25%