device-passport 1.1.0 → 1.2.0

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +10 -7
  2. package/README.md +41 -0
  3. package/assets/ego-profile-manager.png +0 -0
  4. package/dist/adapters/index.cjs +2 -2
  5. package/dist/adapters/index.d.cts +4 -94
  6. package/dist/adapters/index.d.mts +4 -94
  7. package/dist/adapters/index.d.ts +4 -94
  8. package/dist/adapters/index.mjs +2 -2
  9. package/dist/ego/index.cjs +22 -0
  10. package/dist/ego/index.d.cts +5 -0
  11. package/dist/ego/index.d.mts +5 -0
  12. package/dist/ego/index.d.ts +5 -0
  13. package/dist/ego/index.mjs +8 -0
  14. package/dist/evaluator/index.cjs +22 -584
  15. package/dist/evaluator/index.mjs +3 -564
  16. package/dist/geo/index.cjs +1 -1
  17. package/dist/geo/index.d.cts +4 -0
  18. package/dist/geo/index.d.mts +4 -0
  19. package/dist/geo/index.d.ts +4 -0
  20. package/dist/geo/index.mjs +2 -2
  21. package/dist/index.cjs +41 -441
  22. package/dist/index.d.cts +10 -198
  23. package/dist/index.d.mts +10 -198
  24. package/dist/index.d.ts +10 -198
  25. package/dist/index.mjs +7 -418
  26. package/dist/shared/device-passport.BGfRcQNh.mjs +565 -0
  27. package/dist/shared/{device-passport.BPd2-w8e.cjs → device-passport.BKtmLzPt.cjs} +4 -3
  28. package/dist/shared/{device-passport.BBf9OKap.mjs → device-passport.BPQj0qdT.mjs} +4 -3
  29. package/dist/shared/device-passport.CDS7xrj8.d.ts +469 -0
  30. package/dist/shared/device-passport.CfLes-lq.d.cts +469 -0
  31. package/dist/shared/device-passport.CsOWqPIr.d.cts +77 -0
  32. package/dist/shared/device-passport.D7pEnyp2.d.ts +77 -0
  33. package/dist/shared/{device-passport.CLaBZWUV.cjs → device-passport.D9xW6R0B.cjs} +4 -2
  34. package/dist/shared/device-passport.DirQmSd4.d.cts +47 -0
  35. package/dist/shared/device-passport.DirQmSd4.d.mts +47 -0
  36. package/dist/shared/device-passport.DirQmSd4.d.ts +47 -0
  37. package/dist/shared/device-passport.EK4RX7Xd.cjs +584 -0
  38. package/dist/shared/device-passport.ZBspe4ZW.d.mts +77 -0
  39. package/dist/shared/device-passport.dVEqzSEb.d.mts +469 -0
  40. package/dist/shared/{device-passport.NHw_f6HT.mjs → device-passport.gNo82fQ5.mjs} +5 -3
  41. package/dist/shared/device-passport.kekU28UM.mjs +705 -0
  42. package/dist/shared/device-passport.qL4tjwc0.cjs +718 -0
  43. package/dist/storage/index.d.cts +3 -34
  44. package/dist/storage/index.d.mts +3 -34
  45. package/dist/storage/index.d.ts +3 -34
  46. package/dist/types/index.d.cts +183 -1
  47. package/dist/types/index.d.mts +183 -1
  48. package/dist/types/index.d.ts +183 -1
  49. package/package.json +6 -1
