@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.
Files changed (49) hide show
  1. package/bundle/manifest.json +15 -15
  2. package/bundle/parall-browser-pod.js +29726 -375
  3. package/bundle/parall-channel-exec.js +2 -0
  4. package/bundle/parall-claude-agent.js +26091 -273
  5. package/bundle/parall-codex-agent.js +26650 -331
  6. package/bundle/parall-daemon.js +31384 -1998
  7. package/bundle/parall-openclaw-agent.js +1 -0
  8. package/dist/browser-pod.d.ts +23 -1
  9. package/dist/browser-pod.d.ts.map +1 -1
  10. package/dist/browser-pod.js +104 -34
  11. package/dist/browser-profile-reconcile.d.ts +21 -0
  12. package/dist/browser-profile-reconcile.d.ts.map +1 -0
  13. package/dist/browser-profile-reconcile.js +188 -0
  14. package/dist/clip-runtime/browser-cdp.d.ts +40 -0
  15. package/dist/clip-runtime/browser-cdp.d.ts.map +1 -0
  16. package/dist/clip-runtime/browser-cdp.js +218 -0
  17. package/dist/clip-runtime/browser-profile-manager.d.ts +97 -24
  18. package/dist/clip-runtime/browser-profile-manager.d.ts.map +1 -1
  19. package/dist/clip-runtime/browser-profile-manager.js +316 -182
  20. package/dist/clip-runtime/browser-profile-pool.d.ts +3 -0
  21. package/dist/clip-runtime/browser-profile-pool.d.ts.map +1 -1
  22. package/dist/clip-runtime/browser-profile-pool.js +18 -1
  23. package/dist/clip-runtime/browser-proxy-reconcile.d.ts +77 -0
  24. package/dist/clip-runtime/browser-proxy-reconcile.d.ts.map +1 -0
  25. package/dist/clip-runtime/browser-proxy-reconcile.js +139 -0
  26. package/dist/clip-runtime/browser-proxy-state.d.ts +55 -0
  27. package/dist/clip-runtime/browser-proxy-state.d.ts.map +1 -0
  28. package/dist/clip-runtime/browser-proxy-state.js +149 -0
  29. package/dist/clip-runtime/browser-quiescence.d.ts +71 -0
  30. package/dist/clip-runtime/browser-quiescence.d.ts.map +1 -0
  31. package/dist/clip-runtime/browser-quiescence.js +136 -0
  32. package/dist/clip-runtime/browser-readiness.d.ts +64 -0
  33. package/dist/clip-runtime/browser-readiness.d.ts.map +1 -0
  34. package/dist/clip-runtime/browser-readiness.js +161 -0
  35. package/dist/clip-runtime/browser-state-store.d.ts +13 -2
  36. package/dist/clip-runtime/browser-state-store.d.ts.map +1 -1
  37. package/dist/clip-runtime/browser-state-store.js +15 -6
  38. package/dist/clip-runtime/browser-target-registry.d.ts +143 -0
  39. package/dist/clip-runtime/browser-target-registry.d.ts.map +1 -0
  40. package/dist/clip-runtime/browser-target-registry.js +297 -0
  41. package/dist/clip-runtime/browser-viewer-streamer.d.ts +13 -14
  42. package/dist/clip-runtime/browser-viewer-streamer.d.ts.map +1 -1
  43. package/dist/clip-runtime/browser-viewer-streamer.js +11 -63
  44. package/dist/daemon-main.d.ts.map +1 -1
  45. package/dist/daemon-main.js +3 -1
  46. package/dist/supervisor.d.ts +6 -0
  47. package/dist/supervisor.d.ts.map +1 -1
  48. package/dist/supervisor.js +48 -187
  49. package/package.json +8 -6
