@parall/daemon 1.45.0 → 1.46.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.
- package/bundle/manifest.json +15 -15
- package/bundle/parall-browser-pod.js +29726 -375
- package/bundle/parall-channel-exec.js +2 -0
- package/bundle/parall-claude-agent.js +26091 -273
- package/bundle/parall-codex-agent.js +26650 -331
- package/bundle/parall-daemon.js +31384 -1998
- package/bundle/parall-openclaw-agent.js +1 -0
- package/dist/browser-pod.d.ts +23 -1
- package/dist/browser-pod.d.ts.map +1 -1
- package/dist/browser-pod.js +104 -34
- package/dist/browser-profile-reconcile.d.ts +21 -0
- package/dist/browser-profile-reconcile.d.ts.map +1 -0
- package/dist/browser-profile-reconcile.js +188 -0
- package/dist/clip-runtime/browser-cdp.d.ts +40 -0
- package/dist/clip-runtime/browser-cdp.d.ts.map +1 -0
- package/dist/clip-runtime/browser-cdp.js +218 -0
- package/dist/clip-runtime/browser-profile-manager.d.ts +97 -24
- package/dist/clip-runtime/browser-profile-manager.d.ts.map +1 -1
- package/dist/clip-runtime/browser-profile-manager.js +316 -182
- package/dist/clip-runtime/browser-profile-pool.d.ts +3 -0
- package/dist/clip-runtime/browser-profile-pool.d.ts.map +1 -1
- package/dist/clip-runtime/browser-profile-pool.js +18 -1
- package/dist/clip-runtime/browser-proxy-reconcile.d.ts +77 -0
- package/dist/clip-runtime/browser-proxy-reconcile.d.ts.map +1 -0
- package/dist/clip-runtime/browser-proxy-reconcile.js +139 -0
- package/dist/clip-runtime/browser-proxy-state.d.ts +55 -0
- package/dist/clip-runtime/browser-proxy-state.d.ts.map +1 -0
- package/dist/clip-runtime/browser-proxy-state.js +149 -0
- package/dist/clip-runtime/browser-quiescence.d.ts +71 -0
- package/dist/clip-runtime/browser-quiescence.d.ts.map +1 -0
- package/dist/clip-runtime/browser-quiescence.js +136 -0
- package/dist/clip-runtime/browser-readiness.d.ts +64 -0
- package/dist/clip-runtime/browser-readiness.d.ts.map +1 -0
- package/dist/clip-runtime/browser-readiness.js +161 -0
- package/dist/clip-runtime/browser-state-store.d.ts +13 -2
- package/dist/clip-runtime/browser-state-store.d.ts.map +1 -1
- package/dist/clip-runtime/browser-state-store.js +15 -6
- package/dist/clip-runtime/browser-target-registry.d.ts +143 -0
- package/dist/clip-runtime/browser-target-registry.d.ts.map +1 -0
- package/dist/clip-runtime/browser-target-registry.js +297 -0
- package/dist/clip-runtime/browser-viewer-streamer.d.ts +13 -14
- package/dist/clip-runtime/browser-viewer-streamer.d.ts.map +1 -1
- package/dist/clip-runtime/browser-viewer-streamer.js +11 -63
- package/dist/daemon-main.d.ts.map +1 -1
- package/dist/daemon-main.js +3 -1
- package/dist/supervisor.d.ts +6 -0
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +48 -187
- package/package.json +8 -6
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import WebSocket from 'ws';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal browser-level CDP client — Parall's direct line to the Chromium that
|
|
4
|
+
* bb-browser manages, for the few operations bb-browser's HTTP surface cannot
|
|
5
|
+
* express (bb-browser is off-limits for changes; Chrome accepts multiple CDP
|
|
6
|
+
* clients on the browser endpoint, and Parall already consumes CDP directly for
|
|
7
|
+
* the live viewer's page websockets + /json/activate).
|
|
8
|
+
*
|
|
9
|
+
* Used for cookie-preserving proxy reconciliation: `Storage.getCookies` /
|
|
10
|
+
* `Storage.setCookies` against a specific browserContextId — the full jar
|
|
11
|
+
* including HttpOnly cookies, which no page-level API can read — and
|
|
12
|
+
* `Target.getTargetInfo` to map an owned tab to its BrowserContext.
|
|
13
|
+
*/
|
|
14
|
+
const CONNECT_TIMEOUT_MS = 5_000;
|
|
15
|
+
const COMMAND_TIMEOUT_MS = 10_000;
|
|
16
|
+
/**
|
|
17
|
+
* Force-close a socket that never finished connecting WITHOUT risking an
|
|
18
|
+
* unhandled 'error'. Once the connect Promise has removed its own error listener,
|
|
19
|
+
* a bare `terminate()` on a half-open handshake can still emit 'error'
|
|
20
|
+
* (ECONNRESET / abort) with no listener attached — which Node re-raises as an
|
|
21
|
+
* uncaughtException that crashes the daemon. Attach a permanent no-op error sink
|
|
22
|
+
* first, then terminate; swallow a synchronous throw from an already-dead socket.
|
|
23
|
+
*/
|
|
24
|
+
function safeTerminate(socket) {
|
|
25
|
+
socket.on('error', () => { });
|
|
26
|
+
try {
|
|
27
|
+
socket.terminate();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// terminate() on an already-closed socket can throw synchronously — ignore.
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class BrowserCdpClient {
|
|
34
|
+
socket;
|
|
35
|
+
nextId = 1;
|
|
36
|
+
pending = new Map();
|
|
37
|
+
closed = false;
|
|
38
|
+
constructor(socket) {
|
|
39
|
+
this.socket = socket;
|
|
40
|
+
socket.on('message', (data) => this.onMessage(data));
|
|
41
|
+
const fail = (reason) => this.failAll(new Error(reason));
|
|
42
|
+
socket.on('close', () => fail('CDP browser connection closed'));
|
|
43
|
+
socket.on('error', (err) => fail(`CDP browser connection error: ${String(err)}`));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Connect to the browser-level CDP endpoint behind host:port (`/json/version`).
|
|
47
|
+
* `timeoutMs` bounds BOTH the /json/version fetch and the websocket handshake —
|
|
48
|
+
* injectable so tests can force a fast timeout against a hung server, and so a
|
|
49
|
+
* caller with a wall-clock budget can hand down its remaining budget.
|
|
50
|
+
*/
|
|
51
|
+
static async connect(host, port, timeoutMs = CONNECT_TIMEOUT_MS) {
|
|
52
|
+
const resp = await fetch(`http://${host}:${port}/json/version`, {
|
|
53
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
54
|
+
});
|
|
55
|
+
if (!resp.ok) {
|
|
56
|
+
throw new Error(`CDP /json/version returned ${resp.status}`);
|
|
57
|
+
}
|
|
58
|
+
const info = (await resp.json());
|
|
59
|
+
if (!info.webSocketDebuggerUrl) {
|
|
60
|
+
throw new Error('CDP /json/version did not report a webSocketDebuggerUrl');
|
|
61
|
+
}
|
|
62
|
+
const socket = new WebSocket(info.webSocketDebuggerUrl);
|
|
63
|
+
await new Promise((resolve, reject) => {
|
|
64
|
+
// Explicit single-settle guard: whichever of open / error / timeout fires
|
|
65
|
+
// first wins and the others are no-ops. cleanup() also removes the listeners,
|
|
66
|
+
// but the flag makes the invariant obvious and covers a synchronous re-entry.
|
|
67
|
+
let settled = false;
|
|
68
|
+
const cleanup = () => {
|
|
69
|
+
clearTimeout(timer);
|
|
70
|
+
socket.removeListener('open', onOpen);
|
|
71
|
+
socket.removeListener('error', onError);
|
|
72
|
+
};
|
|
73
|
+
const settle = (fn) => {
|
|
74
|
+
if (settled)
|
|
75
|
+
return;
|
|
76
|
+
settled = true;
|
|
77
|
+
cleanup();
|
|
78
|
+
fn();
|
|
79
|
+
};
|
|
80
|
+
const onOpen = () => settle(resolve);
|
|
81
|
+
const onError = (err) => settle(() => {
|
|
82
|
+
safeTerminate(socket); // free the fd without a later unhandled 'error'
|
|
83
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
84
|
+
});
|
|
85
|
+
const timer = setTimeout(() => settle(() => {
|
|
86
|
+
safeTerminate(socket); // stop the pending connect + free the fd
|
|
87
|
+
reject(new Error('CDP browser websocket connect timed out'));
|
|
88
|
+
}), timeoutMs);
|
|
89
|
+
socket.once('open', onOpen);
|
|
90
|
+
socket.once('error', onError);
|
|
91
|
+
});
|
|
92
|
+
return new BrowserCdpClient(socket);
|
|
93
|
+
}
|
|
94
|
+
/** Send a browser-level CDP command and await its result. */
|
|
95
|
+
command(method, params = {}) {
|
|
96
|
+
if (this.closed)
|
|
97
|
+
return Promise.reject(new Error('CDP client is closed'));
|
|
98
|
+
const id = this.nextId++;
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
const timer = setTimeout(() => {
|
|
101
|
+
this.pending.delete(id);
|
|
102
|
+
reject(new Error(`CDP ${method} timed out`));
|
|
103
|
+
}, COMMAND_TIMEOUT_MS);
|
|
104
|
+
this.pending.set(id, {
|
|
105
|
+
resolve: resolve,
|
|
106
|
+
reject,
|
|
107
|
+
timer,
|
|
108
|
+
});
|
|
109
|
+
this.socket.send(JSON.stringify({ id, method, params }), (err) => {
|
|
110
|
+
if (err) {
|
|
111
|
+
const entry = this.pending.get(id);
|
|
112
|
+
if (entry) {
|
|
113
|
+
clearTimeout(entry.timer);
|
|
114
|
+
this.pending.delete(id);
|
|
115
|
+
reject(err);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
close() {
|
|
122
|
+
this.closed = true;
|
|
123
|
+
this.failAll(new Error('CDP client closed'));
|
|
124
|
+
try {
|
|
125
|
+
this.socket.close();
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
/* already closed */
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
onMessage(data) {
|
|
132
|
+
let parsed;
|
|
133
|
+
try {
|
|
134
|
+
parsed = JSON.parse(String(data));
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return; // not a JSON frame we understand — ignore (events etc.)
|
|
138
|
+
}
|
|
139
|
+
if (typeof parsed.id !== 'number')
|
|
140
|
+
return; // CDP event, not a command reply
|
|
141
|
+
const entry = this.pending.get(parsed.id);
|
|
142
|
+
if (!entry)
|
|
143
|
+
return;
|
|
144
|
+
this.pending.delete(parsed.id);
|
|
145
|
+
clearTimeout(entry.timer);
|
|
146
|
+
if (parsed.error) {
|
|
147
|
+
entry.reject(new Error(parsed.error.message || 'CDP command failed'));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
entry.resolve(parsed.result ?? {});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
failAll(err) {
|
|
154
|
+
for (const [id, entry] of this.pending) {
|
|
155
|
+
this.pending.delete(id);
|
|
156
|
+
clearTimeout(entry.timer);
|
|
157
|
+
entry.reject(err);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** The browserContextId owning a page target (empty for the default context). */
|
|
162
|
+
export async function targetBrowserContextId(cdp, targetId) {
|
|
163
|
+
const { targetInfo } = await cdp.command('Target.getTargetInfo', { targetId });
|
|
164
|
+
return targetInfo?.browserContextId ?? '';
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* The full cookie jar of a BrowserContext (HttpOnly included) as CDP
|
|
168
|
+
* `Network.Cookie` objects — the capture side of cookie-preserving proxy
|
|
169
|
+
* reconciliation.
|
|
170
|
+
*/
|
|
171
|
+
export async function getContextCookies(cdp, browserContextId) {
|
|
172
|
+
const { cookies } = await cdp.command('Storage.getCookies', { browserContextId });
|
|
173
|
+
return cookies ?? [];
|
|
174
|
+
}
|
|
175
|
+
/** Restore a captured jar into a (fresh) BrowserContext. */
|
|
176
|
+
export async function setContextCookies(cdp, browserContextId, cookies) {
|
|
177
|
+
if (cookies.length === 0)
|
|
178
|
+
return;
|
|
179
|
+
await cdp.command('Storage.setCookies', {
|
|
180
|
+
cookies: cookies.map(toCookieParam),
|
|
181
|
+
browserContextId,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Map a CDP `Network.Cookie` (as returned by Storage.getCookies) to a
|
|
186
|
+
* `Network.CookieParam` accepted by Storage.setCookies. Allowlisted fields only:
|
|
187
|
+
* read-side extras (`size`, `session`, `sameParty`, …) are not valid params. A
|
|
188
|
+
* session cookie (session=true / expires=-1) is restored WITHOUT `expires`,
|
|
189
|
+
* which is exactly what makes it a session cookie again. This is
|
|
190
|
+
* higher-fidelity than bb-browser's own account-JSON persistence (which drops
|
|
191
|
+
* `sameSite=None` and partition keys).
|
|
192
|
+
*/
|
|
193
|
+
export function toCookieParam(cookie) {
|
|
194
|
+
const out = {
|
|
195
|
+
name: cookie.name,
|
|
196
|
+
value: cookie.value,
|
|
197
|
+
domain: cookie.domain,
|
|
198
|
+
path: cookie.path,
|
|
199
|
+
};
|
|
200
|
+
if (typeof cookie.secure === 'boolean')
|
|
201
|
+
out.secure = cookie.secure;
|
|
202
|
+
if (typeof cookie.httpOnly === 'boolean')
|
|
203
|
+
out.httpOnly = cookie.httpOnly;
|
|
204
|
+
if (typeof cookie.sameSite === 'string')
|
|
205
|
+
out.sameSite = cookie.sameSite;
|
|
206
|
+
if (typeof cookie.expires === 'number' && cookie.expires > 0 && cookie.session !== true) {
|
|
207
|
+
out.expires = cookie.expires;
|
|
208
|
+
}
|
|
209
|
+
if (typeof cookie.priority === 'string')
|
|
210
|
+
out.priority = cookie.priority;
|
|
211
|
+
if (typeof cookie.sourceScheme === 'string')
|
|
212
|
+
out.sourceScheme = cookie.sourceScheme;
|
|
213
|
+
if (typeof cookie.sourcePort === 'number')
|
|
214
|
+
out.sourcePort = cookie.sourcePort;
|
|
215
|
+
if (cookie.partitionKey !== undefined)
|
|
216
|
+
out.partitionKey = cookie.partitionKey;
|
|
217
|
+
return out;
|
|
218
|
+
}
|
|
@@ -17,13 +17,19 @@ export interface BrowserProfileManagerOptions {
|
|
|
17
17
|
error(msg: string): void;
|
|
18
18
|
};
|
|
19
19
|
reportStatus?: (profileId: string, status: BrowserProfileStatus, errorMsg?: string) => void;
|
|
20
|
-
/** Resolve the profile's outbound proxy
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
20
|
+
/** Resolve the profile's DESIRED outbound proxy — Parall's stored config is the
|
|
21
|
+
* sole source of truth. Consulted at account creation AND at every open/first
|
|
22
|
+
* ensure, where the applied config is reconciled against it (cookie-preserving
|
|
23
|
+
* context rebuild — see browser-proxy-reconcile.ts); bb-browser's own persisted
|
|
24
|
+
* account proxy never wins over this. Returning null = direct egress. A thrown
|
|
25
|
+
* error fails the operation closed (better than egressing from the real IP for
|
|
26
|
+
* a proxy-configured profile). */
|
|
26
27
|
resolveProxy?: (profileId: string) => Promise<BrowserProxyConfig | null> | BrowserProxyConfig | null;
|
|
28
|
+
/** Proxy readiness probe endpoint (~zero-byte Parall-owned URL). When a profile
|
|
29
|
+
* has a proxy, open/first-ensure navigates the owned tab here and requires a
|
|
30
|
+
* transport-error-free round trip before reporting `running`
|
|
31
|
+
* (PRLL_BROWSER_PROXY_PROBE_URL override; see browser-readiness.ts). */
|
|
32
|
+
proxyProbeUrl?: string;
|
|
27
33
|
}
|
|
28
34
|
export interface BrowserInvokeRequest {
|
|
29
35
|
profileId: string;
|
|
@@ -48,8 +54,11 @@ export declare class BrowserProfileManager {
|
|
|
48
54
|
private restarting;
|
|
49
55
|
private stopping;
|
|
50
56
|
private readonly ensuredAccounts;
|
|
57
|
+
private readonly preparedAccounts;
|
|
51
58
|
private readonly ensuringAccounts;
|
|
59
|
+
private readonly preparingAccounts;
|
|
52
60
|
private readonly reportedStatuses;
|
|
61
|
+
private readonly targets;
|
|
53
62
|
private readonly viewer;
|
|
54
63
|
constructor(opts: BrowserProfileManagerOptions);
|
|
55
64
|
invoke({ profileId, account, command, input }: BrowserInvokeRequest): Promise<unknown>;
|
|
@@ -57,6 +66,10 @@ export declare class BrowserProfileManager {
|
|
|
57
66
|
forceStatusReport?: boolean;
|
|
58
67
|
}): Promise<void>;
|
|
59
68
|
openProfile(profileId: string, startUrl?: string): Promise<void>;
|
|
69
|
+
/** Resolve + normalize/validate the desired proxy (fail closed on legacy-invalid
|
|
70
|
+
* configs — see browser-proxy-state.ts). null = direct egress. */
|
|
71
|
+
private resolveDesiredProxy;
|
|
72
|
+
private assertReady;
|
|
60
73
|
stopProfile(profileId: string): Promise<void>;
|
|
61
74
|
resetProfile(profileId: string): Promise<void>;
|
|
62
75
|
stop(): Promise<void>;
|
|
@@ -68,34 +81,94 @@ export declare class BrowserProfileManager {
|
|
|
68
81
|
handleViewerCommand(profileId: string, sessionId: string, command: string, input?: Record<string, unknown>, turn?: ViewerTurnConfig): Promise<Record<string, unknown>>;
|
|
69
82
|
/** Read cdpHost/cdpPort from the bb-browser daemon `GET /status`. */
|
|
70
83
|
private cdpEndpoint;
|
|
71
|
-
private
|
|
84
|
+
private lastCdpEndpoint;
|
|
85
|
+
/** Process-group id of the last spawned bb-browser tree (the detached child's
|
|
86
|
+
* pid). Survives the child's exit — quiescence probes it AFTER stop() to
|
|
87
|
+
* confirm the orphaned Chrome is gone too. null = never spawned. */
|
|
88
|
+
private lastPgid;
|
|
89
|
+
/** The browser tree's process-group id for the quiescence barrier. */
|
|
90
|
+
lastKnownProcessGroup(): number | null;
|
|
91
|
+
/** Peek the last known Chrome CDP endpoint WITHOUT starting anything. */
|
|
92
|
+
lastKnownCdpEndpoint(): {
|
|
93
|
+
host: string;
|
|
94
|
+
port: number;
|
|
95
|
+
} | null;
|
|
96
|
+
/**
|
|
97
|
+
* Land the profile on its start URL, idempotently, always inside its own
|
|
98
|
+
* context. A fresh account already opened `url` via `account_create`
|
|
99
|
+
* (accountCreated) — just bind it. Otherwise: reuse an owned tab already on
|
|
100
|
+
* the URL if any (repeated Open is a no-op), else NAVIGATE the profile's
|
|
101
|
+
* primary owned tab (`open {tabId}`) — never stack a new tab per Open.
|
|
102
|
+
*/
|
|
72
103
|
private openProfileTabOnce;
|
|
73
104
|
private resetProfileOnce;
|
|
74
|
-
private prepareInvokeAccount;
|
|
75
105
|
private recoverInvokeAvailability;
|
|
76
106
|
private accountExists;
|
|
107
|
+
/** One account_info round trip: existence + whether bb-browser holds a proxy for
|
|
108
|
+
* the account (server/username only — bb-browser never returns the password). */
|
|
109
|
+
private getAccountInfo;
|
|
110
|
+
/**
|
|
111
|
+
* Build the wire request for a forwarded browser command, binding it to a
|
|
112
|
+
* page the profile's account OWNS. bb-browser's own routing is account-blind
|
|
113
|
+
* (tab-less → global current tab → `targets[0]`, which is the default-context
|
|
114
|
+
* `about:blank` Chrome launches with — no cookies, NO PROXY), so:
|
|
115
|
+
*
|
|
116
|
+
* - a caller-supplied `tabId`/`tab` must resolve to one of the profile's own
|
|
117
|
+
* tabs (numeric global indices are rejected outright);
|
|
118
|
+
* - every other tab-addressed command gets the profile's primary owned tab
|
|
119
|
+
* stamped in (recreated inside the profile's BrowserContext if its pages
|
|
120
|
+
* were closed — never silently retargeted at another page);
|
|
121
|
+
* - only genuinely tab-less commands (TABLESS_COMMANDS) go unpinned.
|
|
122
|
+
*/
|
|
77
123
|
private buildCommandRequest;
|
|
78
124
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
125
|
+
* The domain bb-browser's adapter metadata declares for `siteName` (via
|
|
126
|
+
* site_info), or '' when the adapter genuinely has no domain / does not exist.
|
|
127
|
+
* This is the ONLY trustworthy domain source for site_run routing — a
|
|
128
|
+
* caller-supplied request.domain is ignored by upstream site_run, so it can never
|
|
129
|
+
* gate account-safe routing.
|
|
130
|
+
*
|
|
131
|
+
* Error handling is deliberately split: ONLY a genuine application-level answer
|
|
132
|
+
* from bb-browser ("no such site") yields '' → the caller fails closed. A
|
|
133
|
+
* RECOVERABLE daemon/CDP failure (or any transport error) RETHROWS, so
|
|
134
|
+
* buildCommandRequest's existing `isRecoverableBrowserDaemonError` →
|
|
135
|
+
* `recoverInvokeAvailability` restart+retry path handles it. Masking those as a
|
|
136
|
+
* domain-less adapter would turn a transient hiccup into a permanent
|
|
137
|
+
* BROWSER_TARGET_UNAVAILABLE. Note a BrowserCommandError can itself carry a
|
|
138
|
+
* recoverable message ("Chrome not connected"), so the recoverable check wins.
|
|
139
|
+
*/
|
|
140
|
+
private siteAdapterDomain;
|
|
141
|
+
/**
|
|
142
|
+
* First-use preparation — the SINGLE invariant shared by invoke, viewer, open,
|
|
143
|
+
* and ensureRuntime (fix #4). Runs ONCE per account per session:
|
|
144
|
+
* 1. resolve Parall's desired proxy (fail closed on invalid config);
|
|
145
|
+
* 2. ensure the account exists AND its applied proxy matches desired
|
|
146
|
+
* (cookie-preserving reconcile if it drifted — e.g. a hydrated hosted
|
|
147
|
+
* account created under an old proxy);
|
|
148
|
+
* 3. verify readiness (owned target answers; when proxied, a real request
|
|
149
|
+
* traverses the proxy without a transport error).
|
|
150
|
+
* Subsequent calls take the steady fast path — no config fetch, no probe —
|
|
151
|
+
* unless `force` is set (explicit lifecycle open / pending-row recovery). A
|
|
152
|
+
* daemon restart, reset, or proxy reconcile clears the prepared marker so the
|
|
153
|
+
* next use re-prepares. Deduped so concurrent first-uses share one run.
|
|
154
|
+
*/
|
|
155
|
+
private prepareForUse;
|
|
156
|
+
/**
|
|
157
|
+
* Ensure the profile's bb-browser account exists and honors the DESIRED proxy.
|
|
83
158
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
159
|
+
* `desiredProxy` semantics:
|
|
160
|
+
* - undefined (invoke fast path): don't fetch/reconcile — create-only proxy
|
|
161
|
+
* resolution via opts.resolveProxy when the account is missing. A proxy
|
|
162
|
+
* change applies at the next open / first ensure.
|
|
163
|
+
* - null / config (open + first ensure): Parall's config is the SSOT. A
|
|
164
|
+
* missing account is created with it; an existing account whose APPLIED
|
|
165
|
+
* fingerprint (Parall-owned sidecar) differs is rebuilt with cookies
|
|
166
|
+
* preserved (reconcileAccountProxy) — bb-browser's persisted account proxy
|
|
167
|
+
* never wins.
|
|
90
168
|
*/
|
|
91
|
-
private resolveAccountDomainTab;
|
|
92
|
-
/** Find an account-owned tab whose URL host matches (optionally a specific tab). */
|
|
93
|
-
private findAccountTabOnHost;
|
|
94
169
|
private ensureAccount;
|
|
170
|
+
private reconcileHost;
|
|
95
171
|
private ensureAccountOwnedTab;
|
|
96
|
-
private profileAlreadyHasOpenTab;
|
|
97
|
-
private hasAccountOwnedTab;
|
|
98
|
-
private findAccountTabMatchingUrl;
|
|
99
172
|
private reportStatus;
|
|
100
173
|
private sendCommand;
|
|
101
174
|
private ensureDaemon;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-profile-manager.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/browser-profile-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser-profile-manager.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/browser-profile-manager.ts"],"names":[],"mappings":"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"}
|