package/CHANGELOG.md CHANGED
@@ -5,21 +5,24 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.2.0] - 2026-11-14
9
+
10
+ ### Added
11
+ - **ego-lite account profile layer** (`device-passport/ego`): `AccountProfileManager` maps one account (seed) onto a sticky passport, an ego-lite profile binding and a proxy declaration. It lists the profiles ego-lite already has (there is no create-profile API), binds an account to one of them, and produces a complete launch plan — ordered CDP commands, init scripts, canonical headers, the `profileId`, and the proxy declaration. The proxy is modelled as a declared *gap*, not a feature: ego-lite has no browser-level proxy API (CDP has no `Browser.setProxySettings`, `--proxy-server` is a launch flag rather than a CDP command, and the native bindings expose no proxy setter), so a profile reports `ready` only when a proxy is declared and `missing-proxy` otherwise, and every plan repeats `proxy.bound` / `proxy.resolution === 'system-level'` so an unbound proxy can never be mistaken for an effective one. The proxy must be bound outside the browser (OS proxy / TUN / local forwarder). The passports are persisted with the same durability as the account records, so a restart cannot silently regenerate a persona with a different geo context while keeping the same passport id.
12
+ - **`passportStore` option on `AccountProfileManager`**: account records and personas are two different kinds of state. Persisting only the records left the persona living in memory, so a restart regenerated it from the default geo — the identity drifted while its `id` stayed the same and no caller could tell. The option makes the persona survive a restart for real, and `createSessionPlan()` now aligns the persona's geo context with the declared proxy country so the browser's claimed country and the traffic's exit country cannot diverge.
13
+ - **`EgoSessionPlan` now extends `CdpPassportPlan`**: re-declaring `commands` / `initScripts` / `headers` let the two shapes drift apart and silently dropped `stealthScript` from the plan. The plan also carries its `sessionId` on the init script itself, so a caller that sends `plan.initScripts` directly cannot drop it.
14
+ - **Single source for the profile id**: the session plan takes the profile id from the persisted account record only. Accepting a caller-supplied profile id as well let the plan's profile id and its readiness disagree, and a session could be launched under a profile that was never validated.
15
+
8
16
  ## [1.1.0] - 2026-11-04
9
17
 
10
- > ⚠️ 发布受阻说明:本版本代码已合并并打好 tag,但 **npm 发布尚未完成** ——
11
- > `device-passport` 在 npmjs.com 上没有配置 Trusted Publisher 信任关系。
12
- > 证据:`device-passport@1.0.0` 没有 OIDC attestation(对比 `im-notify-kit@0.4.1` 有),
13
- > 说明该包从未成功走通 OIDC 通道;workflow 里的 `id-token: write` 只是必要条件,
14
- > 不是充分条件。需要在 npmjs.com → Packages → device-passport → Settings →
15
- > Trusted Publisher 里登记:GitHub Actions / 组织 `webkubor` / 仓库 `device-passport` /
16
- > 工作流 `publish.yml`,并允许 `npm publish`。登记后 2 天内需完成首次发布,否则配置过期。
17
18
 
18
19
  ### Added
19
20
  - **Pixel-level protection**: `getStealthScript()` now appends a deterministic noise layer that patches `canvas.toDataURL()`, `getImageData()`, `gl.readPixels()` and the audio analyser, so read-back no longer exposes the host GPU or a shared hash across personas. The noise is derived from the passport seed — stable per account, distinct per account — and uses discrete quantization levels rather than per-pixel dithering, because a smooth ±1 RGB jitter is itself a fingerprint.