@@ -0,0 +1,297 @@
1
+ import { sleep } from './subprocess.js';
2
+ /**
3
+ * BrowserTargetRegistry — binds every browser command to a page target OWNED by
4
+ * the profile's bb-browser account, so no command can fall through to
5
+ * bb-browser's account-blind global routing.
6
+ *
7
+ * WHY. bb-browser-pro 0.15.0 resolves a tab-less command via
8
+ * `ensurePageTarget(undefined)` → global `currentTargetId` → `targets[0]`
9
+ * (verified in its daemon source; `request.account` is never consulted). Chrome
10
+ * is launched with a literal `about:blank` positional tab in the DEFAULT
11
+ * browser context — no account cookies, no account proxy — and nothing ever
12
+ * closes it, so it IS `targets[0]` on a fresh Chromium. Worse, the daemon's own
13
+ * tab-less `tab_list` warm-up is dispatched through `ensurePageTarget` too and
14
+ * pins the global `currentTargetId` to that blank page. Any agent command sent
15
+ * without an explicit `tabId` (navigate/get/click/screenshot/eval/...) then
16
+ * executes against a cookie-less, proxy-less page — including real-IP egress
17
+ * for proxy-configured profiles. The registry closes this by resolving an
18
+ * OWNED target (per `tab_list`'s per-tab `account` attribution) and stamping
19
+ * its full CDP targetId on every tab-addressed command.
20
+ *
21
+ * Ownership ground truth is bb-browser's own `tab_list` attribution (targetId →
22
+ * account, derived from its BrowserContext bookkeeping), so a recreated tab —
23
+ * `tab_new {account}` routes through `createTabInContext` → `ensureContext` —
24
+ * always lands in the profile's BrowserContext with its cookies re-injected,
25
+ * never the default context.
26
+ */
27
+ /**
28
+ * Thrown when a command's target cannot be bound to a profile-owned page: a
29
+ * caller-supplied ref that is not the profile's own tab (foreign tab, numeric
30
+ * global index, stale id), or an owned page that cannot be (re)created. The
31
+ * command is NEVER retargeted at another page — fail closed.
32
+ */
33
+ export class BrowserTargetError extends Error {
34
+ code;
35
+ constructor(message, code) {
36
+ super(message);
37
+ this.code = code;
38
+ this.name = 'BrowserTargetError';
39
+ }
40
+ }
41
+ export class BrowserTargetRegistry {
42
+ host;
43
+ opts;
44
+ // Deliberately STATELESS: ownership is recomputed from bb-browser's live
45
+ // `tab_list` attribution on every resolve. There is no cached binding to go
46
+ // stale, nothing to invalidate on restart/reset, and a resolve can never
47
+ // return a tab that isn't owned RIGHT NOW.
48
+ constructor(host, opts = {}) {
49
+ this.host = host;
50
+ this.opts = opts;
51
+ }
52
+ /** `tab_list` rows owned by the account (per-tab `account` attribution). */
53
+ async ownedTabs(account) {
54
+ const list = await this.host.sendCommand({ method: 'tab_list', account });
55
+ const rows = Array.isArray(list.tabs)
56
+ ? list.tabs
57
+ : [];
58
+ const owned = [];
59
+ for (const row of rows) {
60
+ if (row?.account !== account)
61
+ continue;
62
+ const targetId = typeof row.tabId === 'string' && row.tabId ? row.tabId : undefined;
63
+ if (!targetId)
64
+ continue;
65
+ owned.push({
66
+ targetId,
67
+ shortId: row.tab === undefined ? undefined : String(row.tab),
68
+ url: typeof row.url === 'string' ? row.url : undefined,
69
+ active: row.active === true,
70
+ });
71
+ }
72
+ return owned;
73
+ }
74
+ /**
75
+ * Resolve the full CDP targetId a command must run against.
76
+ *
77
+ * With `ref` (caller-supplied `tabId`/`tab`): it must be one of the account's
78
+ * OWN tabs (full targetId or short id) — anything else throws
79
+ * BrowserTargetError. Numeric refs are rejected outright: bb-browser resolves
80
+ * bare numbers as indices into the GLOBAL page-target array, which can address
81
+ * another context's page.
82
+ *
83
+ * Without `ref`: the owned tab Chrome marks active, else the first owned
84
+ * tab, else a fresh `about:blank` created INSIDE the account's
85
+ * BrowserContext (never the default context). Stateless — derived from the
86
+ * live tab_list every time.
87
+ */
88
+ async resolveCommandTarget(account, ref) {
89
+ if (ref !== undefined && ref !== null && ref !== '') {
90
+ return this.resolveExplicitRef(account, ref);
91
+ }
92
+ const owned = await this.ownedTabs(account);
93
+ const pick = owned.find((t) => t.active) ?? owned[0];
94
+ if (pick)
95
+ return pick.targetId;
96
+ return this.createOwnedTab(account);
97
+ }
98
+ /**
99
+ * Validate + canonicalize a caller-supplied tab ref against owned tabs only.
100
+ * The ref is matched as a string against owned full/short ids and NEVER
101
+ * forwarded raw — so bb-browser's numeric-index fallback (which indexes into
102
+ * the GLOBAL page array, any context) is unreachable.
103
+ */
104
+ async resolveExplicitRef(account, ref) {
105
+ const wanted = String(ref);
106
+ const owned = await this.ownedTabs(account);
107
+ const match = owned.find((t) => t.targetId === wanted || t.shortId === wanted);
108
+ if (!match) {
109
+ const indexHint = /^\d+$/.test(wanted)
110
+ ? ' (numeric tab indices are not supported — pass the tab id returned by tab_list/tab_new)'
111
+ : '';
112
+ throw new BrowserTargetError(`tab ${wanted} does not belong to browser profile ${account} — commands are bound to the profile's own pages${indexHint}`, 'BROWSER_TARGET_FOREIGN');
113
+ }
114
+ return match.targetId;
115
+ }
116
+ /**
117
+ * Ensure the account owns at least one page tab, returning its targetId. A
118
+ * fresh account (or one whose pages were all closed) gets an `about:blank`
119
+ * tab created in ITS BrowserContext via `tab_new {account}` — bb-browser's
120
+ * `createTabInContext` re-activates the context (cookies re-injected) when it
121
+ * was disposed, so recovery never lands in the default context.
122
+ */
123
+ async ensureOwnedTab(account) {
124
+ const owned = await this.ownedTabs(account);
125
+ const existing = owned.find((t) => t.active) ?? owned[0];
126
+ if (existing)
127
+ return existing.targetId;
128
+ return this.createOwnedTab(account);
129
+ }
130
+ async createOwnedTab(account) {
131
+ const created = await this.host.sendCommand({
132
+ method: 'tab_new',
133
+ account,
134
+ url: 'about:blank',
135
+ });
136
+ const targetId = typeof created.tabId === 'string' && created.tabId ? created.tabId : undefined;
137
+ if (targetId)
138
+ return targetId;
139
+ // tab_new responded without a usable tabId — re-derive from ownership rather
140
+ // than guess (never fall back to an unowned page).
141
+ const owned = await this.ownedTabs(account);
142
+ const pick = owned.find((t) => t.active) ?? owned[0];
143
+ if (!pick) {
144
+ throw new BrowserTargetError(`could not create a page for browser profile ${account} in its own context`, 'BROWSER_TARGET_UNAVAILABLE');
145
+ }
146
+ return pick.targetId;
147
+ }
148
+ /** Owned tab currently on `host` (www-tolerant), optionally only a specific ref. */
149
+ async findOwnedTabOnHost(account, host, onlyTargetId) {
150
+ const owned = await this.ownedTabs(account);
151
+ for (const tab of owned) {
152
+ if (onlyTargetId !== undefined && tab.targetId !== onlyTargetId)
153
+ continue;
154
+ if (!tab.url)
155
+ continue;
156
+ try {
157
+ if (hostsMatch(new URL(tab.url).host, host))
158
+ return tab.targetId;
159
+ }
160
+ catch {
161
+ /* non-URL tab (about:blank etc.) — skip */
162
+ }
163
+ }
164
+ return undefined;
165
+ }
166
+ /** Whether any owned tab is already on `url` (same resource, http→https tolerant). */
167
+ async findOwnedTabMatchingUrl(account, url) {
168
+ const expected = comparableUrl(url);
169
+ if (!expected)
170
+ return undefined;
171
+ const owned = await this.ownedTabs(account);
172
+ for (const tab of owned) {
173
+ if (!tab.url)
174
+ continue;
175
+ const actual = comparableUrl(tab.url);
176
+ if (!actual)
177
+ continue;
178
+ const sameResource = hostsMatch(actual.host, expected.host) && actual.target === expected.target;
179
+ const sameProtocol = actual.protocol === expected.protocol;
180
+ const redirectedUpgrade = expected.protocol === 'http:' && actual.protocol === 'https:';
181
+ if (sameResource && (sameProtocol || redirectedUpgrade))
182
+ return tab.targetId;
183
+ }
184
+ return undefined;
185
+ }
186
+ /**
187
+ * Account-scoped tab-by-domain resolution for `eval {domain}` (bb-browser's
188
+ * own `resolveTabByDomain` is account-blind — the reason this exists). Two
189
+ * properties the bare `tab_new` + eval approach lacked, both caught on the
190
+ * staging closed-loop E2E (2026-06-04):
191
+ *
192
+ * 1. Reuse: an existing account tab already on the domain is reused instead
193
+ * of opening a new tab per eval (upstream reuses matching tabs too).
194
+ * 2. Load wait: after creating a tab, wait for the navigation to commit
195
+ * before eval — upstream waits (~10s poll + settle); without it the clip
196
+ * script races `about:blank` and relative fetches fail
197
+ * ("Failed to parse URL from /hot.json").
198
+ */
199
+ async resolveDomainTab(account, domain) {
200
+ const url = normalizeDomainUrl(domain);
201
+ let host = '';
202
+ try {
203
+ host = new URL(url).host;
204
+ }
205
+ catch {
206
+ /* fall through — tab_new with whatever bb-browser makes of it */
207
+ }
208
+ if (host) {
209
+ const existing = await this.findOwnedTabOnHost(account, host);
210
+ if (existing !== undefined)
211
+ return existing;
212
+ }
213
+ const tab = await this.host.sendCommand({ method: 'tab_new', url, account });
214
+ const targetId = typeof tab.tabId === 'string' && tab.tabId ? tab.tabId : undefined;
215
+ if (targetId === undefined || !host)
216
+ return targetId;
217
+ // Wait for the created tab to actually reach the domain (navigation
218
+ // committed). Mirrors upstream resolveTabByDomain's bounded wait + settle.
219
+ let committed = false;
220
+ const deadline = Date.now() + (this.opts.commitTimeoutMs ?? 10_000);
221
+ while (Date.now() < deadline) {
222
+ if ((await this.findOwnedTabOnHost(account, host, targetId)) !== undefined) {
223
+ committed = true;
224
+ break;
225
+ }
226
+ await sleep(this.opts.commitPollMs ?? 300);
227
+ }
228
+ if (!committed) {
229
+ // The tab never confirmed it reached the domain within the deadline — its
230
+ // document is still about:blank / a partial load. Returning it would let a
231
+ // subsequent eval run on the WRONG page. CLOSE it so it can't linger as an
232
+ // owned tab a later ref-less resolve would pick, then fail closed.
233
+ await this.closeTabBestEffort(account, targetId);
234
+ throw new BrowserTargetError(`domain ${domain} page did not commit navigation in browser profile ${account}`, 'BROWSER_TARGET_UNAVAILABLE');
235
+ }
236
+ await sleep(this.opts.commitSettleMs ?? 750); // post-commit settle (upstream uses a flat 2s)
237
+ return targetId;
238
+ }
239
+ /** Close a tab we created but could not commit, so it does not linger as a
240
+ * residual owned tab. Best-effort — a close failure (already gone / rejected)
241
+ * is swallowed. bb-browser's close command is `close` (→ Target.closeTarget). */
242
+ async closeTabBestEffort(account, targetId) {
243
+ try {
244
+ await this.host.sendCommand({ method: 'close', tabId: targetId, account });
245
+ }
246
+ catch {
247
+ /* the tab may already be gone / bb-browser rejected the close — ignore */
248
+ }
249
+ }
250
+ }
251
+ /**
252
+ * Commands that take no page target at all — everything else is tab-addressed
253
+ * and MUST carry an owned tabId. `tab_new`, `site_info`, and the `site_*` listing
254
+ * commands resolve/create their page inside the account's context upstream
255
+ * (createTabInContext / account-scoped adapter execution), so they pass `account`
256
+ * instead of a pinned tab. NOTE `tab_list` IS dispatched through bb-browser's
257
+ * `ensurePageTarget` (its global-current-tab side effect is harmless once every
258
+ * real command pins its own target). `site_run` is deliberately NOT tab-less:
259
+ * the manager resolves the adapter's domain via site_info and pins an owned tab
260
+ * (or fails closed for a domain-less adapter), closing the old global-current-tab
261
+ * fallthrough — see BrowserProfileManager.buildCommandRequest.
262
+ */
263
+ export const TABLESS_COMMANDS = new Set([
264
+ 'account_list',
265
+ 'account_create',
266
+ 'account_delete',
267
+ 'account_info',
268
+ 'tab_list',
269
+ 'tab_new',
270
+ 'site_list',
271
+ 'site_search',
272
+ 'site_info',
273
+ ]);
274
+ /** Host comparison tolerant of a `www.` prefix on either side. */
275
+ export function hostsMatch(a, b) {
276
+ const norm = (h) => h.toLowerCase().replace(/^www\./, '');
277
+ return norm(a) === norm(b);
278
+ }
279
+ export function normalizeDomainUrl(domain) {
280
+ const trimmed = domain.trim();
281
+ if (!trimmed)
282
+ return 'about:blank';
283
+ return /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
284
+ }
285
+ export function comparableUrl(url) {
286
+ try {
287
+ const parsed = new URL(url);
288
+ return {
289
+ protocol: parsed.protocol,
290
+ host: parsed.host,
291
+ target: `${parsed.pathname}${parsed.search}${parsed.hash}`,
292
+ };
293
+ }
294
+ catch {
295
+ return null;
296
+ }
297
+ }
@@ -1,3 +1,4 @@
1
+ import type { BrowserTargetRegistry } from './browser-target-registry.js';
1
2
  /** Optional managed TURN relay config carried on a `stream.start` command. */
2
3
  export interface ViewerTurnConfig {
3
4
  url: string;
@@ -21,13 +22,19 @@ export interface ViewerStreamerHost {
21
22
  method: string;
22
23
  account?: string;
23
24
  }): Promise<Record<string, unknown>>;
24
- ensureAccount(account: string): Promise<boolean>;
25
+ /** First-use preparation (desired-proxy reconcile + readiness), shared with the
26
+ * agent-invoke path — the viewer's first stream/nav on a hydrated account must
27
+ * reconcile the proxy + verify readiness too, not just confirm the account
28
+ * exists. Idempotent: the steady path after first use is cheap. */
29
+ prepareForUse(account: string): Promise<void>;
25
30
  withDaemonRecovery<T>(operation: () => Promise<T>, label: string): Promise<T>;
26
31
  /** cdpHost/cdpPort from the bb-browser daemon `GET /status`. */
27
32
  cdpEndpoint(): Promise<{
28
33
  host: string;
29
34
  port: number;
30
35
  }>;
36
+ /** Shared owned-target resolution (same registry the agent-invoke path pins with). */
37
+ targets: BrowserTargetRegistry;
31
38
  }
32
39
  /**
33
40
  * bb-viewer's /command control plane is UNAUTHENTICATED, so on the shared agents
@@ -165,25 +172,17 @@ export declare class BrowserViewerStreamer {
165
172
  private resolveAccountPageCdpUrl;
166
173
  /**
167
174
  * Full CDP targetId of the profile account's active page tab (the owned tab
168
- * Chrome marks active, else the first owned tab). If the account owns no
169
- * page tab yet, open `about:blank` for it first (mirrors the agent-invoke
170
- * path's "always give a fresh account an owned tab" rule).
175
+ * Chrome marks active, else the first owned tab; a tab-less account gets an
176
+ * `about:blank` created inside its own context first). Shared with the
177
+ * agent-invoke path via BrowserTargetRegistry one ownership implementation.
171
178
  */