20
21
  - **Raw CDP adapter**: `getCdpPlan()` and `applyCdpPassport()` emit an ordered, transport-agnostic Chrome DevTools Protocol command plan for tools that speak bare CDP (e.g. `lite-browser`'s `cdp` channel). Covers headers, `Emulation.setUserAgentOverride` with Client-Hints metadata, timezone, locale, device metrics, touch emulation and init-script installation.
21
22
 
22
23
  ### Fixed
24
+ - **Type-check baseline was red**: `bun run lint` failed on a clean checkout — `toGeoLocation()` dereferenced the optional `GeoContext.coordinates`, and `createPassport()` called the synchronous storage helpers that the `StorageAdapter` interface never declared. The sync capability is now declared on the interface as optional, and `toGeoLocation()` falls back to the country's representative coordinates so an emulated geolocation can never contradict the country/timezone pairing.
25
+ - **`tsconfig.json` rejected by modern TypeScript**: the deprecated `baseUrl` option (unused — the `@/*` alias has no importers) broke `tsc --noEmit` on TypeScript 6, and node globals were unresolvable because `types` was never declared. Both are fixed, so the lint gate passes on TypeScript 5 and 6 alike.
23
26
  - **Canvas serialization recursion**: the temporary canvas used for re-serialization shares the patched prototype, so calling its `toDataURL` recursed until the stack limit. Serialization now uses the captured original method (verified with 25 repeated calls in real Chromium).
24
27
  - **WebGL canvases leaked the real framebuffer through `toDataURL()`**: a canvas with a WebGL context returns `null` from `getContext('2d')`, so that path silently skipped protection. Pixel perturbation now runs through `gl.readPixels` for such canvases.
25
28
  - **Alpha bytes were perturbed**: RGBA alpha now stays untouched, so transparent and opaque pixels keep their semantics (masks and hit-testing unaffected).
package/README.md CHANGED
@@ -377,6 +377,47 @@ const fleetSnapshot = await manager.exportAll();
377
377
 
378
378
  ---
379
379
 
380
+ ## ego-lite Account Profiles (`AccountProfileManager`)
381
+
382
+ ![device-passport ego-lite account profile manager — real run output](assets/ego-profile-manager.png)
383
+
384
+ When the browser is [ego-lite](https://github.com/citrolabs/ego-lite), one account maps to three things that must travel together: a sticky passport, an ego-lite **profile** binding (cookies and login state persist per profile), and a **proxy declaration**.
385
+
386
+ ```typescript
387
+ import { AccountProfileManager } from 'device-passport/ego';
388
+
389
+ const manager = new AccountProfileManager({
390
+ store: './data/accounts.json', // atomic JSON persistence
391
+ // bridge: egoLiteBridge, // optional; inject ego-lite's native bridge
392
+ });
393
+
394
+ // List the profiles ego-lite already has — there is no create-profile API.
395
+ const profiles = await manager.listEgoProfiles(); // [{ id, name, isDefault }]
396
+
397
+ // Bind one account (seed) to one profile and declare its proxy.
398
+ await manager.bindProfile('account_9041', {
399
+ profileId: 'Profile 2',
400
+ proxy: { url: 'http://user-jp:pass@gate.example.com:7000', description: 'Tokyo residential exit', country: 'JP' },
401
+ });
402
+
403
+ // The complete launch plan: CDP commands, init scripts, headers, profileId, proxy declaration.
404
+ const plan = await manager.createSessionPlan('account_9041');
405
+ plan.readiness; // 'ready' | 'missing-proxy' | 'missing-profile'
406
+ plan.launchable; // true only when a proxy is declared
407
+ ```
408
+
409
+ ### ⚠️ The proxy gap, stated plainly
410
+
411
+ **ego-lite cannot configure a proxy at the browser layer, and neither can this library.**
412
+
413
+ - CDP has no `Browser.setProxySettings` — Chromium has never shipped one.
414
+ - `--proxy-server` is a browser **launch** flag on the process, not a CDP command; it cannot be changed after the profile is running.
415
+ - ego-lite's native bindings expose no proxy setter either.
416
+
417
+ A proxy is therefore bound **outside the browser**: at the OS level (system proxy / TUN / transparent redirect), or by routing the ego-lite process through a local forwarder that owns the upstream proxy. This layer refuses to fake it: an account profile is `ready` only when a proxy is **declared**, `missing-proxy` otherwise, and every session plan repeats that state (`plan.proxy.bound`, `plan.proxy.resolution === 'system-level'`) so an unbound proxy can never be mistaken for an effective one.
418
+
419
+ ---
420
+
380
421
  ## Self-Diagnostic Coherence Evaluation
381
422
 
382
423
  Verify any passport or raw external request headers against the theoretical coherence framework:
Binary file
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const cdp = require('../shared/device-passport.CLaBZWUV.cjs');
3
+ const cdp = require('../shared/device-passport.D9xW6R0B.cjs');
4
4
  require('node:crypto');
5
- require('../shared/device-passport.BPd2-w8e.cjs');
5
+ require('../shared/device-passport.BKtmLzPt.cjs');
6
6
 
7
7
 
8
8
 
@@ -1,4 +1,5 @@
1
- import { DevicePassport } from '../types/index.cjs';
1
+ import { DevicePassport, CdpCommand, CdpPassportPlan } from '../types/index.cjs';
2
+ export { P as PlaywrightContextOptions, a as PuppeteerEmulationOptions, b as applyToPlaywrightContext, c as applyToPuppeteerPage, g as getPlaywrightContext, d as getPuppeteerArgs, e as getStealthScript } from '../shared/device-passport.CsOWqPIr.cjs';
2
3
  import '../shared/device-passport.C_F1vBE8.cjs';
3
4
 
4
5
  /**
@@ -34,79 +35,6 @@ declare function toCurl(passport: PassportLike | DevicePassport, url: string, op
34
35
  headers?: Record<string, string>;
35
36
  }): string;
36
37
 
37
- interface PlaywrightContextOptions {
38
- userAgent: string;
39
- viewport: {
40
- width: number;
41
- height: number;
42
- };
43
- deviceScaleFactor: number;
44
- locale: string;
45
- timezoneId: string;
46
- geolocation?: {
47
- latitude: number;
48
- longitude: number;
49
- accuracy?: number;
50
- };
51
- permissions?: string[];
52
- extraHTTPHeaders: Record<string, string>;
53
- hasTouch: boolean;
54
- isMobile: boolean;
55
- colorScheme?: 'light' | 'dark' | 'no-preference';
56
- }
57
- /**
58
- * Builds Playwright BrowserContext options directly from a DevicePassport.
59
- * Ready for `browser.newContext(getPlaywrightContext(passport))`.
60
- */
61
- declare function getPlaywrightContext(passport: DevicePassport): PlaywrightContextOptions;
62
- /**
63
- * Generates an in-page stealth script to patch runtime JavaScript APIs
64
- * (navigator.webdriver, hardwareConcurrency, deviceMemory, WebGL unmasked vendor/renderer,
65
- * navigator.userAgentData Client Hints, and Screen dimensions).
66
- *
67
- * 🔴 API-level spoofing is not enough on its own: `canvas.toDataURL()` and `gl.readPixels()`
68
- * still return the **real** framebuffer, so a headless browser exposes SwiftShader while
69
- * its UA claims a discrete GPU — and every persona on one machine hashes identically.
70
- * The pixel-protection script is therefore appended here, so existing users get
71
- * read-back-safe personas without changing their call sites.
72
- *
73
- * The noise is seeded from the passport seed: stable per account, different per account.
74
- */
75
- declare function getStealthScript(passport: DevicePassport): string;
76
- /**
77
- * Applies stealth injections and extra headers to a Playwright BrowserContext.
78
- *
79
- * @param context Playwright BrowserContext instance
80
- * @param passport DevicePassport instance
81
- */
82
- declare function applyToPlaywrightContext(context: any, passport: DevicePassport): Promise<void>;
83
-
84
- interface PuppeteerEmulationOptions {
85
- launchArgs: string[];
86
- defaultViewport: {
87
- width: number;
88
- height: number;
89
- deviceScaleFactor: number;
90
- isMobile: boolean;
91
- hasTouch: boolean;
92
- };
93
- userAgent: string;
94
- locale: string;
95
- timezoneId: string;
96
- extraHTTPHeaders: Record<string, string>;
97
- }
98
- /**
99
- * Returns Puppeteer launch args and page emulation parameters matching the DevicePassport.
100
- */
101
- declare function getPuppeteerArgs(passport: DevicePassport): PuppeteerEmulationOptions;
102
- /**
103
- * Applies stealth injections, headers, viewport, and timezone emulation to a Puppeteer Page.
104
- *
105
- * @param page Puppeteer Page instance
106
- * @param passport DevicePassport instance
107
- */
108
- declare function applyToPuppeteerPage(page: any, passport: DevicePassport): Promise<void>;
109
-
110
38
  /**
111
39
  * Raw Chrome DevTools Protocol adapter.
112
40
  *
@@ -120,24 +48,6 @@ declare function applyToPuppeteerPage(page: any, passport: DevicePassport): Prom
120
48
  * applies every command in order. The caller owns the transport, so this module has no
121
49
  * dependency and works over WebSocket, stdio, or an in-process socket.
122
50
  */
123
- interface CdpCommand {
124
- method: string;
125
- params?: Record<string, unknown>;
126
- /** `sessionId` is required for page-scoped domains when using flattened sessions. */
127
- sessionId?: string;
128
- }
129
- interface CdpPassportPlan {
130
- /** Ordered commands to apply the passport to a target. */
131
- commands: CdpCommand[];
132
- /** Init scripts to install on every new document. */
133
- initScripts: {
134
- source: string;
135
- }[];
136
- /** Extra HTTP headers to set on the session. */
137
- headers: Record<string, string>;
138
- /** The raw stealth + pixel-protection script, for callers that prefer their own path. */
139
- stealthScript: string;
140
- }
141
51
  /**
142
52
  * Builds the ordered CDP command plan for a passport.
143
53
  *
@@ -152,5 +62,5 @@ declare function getCdpPlan(passport: DevicePassport, sessionId?: string): CdpPa
152
62
  */
153
63
  declare function applyCdpPassport(passport: DevicePassport, send: (command: CdpCommand) => Promise<unknown>, sessionId?: string): Promise<void>;
154
64
 
155
- export { CANONICAL_HEADER_ORDER, applyCdpPassport, applyToPlaywrightContext, applyToPuppeteerPage, formatCanonicalHeaders, getCdpPlan, getPlaywrightContext, getPuppeteerArgs, getStealthScript, toCurl, withPassport };
156
- export type { CdpCommand, CdpPassportPlan, PassportLike, PlaywrightContextOptions, PuppeteerEmulationOptions };
65
+ export { CANONICAL_HEADER_ORDER, applyCdpPassport, formatCanonicalHeaders, getCdpPlan, toCurl, withPassport };
66
+ export type { PassportLike };
@@ -1,4 +1,5 @@
1
- import { DevicePassport } from '../types/index.mjs';
1
+ import { DevicePassport, CdpCommand, CdpPassportPlan } from '../types/index.mjs';
2
+ export { P as PlaywrightContextOptions, a as PuppeteerEmulationOptions, b as applyToPlaywrightContext, c as applyToPuppeteerPage, g as getPlaywrightContext, d as getPuppeteerArgs, e as getStealthScript } from '../shared/device-passport.ZBspe4ZW.mjs';
2
3
  import '../shared/device-passport.C_F1vBE8.mjs';
3
4
 
4
5
  /**
@@ -34,79 +35,6 @@ declare function toCurl(passport: PassportLike | DevicePassport, url: string, op
34
35
  headers?: Record<string, string>;
35
36
  }): string;
36
37
 
37
- interface PlaywrightContextOptions {
38
- userAgent: string;
39
- viewport: {
40
- width: number;
41
- height: number;
42
- };
43
- deviceScaleFactor: number;
44
- locale: string;
45
- timezoneId: string;
46
- geolocation?: {
47
- latitude: number;
48
- longitude: number;
49
- accuracy?: number;
50
- };
51
- permissions?: string[];
52
- extraHTTPHeaders: Record<string, string>;
53
- hasTouch: boolean;
54
- isMobile: boolean;
55
- colorScheme?: 'light' | 'dark' | 'no-preference';
56
- }
57
- /**
58
- * Builds Playwright BrowserContext options directly from a DevicePassport.
59
- * Ready for `browser.newContext(getPlaywrightContext(passport))`.
60
- */
61
- declare function getPlaywrightContext(passport: DevicePassport): PlaywrightContextOptions;
62
- /**
63
- * Generates an in-page stealth script to patch runtime JavaScript APIs
64
- * (navigator.webdriver, hardwareConcurrency, deviceMemory, WebGL unmasked vendor/renderer,
65
- * navigator.userAgentData Client Hints, and Screen dimensions).
66
- *
67
- * 🔴 API-level spoofing is not enough on its own: `canvas.toDataURL()` and `gl.readPixels()`
68
- * still return the **real** framebuffer, so a headless browser exposes SwiftShader while
69
- * its UA claims a discrete GPU — and every persona on one machine hashes identically.
70
- * The pixel-protection script is therefore appended here, so existing users get
71
- * read-back-safe personas without changing their call sites.
72
- *
73
- * The noise is seeded from the passport seed: stable per account, different per account.
74
- */
75
- declare function getStealthScript(passport: DevicePassport): string;
76
- /**
77
- * Applies stealth injections and extra headers to a Playwright BrowserContext.
78
- *
79
- * @param context Playwright BrowserContext instance
80
- * @param passport DevicePassport instance
81
- */
82
- declare function applyToPlaywrightContext(context: any, passport: DevicePassport): Promise<void>;
83
-
84
- interface PuppeteerEmulationOptions {
85
- launchArgs: string[];
86
- defaultViewport: {
87
- width: number;
88
- height: number;
89
- deviceScaleFactor: number;
90
- isMobile: boolean;
91
- hasTouch: boolean;
92
- };
93
- userAgent: string;
94
- locale: string;
95
- timezoneId: string;
96
- extraHTTPHeaders: Record<string, string>;
97
- }
98
- /**
99
- * Returns Puppeteer launch args and page emulation parameters matching the DevicePassport.
100
- */
101
- declare function getPuppeteerArgs(passport: DevicePassport): PuppeteerEmulationOptions;
102
- /**
103
- * Applies stealth injections, headers, viewport, and timezone emulation to a Puppeteer Page.
104
- *
105
- * @param page Puppeteer Page instance
106
- * @param passport DevicePassport instance
107
- */
108
- declare function applyToPuppeteerPage(page: any, passport: DevicePassport): Promise<void>;
109
-
110
38
  /**
111
39
  * Raw Chrome DevTools Protocol adapter.
112
40
  *
@@ -120,24 +48,6 @@ declare function applyToPuppeteerPage(page: any, passport: DevicePassport): Prom
120
48
  * applies every command in order. The caller owns the transport, so this module has no
121
49
  * dependency and works over WebSocket, stdio, or an in-process socket.
122
50
  */
123
- interface CdpCommand {
124
- method: string;
125
- params?: Record<string, unknown>;
126
- /** `sessionId` is required for page-scoped domains when using flattened sessions. */
127
- sessionId?: string;
128
- }
129
- interface CdpPassportPlan {
130
- /** Ordered commands to apply the passport to a target. */
131
- commands: CdpCommand[];
132
- /** Init scripts to install on every new document. */
133
- initScripts: {
134
- source: string;
135
- }[];
136
- /** Extra HTTP headers to set on the session. */
137
- headers: Record<string, string>;
138
- /** The raw stealth + pixel-protection script, for callers that prefer their own path. */
139
- stealthScript: string;
140
- }
141
51
  /**
142
52
  * Builds the ordered CDP command plan for a passport.
143
53
  *
@@ -152,5 +62,5 @@ declare function getCdpPlan(passport: DevicePassport, sessionId?: string): CdpPa
152
62
  */
153
63
  declare function applyCdpPassport(passport: DevicePassport, send: (command: CdpCommand) => Promise<unknown>, sessionId?: string): Promise<void>;
154
64
 
155
- export { CANONICAL_HEADER_ORDER, applyCdpPassport, applyToPlaywrightContext, applyToPuppeteerPage, formatCanonicalHeaders, getCdpPlan, getPlaywrightContext, getPuppeteerArgs, getStealthScript, toCurl, withPassport };
156
- export type { CdpCommand, CdpPassportPlan, PassportLike, PlaywrightContextOptions, PuppeteerEmulationOptions };
65
+ export { CANONICAL_HEADER_ORDER, applyCdpPassport, formatCanonicalHeaders, getCdpPlan, toCurl, withPassport };
66
+ export type { PassportLike };
@@ -1,4 +1,5 @@
1
- import { DevicePassport } from '../types/index.js';
1
+ import { DevicePassport, CdpCommand, CdpPassportPlan } from '../types/index.js';
2
+ export { P as PlaywrightContextOptions, a as PuppeteerEmulationOptions, b as applyToPlaywrightContext, c as applyToPuppeteerPage, g as getPlaywrightContext, d as getPuppeteerArgs, e as getStealthScript } from '../shared/device-passport.D7pEnyp2.js';
2
3
  import '../shared/device-passport.C_F1vBE8.js';
3
4
 
4
5
  /**
@@ -34,79 +35,6 @@ declare function toCurl(passport: PassportLike | DevicePassport, url: string, op
34
35
  headers?: Record<string, string>;
35
36
  }): string;
36
37
 
37
- interface PlaywrightContextOptions {
38
- userAgent: string;
39
- viewport: {
40
- width: number;
41
- height: number;
42
- };
43
- deviceScaleFactor: number;
44
- locale: string;
45
- timezoneId: string;
46
- geolocation?: {
47
- latitude: number;
48
- longitude: number;
49
- accuracy?: number;
50
- };
51
- permissions?: string[];
52
- extraHTTPHeaders: Record<string, string>;
53
- hasTouch: boolean;
54
- isMobile: boolean;
55
- colorScheme?: 'light' | 'dark' | 'no-preference';
56
- }
57
- /**
58
- * Builds Playwright BrowserContext options directly from a DevicePassport.
59
- * Ready for `browser.newContext(getPlaywrightContext(passport))`.
60
- */
61
- declare function getPlaywrightContext(passport: DevicePassport): PlaywrightContextOptions;
62
- /**
63
- * Generates an in-page stealth script to patch runtime JavaScript APIs
64
- * (navigator.webdriver, hardwareConcurrency, deviceMemory, WebGL unmasked vendor/renderer,
65
- * navigator.userAgentData Client Hints, and Screen dimensions).
66
- *
67
- * 🔴 API-level spoofing is not enough on its own: `canvas.toDataURL()` and `gl.readPixels()`
68
- * still return the **real** framebuffer, so a headless browser exposes SwiftShader while
69
- * its UA claims a discrete GPU — and every persona on one machine hashes identically.
70
- * The pixel-protection script is therefore appended here, so existing users get
71
- * read-back-safe personas without changing their call sites.
72
- *
73
- * The noise is seeded from the passport seed: stable per account, different per account.
74
- */
75
- declare function getStealthScript(passport: DevicePassport): string;
76
- /**
77
- * Applies stealth injections and extra headers to a Playwright BrowserContext.
78
- *
79
- * @param context Playwright BrowserContext instance
80
- * @param passport DevicePassport instance
81
- */
82
- declare function applyToPlaywrightContext(context: any, passport: DevicePassport): Promise<void>;
83
-
84
- interface PuppeteerEmulationOptions {
85
- launchArgs: string[];
86
- defaultViewport: {
87
- width: number;
88
- height: number;
89
- deviceScaleFactor: number;
90
- isMobile: boolean;
91
- hasTouch: boolean;
92
- };
93
- userAgent: string;
94
- locale: string;
95
- timezoneId: string;
96
- extraHTTPHeaders: Record<string, string>;
97
- }
98
- /**
99
- * Returns Puppeteer launch args and page emulation parameters matching the DevicePassport.
100
- */
101
- declare function getPuppeteerArgs(passport: DevicePassport): PuppeteerEmulationOptions;
102
- /**
103
- * Applies stealth injections, headers, viewport, and timezone emulation to a Puppeteer Page.
104
- *
105
- * @param page Puppeteer Page instance
106
- * @param passport DevicePassport instance
107
- */
108
- declare function applyToPuppeteerPage(page: any, passport: DevicePassport): Promise<void>;
109
-
110
38
  /**
111
39
  * Raw Chrome DevTools Protocol adapter.
112
40
  *
@@ -120,24 +48,6 @@ declare function applyToPuppeteerPage(page: any, passport: DevicePassport): Prom
120
48
  * applies every command in order. The caller owns the transport, so this module has no
121
49
  * dependency and works over WebSocket, stdio, or an in-process socket.
122
50
  */
123
- interface CdpCommand {
124
- method: string;
125
- params?: Record<string, unknown>;
126
- /** `sessionId` is required for page-scoped domains when using flattened sessions. */
127
- sessionId?: string;
128
- }
129
- interface CdpPassportPlan {
130
- /** Ordered commands to apply the passport to a target. */
131
- commands: CdpCommand[];
132
- /** Init scripts to install on every new document. */
133
- initScripts: {
134
- source: string;
135
- }[];
136
- /** Extra HTTP headers to set on the session. */
137
- headers: Record<string, string>;
138
- /** The raw stealth + pixel-protection script, for callers that prefer their own path. */
139
- stealthScript: string;
140
- }
141
51
  /**
142
52
  * Builds the ordered CDP command plan for a passport.
143
53
  *
@@ -152,5 +62,5 @@ declare function getCdpPlan(passport: DevicePassport, sessionId?: string): CdpPa
152
62
  */
153
63
  declare function applyCdpPassport(passport: DevicePassport, send: (command: CdpCommand) => Promise<unknown>, sessionId?: string): Promise<void>;
154
64
 
155
- export { CANONICAL_HEADER_ORDER, applyCdpPassport, applyToPlaywrightContext, applyToPuppeteerPage, formatCanonicalHeaders, getCdpPlan, getPlaywrightContext, getPuppeteerArgs, getStealthScript, toCurl, withPassport };
156
- export type { CdpCommand, CdpPassportPlan, PassportLike, PlaywrightContextOptions, PuppeteerEmulationOptions };
65
+ export { CANONICAL_HEADER_ORDER, applyCdpPassport, formatCanonicalHeaders, getCdpPlan, toCurl, withPassport };
66
+ export type { PassportLike };
@@ -1,3 +1,3 @@
1
- export { C as CANONICAL_HEADER_ORDER, a as applyCdpPassport, b as applyToPlaywrightContext, c as applyToPuppeteerPage, f as formatCanonicalHeaders, g as getCdpPlan, d as getPlaywrightContext, e as getPuppeteerArgs, h as getStealthScript, t as toCurl, w as withPassport } from '../shared/device-passport.NHw_f6HT.mjs';
1
+ export { C as CANONICAL_HEADER_ORDER, a as applyCdpPassport, b as applyToPlaywrightContext, c as applyToPuppeteerPage, f as formatCanonicalHeaders, g as getCdpPlan, d as getPlaywrightContext, e as getPuppeteerArgs, h as getStealthScript, t as toCurl, w as withPassport } from '../shared/device-passport.gNo82fQ5.mjs';
2
2
  import 'node:crypto';
3
- import '../shared/device-passport.BBf9OKap.mjs';
3
+ import '../shared/device-passport.BPQj0qdT.mjs';
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const bridge = require('../shared/device-passport.qL4tjwc0.cjs');
4
+ require('../shared/device-passport.D9xW6R0B.cjs');
5
+ require('node:crypto');
6
+ require('../shared/device-passport.BKtmLzPt.cjs');
7
+ require('../shared/device-passport.EK4RX7Xd.cjs');
8
+ require('../shared/device-passport.Cjxlv8xI.cjs');
9
+ require('node:fs');
10
+ require('node:path');
11
+
12
+
13
+
14
+ exports.AccountProfileManager = bridge.AccountProfileManager;
15
+ exports.PROXY_MISSING_NOTE = bridge.PROXY_MISSING_NOTE;
16
+ exports.PROXY_RESOLUTION_NOTE = bridge.PROXY_RESOLUTION_NOTE;
17
+ exports.buildEgoSessionPlan = bridge.buildEgoSessionPlan;
18
+ exports.buildProxyDeclaration = bridge.buildProxyDeclaration;
19
+ exports.createEgoBridge = bridge.createEgoBridge;
20
+ exports.defaultTaskSpaceName = bridge.defaultTaskSpaceName;
21
+ exports.getEgoNativeBridge = bridge.getEgoNativeBridge;
22
+ exports.getProfileReadiness = bridge.getProfileReadiness;
@@ -0,0 +1,5 @@
1
+ export { A as AccountProfileManager, a as AccountProfileManagerOptions, B as BindProfileOptions, b as BuildEgoSessionPlanOptions, c as CreateSessionPlanOptions, E as EgoNativeBridge, P as PROXY_MISSING_NOTE, d as PROXY_RESOLUTION_NOTE, g as buildEgoSessionPlan, h as buildProxyDeclaration, i as createEgoBridge, k as defaultTaskSpaceName, l as getEgoNativeBridge, m as getProfileReadiness } from '../shared/device-passport.CfLes-lq.cjs';
2
+ import '../types/index.cjs';
3
+ import '../shared/device-passport.C_F1vBE8.cjs';
4
+ import '../shared/device-passport.CsOWqPIr.cjs';
5
+ import '../shared/device-passport.DirQmSd4.cjs';
@@ -0,0 +1,5 @@
1
+ export { A as AccountProfileManager, a as AccountProfileManagerOptions, B as BindProfileOptions, b as BuildEgoSessionPlanOptions, c as CreateSessionPlanOptions, E as EgoNativeBridge, P as PROXY_MISSING_NOTE, d as PROXY_RESOLUTION_NOTE, g as buildEgoSessionPlan, h as buildProxyDeclaration, i as createEgoBridge, k as defaultTaskSpaceName, l as getEgoNativeBridge, m as getProfileReadiness } from '../shared/device-passport.dVEqzSEb.mjs';
2
+ import '../types/index.mjs';
3
+ import '../shared/device-passport.C_F1vBE8.mjs';
4
+ import '../shared/device-passport.ZBspe4ZW.mjs';
5
+ import '../shared/device-passport.DirQmSd4.mjs';
@@ -0,0 +1,5 @@
1
+ export { A as AccountProfileManager, a as AccountProfileManagerOptions, B as BindProfileOptions, b as BuildEgoSessionPlanOptions, c as CreateSessionPlanOptions, E as EgoNativeBridge, P as PROXY_MISSING_NOTE, d as PROXY_RESOLUTION_NOTE, g as buildEgoSessionPlan, h as buildProxyDeclaration, i as createEgoBridge, k as defaultTaskSpaceName, l as getEgoNativeBridge, m as getProfileReadiness } from '../shared/device-passport.CDS7xrj8.js';
2
+ import '../types/index.js';
3
+ import '../shared/device-passport.C_F1vBE8.js';
4
+ import '../shared/device-passport.D7pEnyp2.js';
5
+ import '../shared/device-passport.DirQmSd4.js';
@@ -0,0 +1,8 @@
1
+ export { A as AccountProfileManager, P as PROXY_MISSING_NOTE, a as PROXY_RESOLUTION_NOTE, b as buildEgoSessionPlan, c as buildProxyDeclaration, d as createEgoBridge, e as defaultTaskSpaceName, g as getEgoNativeBridge, f as getProfileReadiness } from '../shared/device-passport.kekU28UM.mjs';
2
+ import '../shared/device-passport.gNo82fQ5.mjs';
3
+ import 'node:crypto';
4
+ import '../shared/device-passport.BPQj0qdT.mjs';
5
+ import '../shared/device-passport.BGfRcQNh.mjs';
6
+ import '../shared/device-passport.CyQtcZeD.mjs';
7
+ import 'node:fs';
8
+ import 'node:path';