172
179
  private accountActivePageTargetId;
173
- /**
174
- * Full CDP targetId (`tabId`) of the account's active page tab: the owned tab
175
- * Chrome marks `active` when it belongs to this account, else the first owned
176
- * tab (the global active flag is account-blind — another profile's tab may
177
- * hold it, which must not leak here).
178
- */
179
- private firstAccountPageTargetId;
180
180
  /**
181
181
  * Full CDP targetId for a specific account tab, addressed by the bb-browser
182
- * short tab id (`tab`) or full target id (`tabId`). Used by stream.switch.
182
+ * short tab id (`tab`) or full target id (`tabId`). Throws on tabs the
183
+ * profile does not own (BrowserTargetError). Used by stream.switch.
183
184
  */
184
185
  private accountTabTargetId;
185
- /** `tab_list {account}` rows, typed to the fields we read (tabId/tab/account/active). */
186
- private accountTabs;
187
186
  /**
188
187
  * Spawn a bb-viewer streamer for the profile and wait until healthy. Binary
189
188
  * is PRLL_BB_VIEWER_BIN (our image sets it to /usr/local/bin/bb-viewer),
@@ -1 +1 @@
1
- {"version":3,"file":"browser-viewer-streamer.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/browser-viewer-streamer.ts"],"names":[],"mappings":"AAsCA,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAcD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE;QAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpF,gFAAgF;IAChF,kBAAkB,CAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GACtE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpC,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,kBAAkB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9E,gEAAgE;IAChE,WAAW,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAGT;AAED,qBAAa,qBAAqB;IAiBpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAO9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAI5D,OAAO,CAAC,QAAQ,CAAS;gBAEI,IAAI,EAAE,kBAAkB;IAErD;;;;;OAKG;IACG,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,CAAC,EAAE,gBAAgB,GACtB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAuCnC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,UAAU;IAwBlB;;;;OAIG;YACW,iBAAiB;IA+C/B;;;;OAIG;YACW,kBAAkB;IAgBhC;;;;;;;;;;OAUG;YACW,iBAAiB;IAuB/B;;;;;;;;OAQG;YACW,kBAAkB;IAuBhC;;;;;;OAMG;YACW,cAAc;IAiC5B;;;;;;;OAOG;YACW,kBAAkB;IAqBhC;;;;;;;;;;;;;;;;;;;;OAoBG;YACW,gBAAgB;IA6C9B;;;;;;;;;;;;;;;;;;OAkBG;YACW,wBAAwB;IAetC;;;;;OAKG;YACW,yBAAyB;IAevC;;;;;OAKG;YACW,wBAAwB;IAatC;;;OAGG;YACW,kBAAkB;IAehC,yFAAyF;YAC3E,WAAW;IAgBzB;;;;;OAKG;YACW,aAAa;IAiH3B;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAqBjB;;;;OAIG;YACW,eAAe;IA+B7B;;;;;OAKG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ5C;;;OAGG;IACH,QAAQ,IAAI,IAAI;CAMjB"}
1
+ {"version":3,"file":"browser-viewer-streamer.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/browser-viewer-streamer.ts"],"names":[],"mappings":"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"}
@@ -332,7 +332,7 @@ export class BrowserViewerStreamer {
332
332
  }
333
333
  }
334
334
  return this.host.withDaemonRecovery(async () => {
335
- await this.host.ensureAccount(profileId);
335
+ await this.host.prepareForUse(profileId);
336
336
  const request = { ...(input ?? {}) };
337
337
  if (command === 'open' || command === 'tab_new') {
338
338
  assertViewerNavigableUrl(request.url);
@@ -375,7 +375,7 @@ export class BrowserViewerStreamer {
375
375
  * is the per-tab attribution we filter on (reused by findAccountTabOnHost).
376
376
  */
377
377
  async resolveAccountPageCdpUrl(profileId, tabRef) {
378
- await this.host.ensureAccount(profileId);
378
+ await this.host.prepareForUse(profileId);
379
379
  const { host, port } = await this.host.cdpEndpoint();
380
380
  const targetId = tabRef !== undefined
381
381
  ? await this.accountTabTargetId(profileId, tabRef)
@@ -384,72 +384,20 @@ export class BrowserViewerStreamer {
384
384
  }
385
385
  /**
386
386
  * Full CDP targetId of the profile account's active page tab (the owned tab
387
- * Chrome marks active, else the first owned tab). If the account owns no
388
- * page tab yet, open `about:blank` for it first (mirrors the agent-invoke
389
- * path's "always give a fresh account an owned tab" rule).
387
+ * Chrome marks active, else the first owned tab; a tab-less account gets an
388
+ * `about:blank` created inside its own context first). Shared with the
389
+ * agent-invoke path via BrowserTargetRegistry one ownership implementation.
390
390
  */
391
- async accountActivePageTargetId(profileId) {
392
- let targetId = await this.firstAccountPageTargetId(profileId);
393
- if (targetId !== undefined)
394
- return targetId;
395
- await this.host.sendBrowserCommand({
396
- method: 'tab_new',
397
- account: profileId,
398
- url: 'about:blank',
399
- });
400
- targetId = await this.firstAccountPageTargetId(profileId);
401
- if (targetId === undefined) {
402
- throw new Error(`no page tab found for profile account ${profileId}`);
403
- }
404
- return targetId;
405
- }
406
- /**
407
- * Full CDP targetId (`tabId`) of the account's active page tab: the owned tab
408
- * Chrome marks `active` when it belongs to this account, else the first owned
409
- * tab (the global active flag is account-blind — another profile's tab may
410
- * hold it, which must not leak here).
411
- */
412
- async firstAccountPageTargetId(profileId) {
413
- const tabs = await this.accountTabs(profileId);
414
- let firstOwned;
415
- for (const t of tabs) {
416
- if (t.account !== profileId)
417
- continue;
418
- const tabId = t.tabId;
419
- if (typeof tabId !== 'string' || !tabId)
420
- continue;
421
- if (t.active === true)
422
- return tabId;
423
- firstOwned ??= tabId;
424
- }
425
- return firstOwned;
391
+ accountActivePageTargetId(profileId) {
392
+ return this.host.targets.resolveCommandTarget(profileId);
426
393
  }
427
394
  /**
428
395
  * Full CDP targetId for a specific account tab, addressed by the bb-browser
429
- * short tab id (`tab`) or full target id (`tabId`). Used by stream.switch.
396
+ * short tab id (`tab`) or full target id (`tabId`). Throws on tabs the
397
+ * profile does not own (BrowserTargetError). Used by stream.switch.
430
398
  */
431
- async accountTabTargetId(profileId, tabRef) {
432
- const ref = String(tabRef);
433
- const tabs = await this.accountTabs(profileId);
434
- for (const t of tabs) {
435
- if (t.account !== profileId)
436
- continue;
437
- const tabId = typeof t.tabId === 'string' ? t.tabId : undefined;
438
- const shortTab = t.tab === undefined ? undefined : String(t.tab);
439
- if ((tabId && tabId === ref) || (shortTab && shortTab === ref)) {
440
- if (!tabId)
441
- break;
442
- return tabId;
443
- }
444
- }
445
- throw new Error(`tab ${ref} not found for profile account ${profileId}`);
446
- }
447
- /** `tab_list {account}` rows, typed to the fields we read (tabId/tab/account/active). */
448
- async accountTabs(profileId) {
449
- const list = await this.host.sendBrowserCommand({ method: 'tab_list', account: profileId });
450
- return Array.isArray(list.tabs)
451
- ? list.tabs
452
- : [];
399
+ accountTabTargetId(profileId, tabRef) {
400
+ return this.host.targets.resolveCommandTarget(profileId, tabRef);
453
401
  }
454
402
  // ---- bb-viewer streamer lifecycle ----
455
403
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-main.d.ts","sourceRoot":"","sources":["../src/daemon-main.ts"],"names":[],"mappings":";AAyBA,MAAM,MAAM,oBAAoB,GAAG;IACjC,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AA4KF,wBAAsB,cAAc,CAClC,SAAS,EAAE,oBAAoB,EAC/B,IAAI,WAAwB,GAC3B,OAAO,CAAC,IAAI,CAAC,CASf"}
1
+ {"version":3,"file":"daemon-main.d.ts","sourceRoot":"","sources":["../src/daemon-main.ts"],"names":[],"mappings":";AA0BA,MAAM,MAAM,oBAAoB,GAAG;IACjC,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AA8KF,wBAAsB,cAAc,CAClC,SAAS,EAAE,oBAAoB,EAC/B,IAAI,WAAwB,GAC3B,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createLogger, createOtelLogger, initAgentTelemetry, } from '@parall/agent-core';
2
+ import { configureHttpKeepAlive, createLogger, createOtelLogger, initAgentTelemetry, } from '@parall/agent-core';
3
3
  import { ParallClient } from '@parall/sdk';
4
4
  import { runCLI } from './cli.js';
5
5
  import { resolveBundleDir, resolveClaudeDaemonConfig, resolveWsUrl, } from './config.js';
@@ -75,6 +75,8 @@ async function runForever(config, client, log, signal, updater, gate) {
75
75
  }
76
76
  }
77
77
  async function main(bootstrap) {
78
+ // Before any fetch: long-lived HTTP connections for control-plane calls.
79
+ configureHttpKeepAlive();
78
80
  const config = resolveClaudeDaemonConfig(process.env);
79
81
  const telemetry = await initAgentTelemetry('parall-daemon', 'daemon');
80
82
  log = createOtelLogger('daemon', 'daemon');
@@ -81,6 +81,12 @@ export declare class DaemonSupervisor {
81
81
  * proxy-configured profile (the caller reports `error` and retries next tick).
82
82
  */
83
83
  private resolveBrowserProfileProxy;
84
+ /** Proxy readiness probe endpoint for BYOC profiles (browser-readiness.ts): an
85
+ * explicit override, else the api-server's Parall-owned public `/generate_204`.
86
+ * The probe navigates a sacrificial tab THROUGH the profile's proxy, so the
87
+ * target must be public + proxy-resolvable — `config.apiUrl` is the public API
88
+ * host for BYOC. Falls back to a well-known public 204 if apiUrl is unusable. */
89
+ private resolveBrowserProxyProbeUrl;
84
90
  /**
85
91
  * Detects a legacy flat state layout (no agents/ subdir) and migrates it
86
92
  * into the per-agent directory for the owning agent. Ownership is determined
@@ -1 +1 @@
1
- {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../src/supervisor.ts"],"names":[],"mappings":"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"}